【问题标题】:backtrace by SIGSEGVSIGSEGV 的回溯
【发布时间】:2011-05-13 11:40:47
【问题描述】:

我正在调试一个用 ansi C 编写的应用程序,一个多线程程序。
有时,在主线程中会导致 SIGSEGV 故障。

(gdb) backtrace full
#0  0x0000000000000000 in ?? ()
No symbol table info available.
#1  0x0000000000000000 in ?? ()
No symbol table info available.
(gdb) info registers
rax            0x1      1
rbx            0x0      0
rcx            0x0      0
rdx            0x2      2
rsi            0x458e7aa0       1166965408
rdi            0x0      0
rbp            0x0      0x0
rsp            0x458e7b60       0x458e7b60
r8             0x458e7b20       1166965536
r9             0x0      0
r10            0x0      0
r11            0x206    518
r12            0x2aaaac400e70   46912522686064
r13            0x2aaaac514090   46912523813008
r14            0x1      1
r15            0x18505f10       407920400
rip            0x0      0
eflags         0x10206  [ PF IF RF ]
cs             0x33     51
ss             0x2b     43
ds             0x0      0
es             0x0      0
fs             0x63     99
gs             0x0      0
fctrl          0x37f    895
fstat          0x0      0
ftag           0xffff   65535
fiseg          0x0      0
fioff          0x0      0
foseg          0x0      0
fooff          0x0      0
fop            0x0      0
mxcsr          0x1f80   [ IM DM ZM OM UM PM ]
(gdb)

此信息来自核心文件,我不是很喜欢在 Linux 环境中调试,有什么办法可以找出问题所在吗?

编辑:所有的源文件都用如下标志编译

gcc -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/redisconnector.d" -MT"src/redisconnector.d" -o"src/redisconnector.o" "../src/redisconnector.c"

【问题讨论】:

  • 请列出所有编译选项和 GCC 版本
  • 好的,我已经编辑了问题。

标签: c linux debugging segmentation-fault backtrace


【解决方案1】:

您的 RIP 指向 0。这可能是由堆栈溢出引起的。你的 RBP 也是 0,所以backtrace gdb 命令什么也不会告诉你。

【讨论】:

  • 补充一点,如果它是堆栈溢出,那么您很可能正在写入数组(或字符串)的末尾。我会先检查那里。
  • @OmnipotentEntity 我认为您的意思是当您写入数组末尾时缓冲区溢出?
  • 好吧,如果你的缓冲区在堆栈上,那也是一样的。缓冲区溢出是任何缓冲区、堆栈、堆等。堆栈溢出专门覆盖堆栈的缓冲区。你可以说这是一个堆栈溢出,因为指令指针被搞砸了。 :)
  • @OmnipotentEntity:也可能是覆盖了 GOT、C++ vtable 或指向函数的指针……只是我觉得堆栈溢出的可能性更大(并且 RBP 也是 0,但是 x86_64 通常是用帧指针编译的吗?)。
  • x86_64 在优化级别 0、1、2 上使用帧指针编译。
【解决方案2】:

使用“-g”选项重新编译应用程序;

不将 Gdb 用于核心文件,而是用于运行整个应用程序:

gdb --args ./application application_options

然后“运行”gdb 命令。

从 gdb 运行将检测 SIGSEGV,gdb 将专注于失败的线程。

【讨论】:

    【解决方案3】:

    嗯,首先您需要在启用调试的情况下进行编译,以便您的回溯有一些可用的东西。标志是 gcc -g

    【讨论】:

    • 我已经用 -g3 编译过了,但能显示的就这些了。
    猜你喜欢
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 2018-07-07
    • 1970-01-01
    • 2011-10-10
    • 2021-04-03
    • 1970-01-01
    相关资源
    最近更新 更多