如何通过 glibc/malloc 回溯(无可用内核)调试崩溃的 Linux 程序?

How to debug a crashed Linux program by its glibc/malloc backtrace (no core available)?

我在远程服务器上有一个 C++ 应用程序 运行。我最近引入了很多新代码。由于担心崩溃,我设置了 ulimit -c unlimited,一段时间后我遇到了崩溃,并出现了 coredump,这帮助我调试了一个问题。出于商业原因,运行 二进制文件没有调试符号,但我的 PC 上确实有 with-symbols 二进制文件,因此调试很容易。

今天更新后的服务又崩溃了,不幸的是这次它没有产生核心转储(旧的core文件还在那里,没有动过,我想这可能是某种预期的行为)。这次崩溃发生在 realloc() 内部,所以它向我提供了到 stdout 的堆栈跟踪:

*** Error in `./MyApp': corrupted double-linked list: 0x0000000003a04940 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f05ed2897e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x7e6ed)[0x7f05ed2906ed]
/lib/x86_64-linux-gnu/libc.so.6(+0x81cde)[0x7f05ed293cde]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x54)[0x7f05ed296184]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0x358)[0x7f05ed296a18]
./MyApp[0x453f58]
./MyApp[0x454a42]
./MyApp[0x457cd6]
./MyApp[0x45eb19]
./MyApp[0x49cfd7]
./MyApp[0x49707b]
./MyApp[0x70734e]
...
a lot more lines
...
./MyApp[0x664c65]
./MyApp[0x73e7b2]
./MyApp[0x70d849]
./MyApp[0x783af4]
./MyApp[0x425da8]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f05ed232830]
./MyApp[0x43a0c9]
======= Memory map: ========
...
< a huge table of memory mappings, ending with: >
Aborted (core dumped)

如前所述,核心文件与上次崩溃没有变化,因此无法使用。

我想知道我是否可以使用这个堆栈跟踪来手动找出哪个函数触发了 realloc() 破坏了一切。我尝试 addr2line 使用提到的地址,但我觉得它把我送到了错误的地方,因为它们完全不相关。可能我应该以某种我不理解并且在谷歌搜索后找不到的方式使用内存映射。是否有使用此类堆栈跟踪的指南?

objdump - 来自 GNU 工具链的一个很酷的程序,可以显示有关二进制的信息。链接库、内存对齐、函数表等等。

常用:
objdump -T <file>

还有一些工具可以帮助您。像 nmreadelf(对于 elf 文件)。

nm -g -C <file>
readelf -sW <file>