c - 程序接收到信号 SIGSEGV,段错误(程序用完堆栈。)

标签 c gdb segmentation-fault

当我用 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

最佳答案

The error is shown at this line:

long a = thread_fake(); //in file1.c

这可能会导致 SIGSEGV如果您的程序已用完堆栈。

使用 x/i $pc 检查 GDB 中的实际崩溃指令.

如果指令是 PUSH , 或 CALL ,那么我的猜测得到了证实。

另一种可能性:您已经通过优化编译了代码,而实际的错误指令与它归因于的源代码行几乎没有关系。

更新:

Yes it gives a call call 0x804e580 <thread_fake>. What could be the solution?

解决方案是不要用完堆栈。执行 GDB where命令,然后,在导致崩溃的每个帧中,执行 info frame并寻找过大的框架。

不要在堆栈上分配太多数据,或增加堆栈大小 (ulimit -s)。

valgrind shows the following error:

也就是

  • 不是错误
  • 与你的问题无关

更新 2:

How do I check the size of each frame?

鉴于此:

Stack level 0, frame at 0xffffc248:
...
Stack level 1, frame at 0xffffc250:
...
Stack level 2, frame at 0xffffc2a0:

第 1 帧的大小是 8 ( 0xffffc250 - 0xffffc248 ),第 2 帧是 80

最终更新:

事实证明,我上面的程序未能测量 frame#0 的大小,结果是……61MB!由于存在巨大的本地数组(正如 Grady Player 正确猜到的那样)。

关于c - 程序接收到信号 SIGSEGV,段错误(程序用完堆栈。),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18751532/

相关文章:

Calloc() 不分配零

c - 存储在有一些空格的数组中

c++ - QtCreator 调试器只显示汇编程序

c - 在我的 C 程序中出现 SIGSEGV 错误

c++ - 如何判断 Qt (C/C++) 程序中是否正在运行屏幕保护程序? (微软 Windows )

c - 动态矩阵和动态值到矩阵

c++ - 在 gdb 中打印整个链表?

gdb宏确定被调试程序的体系结构

linux - SECTION .DATA 中变量的段错误

c - 为什么我会出现段错误 [139]?