用gdb调试C程序
我正在尝试测试我编写的调度器。我安排了两个进程——它们都是无限的while循环(justwhile(1)语句)。当我运行程序时,有时它会在大约10秒(有时5秒,有时15秒或更长)后出现故障。有时,它根本不会出现故障,并按预期运行。我有一个日志文件,它告诉我在SEGFULT发生之前,两个进程都按预期计划进行。我正在尝试使用gdb调试错误,但它没有多大帮助。以下是我通过回溯得到的信息:用gdb调试C程序,c,gdb,C,Gdb,我正在尝试测试我编写的调度器。我安排了两个进程——它们都是无限的while循环(justwhile(1)语句)。当我运行程序时,有时它会在大约10秒(有时5秒,有时15秒或更长)后出现故障。有时,它根本不会出现故障,并按预期运行。我有一个日志文件,它告诉我在SEGFULT发生之前,两个进程都按预期计划进行。我正在尝试使用gdb调试错误,但它没有多大帮助。以下是我通过回溯得到的信息: #0 0x00007ffff7ff1000 in ?? () #1 0x000000000000002b in
#0 0x00007ffff7ff1000 in ?? ()
#1 0x000000000000002b in ?? ()
#2 0x00007ffff78b984a in new_do_write () from /lib64/libc.so.6
#3 0x000000000061e3d0 in ?? ()
#4 0x0000000000000000 in ?? ()
我真的不明白
我认为这可能是与堆栈溢出相关的错误。然而,我在整个过程中只进行了两次malloc操作——两次都是在设置这两个过程时,我在我编写的pcb表中对pcb块进行malloc操作。以前有人遇到过类似的问题吗?这可能与我在调度程序中设置/交换上下文的方式有关吗?为什么它有时会出错,有时不会 由于堆栈似乎已损坏,您可能正确地认为堆栈缓冲区某处溢出。如果没有代码,就有点难说了 但这与您的
malloc
调用无关。溢出动态分配的缓冲区将损坏堆,而不是堆栈
您可能需要注意的是,局部变量对于您试图复制到其中的数据来说不够大,例如:
char xyzzy[5];
strcpy (xyzzy, "this is a bad idea";
或者将缓冲区(同样,最有可能在堆栈上)传递给系统调用,该系统调用向其写入的数据超过了您提供的数据量
它们是最有可能的原因,当然,理论上,你的任何未定义的行为都可能导致这种情况。如果基于此答案,解决方案不明显,则可能需要发布导致此问题的代码。当你这么做的时候,尽量确保你尽可能地把它删减,这样它才是展示错误的最短完整程序
通常您会发现,通过这样做,问题变得很明显:-)您没有说明如何获得问题中显示的堆栈跟踪
堆栈跟踪很可能是伪造的,不是因为堆栈已损坏,而是因为您错误地调用了GDB,例如在附加进程或检查核心转储时指定了错误的可执行文件
一个常见的错误是使用-O2
构建可执行文件(我们称之为可执行文件E1
),然后使用-g
(我们称之为E2
)重建它,并尝试分析运行E1
的活动进程的核心,将GDBE2
作为符号文件
不要这样做,它不起作用,也不应该起作用。你应该用调试信息编译你的代码(-g在gcc中),那么你的堆栈跟踪将更有意义。我怀疑-Wall
也会有帮助。你不应该描述你的代码,而应该在这里发布它。对具体代码的注释比对散文的注释更容易。另外,请不要在C中强制转换malloc返回值,它至少可以隐藏一个潜在的错误,在某个时候会咬到你。它会把你的代码弄得乱七八糟。C完全能够隐式地将void*
转换为任何其他指针类型。在上面。你能帮我找出哪里出了问题吗?thanks@user1710707,没有太多代码可以使用:-)但是,在我的回答中,很可能是后一个问题,将无效参数传递给调用。类似Exec的调用通常期望在argv数组的末尾有一个额外的元素,设置为null。不确定p_spawn_internal是否是这种情况,但您应该对此进行调查。