如何获得更详细的回溯

kor*_*han 19 c linux

当我的C++程序终止时,我正在尝试打印回溯.功能打印回溯如下所示;

   void print_backtrace(void){

       void *tracePtrs[10];
       size_t count;

       count = backtrace(tracePtrs, 10);

       char** funcNames = backtrace_symbols(tracePtrs, count);

       for (int i = 0; i < count; i++)
           syslog(LOG_INFO,"%s\n", funcNames[i]);

       free(funcNames);

}
Run Code Online (Sandbox Code Playgroud)

它给出了类似的输出;

   desktop program: Received SIGSEGV signal, last error is : Success
   desktop program: ./program() [0x422225]
   desktop program: ./program() [0x422371]
   desktop program: /lib/libc.so.6(+0x33af0) [0x7f0710f75af0]
   desktop program: /lib/libc.so.6(+0x12a08e) [0x7f071106c08e]
   desktop program: ./program() [0x428895]
   desktop program: /lib/libc.so.6(__libc_start_main+0xfd) [0x7f0710f60c4d]
   desktop program: ./program() [0x4082c9]
Run Code Online (Sandbox Code Playgroud)

有没有办法获得更详细的函数名称和行回溯,如gdb输出?

gby*_*gby 19

是 - 将-rdynamic标志传递给链接器.它将使链接器在链接表中输出代码中所有非静态函数的名称,而不仅仅是导出的函数.

您支付的价格是您的计划启动时间略长.对于中小型课程,你不会注意到它.你得到的是backtrace()能够给你后面跟踪中所有非静态函数的名称.

但是 - 请注意:您需要注意几个陷阱:

  1. backtrace_symbols从malloc分配内存.如果你因为malloc竞技场腐败(很常见)而进入SIGSEGV,那么你将在这里加倍故障并且永远不会看到你的背影.

  2. 根据运行的平台(例如x86),您崩溃的确切函数的地址/函数名称将在堆栈中替换为信号处理程序的返回地址.您需要从这些平台的信号处理程序参数中获取崩溃函数的正确EIP.

  3. syslog不是异步信号安全功能.它可能需要内部锁定,如果在发生崩溃时采取了锁定(因为你在另一次调用syslog的过程中崩溃了),你就会死锁

如果您想了解所有血腥细节,请查看我在OLS上发表演讲的视频:http://free-electrons.com/pub/video/2008/ols/ols2008-gilad-ben-yossef-故障handlers.ogg


Int*_*idd 0

如果您想要非常详细的回溯,您应该使用 ptrace(2) 来跟踪您想要回溯的进程。

您将能够看到您的进程使用的所有函数,但您需要一些基本的汇编知识