Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 分析由于错误库而发生的崩溃的回溯跟踪_C++_C_Backtrace_Debug Backtrace_Addr2line - Fatal编程技术网

C++ 分析由于错误库而发生的崩溃的回溯跟踪

C++ 分析由于错误库而发生的崩溃的回溯跟踪,c++,c,backtrace,debug-backtrace,addr2line,C++,C,Backtrace,Debug Backtrace,Addr2line,在我的应用程序中,我设置了信号处理程序来捕捉SEGFULTS,并打印bactraces。 当进程启动时,我的应用程序加载一些插件库 如果由于主可执行二进制文件中的错误,我的应用程序因segfault而崩溃,我可以使用以下方法分析回溯: addr2line -Cif -e ./myapplication 0x4... 它准确地显示函数和源文件:行号 但是,如何分析崩溃是否是由于插件中的错误造成的,如下面的回溯所示 /opt/myapplication(_Z7sigsegvv+0x15)[0x50

在我的应用程序中,我设置了信号处理程序来捕捉SEGFULTS,并打印bactraces。 当进程启动时,我的应用程序加载一些插件库

如果由于主可执行二进制文件中的错误,我的应用程序因segfault而崩溃,我可以使用以下方法分析回溯:

addr2line -Cif -e ./myapplication 0x4...
它准确地显示函数和源文件:行号

但是,如何分析崩溃是否是由于插件中的错误造成的,如下面的回溯所示

/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编译的,并且都是非压缩的。 我的应用程序在执行时,加载plugin.so和dlopen 不幸的是,崩溃发生在我无法在gdb下运行应用程序的站点

谷歌疯狂地四处寻找答案,但所有讨论backtrace和addr2line的网站都排除了可能需要分析错误插件的场景。 我希望一些善良的黑客知道这个困境的解决办法,并能分享一些见解。这对其他程序员来说是非常宝贵的


非常感谢。

这里有一些提示可以帮助您调试:

回溯中的地址是进程崩溃时进程地址空间中的地址。这意味着,如果要将其转换为相对于库的
.text
部分开始的“物理”地址,则必须从回溯中的地址减去
pmap
相关部分的开始地址

不幸的是,这意味着您需要在进程崩溃之前对其进行
pmap
。诚然,如果关闭并重新运行库,我不知道在单个系统上加载库的地址是否是恒定的(可以想象,有一些安全特性将其随机化),但正如您所注意到的,它肯定不能跨系统移植

在你的位置上,我会尝试:

  • 使用
    c++filt-n
    或手动请求符号名称。我现在没有shell,所以这里是我的手动尝试:
    \u ZN11ICAPSection7processEP12CONNECTION\u TP7Filebufi
    ICAPSection::process(CONNECTION\u t*,Filebuf*,int)
    。这可能已经有帮助了。如果没有:
  • 使用
    objdump
    nm
    (我很确定他们可以这样做)找到与损坏名称对应的地址,然后将偏移量(
    +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来确定指向损坏名称的地址。(在这一点上,us2012所做的Demanling并不是真正必要的)。因此,使用:

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

这是实际的源文件:错误代码的行号,可以用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
std::char\u traits::length(char const*)
/usr/include/c++/4.4/bits/char_traits.h:263
std::string::assign(字符常量*)
/usr/include/c++/4.4/bits/basic_string.h:970
std::string::operator=(字符常量*)
/usr/include/c++/4.4/bits/basic_string.h:514
??
/usr/local/src/unstable/myapplication/sources/modules/myplugin/myplugin.cpp:622

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

这些“插件库”有什么特别之处吗或者它们只是标准的共享库?还有,你看到这个问题了吗?@us2012是的,几个月前我已经查看了这个链接,并且还要求在派生方面更加清晰,请参见我的评论。顺便说一句,我的插件库是简单的c/c++对象,没有什么特别之处。衷心感谢您的关注。Oh、 这是你的评论!在看问题时没有意识到。你有来自pmap的lib起始地址吗?我不太清楚另一个问题从哪里得到数字,但我认为它应该像(在你的情况下)0x7f5588fe4bbf-[来自pmap的适当起始地址]一样简单。如果您在查找正确的部分时遇到困难,请将与您的库相对应的pmap部分添加到问题中。@us2012 pmap-d结果为:
00007fab30287000 48 r-x--0000000000000000 008:00001 myplugin.so 00007fab30293000 2044-----000000000000000000C000 008:00001 myplugin.so 00007fab30492000 4 r-x--000000000000 B000 008:00001 myplugin.so 00007fab30493000 4 rwx--000000000000 C000 008:00001 myplugin.so
所以我的库起始地址应该是0x7FAB030287000,对吧?答对了!你完全搞定了。它很有效,而且很精确。真是太感谢你了。我知道我会在这里受到ace攻击。再次感谢。我使用了nm。它的开关更少而且输出更易于使用。请查看下面,我已经详细阐述了您的提示,希望是正确的。干杯。