繁体   English   中英

分析由于库有错误而发生的崩溃的回溯

[英]Analyze backtrace of a crash occurring due to a faulty library

在我的应用程序中,我有设置信号处理程序来捕获Segfaults,并打印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_TP7FilebufiICAPSection::process(CONNECTION_T *, Filebuf *, int) 这可能已经有所帮助。 如果不:
  • 使用objdumpnm (我很确定他们可以这样做)找到对应于+0x6af名称的地址,然后将偏移量(根据你的+0x6af加上+0x6af )添加到此,然后使用addr2line查找结果地址。

us2012的答案是解决问题所需的诀窍。 我只是想在这里重申它只是为了帮助任何其他新手在同样的问题上挣扎,或者如果有人希望提供改进。

在回溯中,可以清楚地看到myplugin.so的代码中存在缺陷。 回溯表明它存在于:

/opt/myapplication/modules/myplugin.so(_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi+0x6af)[0x7f5588fe4bbf]

定位与此故障相对应的线的问题不能简单地确定为:

addr2line -Cif -e /opt/myapplication/modules/myplugin.so 0x7f5588fe4bbf

这里正确的过程是使用nm或objdump来确定指向受损名称的地址。 (目前还没有真正需要在2012年完成的解码)。 所以使用:

nm -Dlan /opt/myapplication/modules/myplugin.so | grep "_ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi"

我明白了:

0000000000008510 T _ZN11ICAPSection7processEP12CONNECTION_TP7Filebufi   /usr/local/src/unstable/myapplication/sources/modules/myplugin/myplugin.cpp:518

有趣的是,myplugin.cpp:518实际上指向函数ICAPSection :: process(CONNECTION_T *,Filebuf *,int)的开头“{”的行

接下来,我们使用linux shell命令将0x6af添加到地址(由上面的nm输出显示)0000000000008510

 printf '0x%x\n' $(( 0x0000000000008510 + 0x6af ))

这导致0x8bbf

这是错误代码的实际source_file:line_no,可以使用addr2line精确确定:

addr2line -Cif -e /opt/myapplication/modules/myplugin.so 0x8bbf

哪个显示:

std::char_traits<char>::length(char const*)
/usr/include/c++/4.4/bits/char_traits.h:263
std::string::assign(char const*)
/usr/include/c++/4.4/bits/basic_string.h:970
std::string::operator=(char const*)
/usr/include/c++/4.4/bits/basic_string.h:514
??
/usr/local/src/unstable/myapplication/sources/modules/myplugin/myplugin.cpp:622

我不太清楚为什么这里没有显示函数名,但myplugin.cpp:622恰恰是故障所在。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM