本文主要通过一个例子来介绍通过libunwind
打印函数调用栈的方法。
例子
来自网络
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #define UNW_LOCAL_ONLY #include <libunwind.h> #include <stdio.h>
void backtrace() { unw_cursor_t cursor; unw_context_t context;
unw_getcontext(&context); unw_init_local(&cursor, &context);
while (unw_step(&cursor) > 0) { unw_word_t offset, pc; unw_get_reg(&cursor, UNW_REG_IP, &pc); if (pc == 0) { break; } printf("0x%lx:", pc);
char sym[256]; if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) { printf(" (%s+0x%lx)\n", sym, offset); } else { printf(" -- error: unable to obtain symbol name for this frame\n"); } } }
void foo() { backtrace(); }
void bar() { foo(); }
int main(int argc, char **argv) { bar();
return 0; }
|
编译方法
对于gcc
或g++
通常需要添加-lunwind
参数,如果还显示链接错误,可以考虑再添加-lunwind-x86_64
参数
上述程序的输出
最前面的地址可能会不一样
1 2 3 4 5 6
| 0x555db4dc335e: (foo+0x12) 0x555db4dc3373: (bar+0x12) 0x555db4dc3393: (main+0x1d) 0x7fc1c20ccd90: (__libc_init_first+0x90) 0x7fc1c20cce40: (__libc_start_main+0x80) 0x555db4dc3165: (_start+0x25)
|