在我的应用程序中,我设置了信号处理程序来捕获段错误并打印 bactraces。 当进程启动时,我的应用程序加载了一些插件库。
如果我的应用程序因段错误而崩溃,这是由于主要可执行二进制文件中的错误,我可以通过以下方式分析回溯:
addr2line -Cif -e ./myapplication 0x4...
它准确地显示了函数和 source_file:line_no
但是如何分析崩溃是否是由于插件错误导致的,如下面的回溯?
/opt/myapplication(_Z7sigsegvv+0x15)[0x504245]
/lib64/libpthread.so.0[0x3f1c40f500]
/opt/myapplication/modules/myplugin.so(_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi+0x6af)[0x7f5588fe4bbf]
/opt/myapplication/modules/myplugin.so(_Z11myplugin_reqmodP12CONNECTION_TP7Filebuf+0x68)[0x7f5588fe51e8]
/opt/myapplication(_ZN10Processors7ExecuteEiP12CONNECTION_TP7Filebuf+0x5b)[0x4e584b]
/opt/myapplication(_Z15process_requestP12CONNECTION_TP7Filebuf+0x462)[0x4efa92]
/opt/myapplication(_Z14handle_requestP12CONNECTION_T+0x1c6d)[0x4d4ded]
/opt/myapplication(_Z13process_entryP12CONNECTION_T+0x240)[0x4d79c0]
/lib64/libpthread.so.0[0x3f1c407851]
/lib64/libc.so.6(clone+0x6d)[0x3f1bce890d]
我的应用程序和插件库都已使用 gcc 编译并且未剥离。 我的应用程序在执行时会使用 dlopen 加载 plugin.so 不幸的是,崩溃发生在我无法在 gdb 下运行应用程序的站点。
疯狂地在谷歌上搜索答案,但所有讨论回溯和 addr2line 的站点都排除了可能需要分析错误插件的情况。 我希望一些好心的黑客知道解决这个难题的方法,并且可以分享一些见解。这对其他程序员来说非常宝贵。
非常感谢。
最佳答案
以下是一些可以帮助您调试此问题的提示:
回溯中的地址是进程崩溃时进程地址空间中的一个地址。这意味着,如果您想将其转换为相对于库的 .text
部分开头的“物理”地址,则必须减去 相关部分的起始地址>pmap
来自你回溯中的地址。
不幸的是,这意味着您需要进程崩溃前的 pmap
。诚然,我不知道如果您关闭并重新运行它,单个系统上库的加载地址是否不变(可以想象有安全功能可以随机化它),但它肯定不能跨系统移植,正如您所注意到的。
在你的位置上,我会尝试:
- 使用
c++filt -n
或手动对符号名称进行解码。我现在没有 shell,所以这是我的手动尝试:_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi
是ICAPSection::process(CONNECTION_T *, Filebuf *, int)
。这可能已经有所帮助。如果不是: - 使用
objdump
或nm
(我很确定他们能做到)找到与错位名称对应的地址,然后添加偏移量(+0x6af
根据您的堆栈跟踪)到此,然后使用addr2line
查找结果地址。
关于c++ - 分析由于库故障而发生的崩溃的回溯,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18892033/