代码之家  ›  专栏  ›  技术社区  ›  Leedehai

macOS v.s.Linux上的回溯信息不同

  •  0
  • Leedehai  · 技术社区  · 6 年前

    #include <signal.h>    
    #include <stdio.h>
    #include <stdlib.h>
    
    #include <execinfo.h>
    #include <unistd.h>
    
    void handler(int sig) {
      void *array[10];
      size_t size;
    
      // get void*'s for all entries on the stack
      size = backtrace(array, 10);
    
      // print out all the frames to stderr
      fprintf(stderr, "Error: signal %d:\n", sig);
      backtrace_symbols_fd(array, size, STDERR_FILENO);
      exit(1);
    }
    
    void baz() {
      int *foo = (int*)-1; // make a bad pointer
      printf("%d\n", *foo);       // causes segfault
    }
    
    void bar() { baz(); }
    void foo() { bar(); }
    
    
    int main(int argc, char **argv) {
      signal(SIGSEGV, handler);   // install our handler
      foo(); // this will call foo, bar, and baz.  baz segfaults.
    }
    

    这是编译和链接步骤(在macOS上, g++ clang++ ):

    g++ backtrace_example.cc -c -O0
    g++ -rdynamic backtrace_example.o -o bt_example
    

    这是印在macOS上的回溯信息:

    $ ./bt_example
    Error: signal 11:
    0   bt_example                          0x000000010dd39dbf handler + 31
    1   libsystem_platform.dylib            0x00007fff5e0b7b3d _sigtramp + 29
    2   ???                                 0x0000000117f6a7c7 0x0 + 4697008071
    3   bt_example                          0x000000010dd39eb9 _Z3barv + 9
    4   bt_example                          0x000000010dd39ec9 _Z3foov + 9
    5   bt_example                          0x000000010dd39efe main + 46
    6   libdyld.dylib                       0x00007fff5dece085 start + 1
    7   ???                                 0x0000000000000001 0x0 + 1
    

    这是在Linux上打印的回溯信息:

    $ ./bt_example
    Error: signal 11:
    ./bt_example(handler+0x2b)[0x400982]
    /lib/x86_64-linux-gnu/libc.so.6(+0x354b0)[0x7f2aefc534b0]
    ./bt_example(_Z3bazv+0x14)[0x4009db]
    ./bt_example(_Z3barv+0x9)[0x4009fa]
    ./bt_example(_Z3foov+0x9)[0x400a06]
    ./bt_example(main+0x23)[0x400a2c]
    /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f2aefc3e830]
    ./bt_example(_start+0x29)[0x4008a9]
    

    除了格式上的差异,还有一个关键的区别:macOS版本没有提到函数 baz() 巴兹() .

    backtrace_symbol_fd() ,或者这是有意的(如果是,怎么做)?

    参考:GNU文档 glibc's backtraces

    1 回复  |  直到 6 年前
        1
  •  0
  •   Ken Thomases    6 年前

    首先,您在 handler 可以从信号处理程序调用。因此,你完全处于未定义的行为领域。

    第二,这并不是一个缺陷 backtrace here .