当我使用gdb运行程序时,我收到此错误消息。错误显示在以下行:
long a = thread_fake(); //in file1.c
我遇到了在单独文件中定义的其他函数的问题,所以我简化为一个只返回0的简单函数。 该函数定义为:
long thread_fake(){ //defined in file2.c
return 0;
}
正如@EmployedRussian指出的那样,程序看起来似乎没有堆栈。 valgrind显示以下错误:
==14711== 144 bytes in 1 blocks are possibly lost in loss record 17 of 32
==14711== at 0x4025315: calloc (vg_replace_malloc.c:467)
==14711== by 0x4010CD7: allocate_dtv (dl-tls.c:300)
==14711== by 0x401146B: _dl_allocate_tls (dl-tls.c:464)
==14711== by 0x40475C6: pthread_create@@GLIBC_2.1 (allocatestack.c:570)
==14711== by 0x8050583: tm_main_startup
==14711== by 0x8048F6B: main (genome.c:201)
==14711== 144 bytes in 1 blocks are possibly lost in loss record 18 of 32
==14711== at 0x4025315: calloc (vg_replace_malloc.c:467)
==14711== by 0x4010CD7: allocate_dtv (dl-tls.c:300)
==14711== by 0x401146B: _dl_allocate_tls (dl-tls.c:464)
==14711== by 0x40475C6: pthread_create@@GLIBC_2.1 (allocatestack.c:570)
==14711== by 0x804DFE3: thread_startup (thread.c:151)
==14711== by 0x8048F73: main (genome.c:203)
创建的所有线程都加入了相应的pthread_join调用。此外,我尝试了sgcheck工具,但它不适用于平台'x86-linux'。请帮忙。
bt命令的完整输出:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x406e8b70 (LWP 19416)]
sequencer_run (argPtr=0x89fce00) at sequencer.c:251
251 a = thread_fake();
(gdb) bt
#0 sequencer_run (argPtr=0x89fce00) at sequencer.c:251
#1 0x0804e306 in threadWait (argPtr=0x89dc1f4) at ../lib/thread.c:105
#2 0x4003be99 in start_thread (arg=0x406e8b70) at pthread_create.c:304
#3 0x40253cbe in clone () at ../sysdeps/unix/sysv/linux/i386/clone.S:130
答案 0 :(得分:2)
错误显示在以下行:
long a = thread_fake(); //in file1.c
如果您的程序已经用完了堆栈,那么SIGSEGV
可能会出现这种情况。
使用x/i $pc
检查GDB中的实际崩溃指令。
如果说明是PUSH
或CALL
,那么我的猜测就会得到确认。
另一种可能性:您已经使用优化编译了代码,实际的错误指令与它所归属的源代码行几乎没有关系。
更新
是的,它会拨打电话
call 0x804e580 <thread_fake>
。可能是什么解决方案?
解决方案是不要耗尽堆栈。执行GDB where
命令,然后,在每个导致崩溃的帧中,执行info frame
并查找过大的帧。
不要在堆栈上分配太多数据,也不要增加堆栈大小(ulimit -s
)。
valgrind显示以下错误:
那是
UPDATE2:
如何检查每个帧的大小?
鉴于此:
Stack level 0, frame at 0xffffc248:
...
Stack level 1, frame at 0xffffc250:
...
Stack level 2, frame at 0xffffc2a0:
第1帧的大小为8
(0xffffc250 - 0xffffc248
),第2帧为80
等。
最终更新:
事实证明我上面的程序无法测量帧#0的大小,结果是...... 61MB!由于存在 humongous 本地数组(正如Grady Player正确猜测的那样)。