生成 C++ OS/X 中的 BackTraces (10.5.7)

发布于 2024-08-02 00:40:52 字数 796 浏览 6 评论 0原文

我一直在利用 backtrace 和 backtrace_symbols 生成编程堆栈跟踪,以便进行日志记录/诊断。 它似乎大致有效,但是,我遇到了一些混乱,并且没有与每个函数调用关联的随附文件/行号(正如我在 gdb bt 调用或其他内容中所期望的那样)。 这是一个示例:

1 leonardo 0x00006989 _ZN9ExceptionC2E13ExceptionType + 111
2 莱昂纳多 0x00006a20 _ZN9ExceptionC1E13ExceptionType + 24
3 莱昂纳多 0x0000ab64 _ZN5Rules11ApplyActionER16ApplicableActionR9GameState + 1060
4 莱昂纳多 0x0000ed15 _ZN9Simulator8SimulateEv + 2179
5 莱昂纳多 0x0000eec9 _ZN9Simulator8SimulateEi + 37
6 莱昂纳多 0x00009729 主 + 45
7 leonardo 0x000025c6 start + 54

我遗漏了什么,做了一些愚蠢的事情,或者这就是我在 OS/X 上的回溯中所期望的一切?

其他一些花絮:

  • 我没有看到我正在使用的 g++ 版本 (4.0.1) 的 rdynamic 链接选项。
  • -g/-g3 没有任何区别。
  • abi::__cxa__demangle 似乎没有做任何事情

  • I've been utilizing backtrace and backtrace_symbols to generate programmatic stack traces for the purposes of logging/diagnosis. It seems to roughly work, however, I'm getting a little bit of mangling and there are no accompanying file/line numbers associated with each function invocation (as I'd expect within a gdb bt call or something). Here's an example:

    1 leonardo 0x00006989 _ZN9ExceptionC2E13ExceptionType + 111
    2 leonardo 0x00006a20 _ZN9ExceptionC1E13ExceptionType + 24
    3 leonardo 0x0000ab64 _ZN5Rules11ApplyActionER16ApplicableActionR9GameState + 1060
    4 leonardo 0x0000ed15 _ZN9Simulator8SimulateEv + 2179
    5 leonardo 0x0000eec9 _ZN9Simulator8SimulateEi + 37
    6 leonardo 0x00009729 main + 45
    7 leonardo 0x000025c6 start + 54

    Anything I'm missing something, doing something silly, or is this all I can expect out of backtrace on OS/X?

    Some other tidbits:

  • I don't see a rdynamic link option for the g++ version (4.0.1) I'm using.
  • -g/-g3 doesn't make any difference.
  • abi::__cxa__demangle doesn't seem to do anything

  • 如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

    扫码二维码加入Web技术交流群

    发布评论

    需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

    评论(2

    怼怹恏 2024-08-09 00:40:52

    回溯通常以以下格式从 backtrace_symbols 返回:

    ./MyApp(_ZN4test3fooEv+0x8) [0x821c874]

    abi::__cxa_demangle 仅需要函数名称。 因此,必须首先对跟踪进行一些解析:

          std::string trace(backtrace[idx]);
    
          // attempt to demangle
          {
             std::string::size_type begin, end;
    
             // find the beginning and the end of the useful part of the trace
             begin = trace.find_first_of('(') + 1;
             end = trace.find_last_of('+');
    
             // if they were found, we'll go ahead and demangle
             if (begin != std::string::npos && end != std::string::npos) {
                trace = trace.substr(begin, end - begin);
    
                size_t maxName = 1024;
                int demangleStatus;
    
                char* demangledName = (char*) malloc(maxName);
                if ((demangledName = abi::__cxa_demangle(trace.c_str(), demangledName, &maxName,
                      &demangleStatus)) && demangleStatus == 0) {
                   trace = demangledName; // the demangled name is now in our trace string
                }
                free(demangledName);
             }
          }

    我已经在我自己的项目中测试了这一点,并且它提供了更好的回溯,格式如下:

    test::foo()

    当然,没有行号,但我我不确定这是否可能。

    The backtraces typically come back from backtrace_symbols in the following format:

    ./MyApp(_ZN4test3fooEv+0x8) [0x821c874]

    abi::__cxa_demangle expects only the function name. Thus, some parsing must first be done on the trace:

          std::string trace(backtrace[idx]);
    
          // attempt to demangle
          {
             std::string::size_type begin, end;
    
             // find the beginning and the end of the useful part of the trace
             begin = trace.find_first_of('(') + 1;
             end = trace.find_last_of('+');
    
             // if they were found, we'll go ahead and demangle
             if (begin != std::string::npos && end != std::string::npos) {
                trace = trace.substr(begin, end - begin);
    
                size_t maxName = 1024;
                int demangleStatus;
    
                char* demangledName = (char*) malloc(maxName);
                if ((demangledName = abi::__cxa_demangle(trace.c_str(), demangledName, &maxName,
                      &demangleStatus)) && demangleStatus == 0) {
                   trace = demangledName; // the demangled name is now in our trace string
                }
                free(demangledName);
             }
          }

    I've tested this is on my own project, and it gives somewhat nicer backtraces with the following format:

    test::foo()

    Sure, there are no line numbers, but I'm not certain that is even possible.

    ゝ杯具 2024-08-09 00:40:52

    我不知道 backtrace_symbols() 的任何实现都提供了超过符号+偏移量的功能。

    对于 abi:: __cxa__demangle,您需要确保只传递符号名称,不带 + line 后缀,否则它不会将该符号识别为有效的。

    I don't know of any implementation of backtrace_symbols() which gives any more than symbol+offset.

    With regards to abi:: __cxa__demangle, you need to ensure that you only pass it the symbol name, without the + line suffix, otherwise it won't recognise the symbol as valid.

    ~没有更多了~
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文