X86 64平台的函数调用链的解析stack unwind相关的资料

January 11, 2016 | 0 Minute Read

x86的call stack可以 esp ebp 和保存在栈上 "返回地址"就可以还原函数调用链了。 除非你用-fomit-frame-pointer改变了默认行为。 但x86-64寄存器多了之后,很多函数参数都是通过寄存器传递,这个“返回地址”默认 也不保存在栈上了。一直不清楚这个平台是怎么可以还原函数调用链的。不过听说libunwind 这个库是可以做到准确还原的。于是就搜索了一下资料。。。。 libunwind的库是可以用来解析 x86-64 的call stack的, 很多调试工具也都使用这个库来 做函数调用链的解析,比如perf, gperftools 等 x86-64的ABI要求ELF文件包含一个专门用于stack unwind的叫做.eh_frame的section .eh_frame This section holds the unwind function table. The contents are described in Section 4.2.4 of this document. DWARF 格式里面的 section .eh_frame( .debug_frame) CIE (Common Information Entry) FDEs (Frame Descriptor Entry). -》return_address_register -》register columns 的 register rule 指定了 怎么样还原 stack的 return addres,到底使用 寄存器还是偏移来计算等等。 详细的细节可以参考 ================== x86-64 的ABI文档 3.7 Stack Unwind Algorithm说了怎么利用这个eh_framex信息来解析堆栈的。 http://www.x86-64.org/documentation/abi.pdf DWARF Debugging Information Format Version 4 http://www.dwarfstd.org/doc/DWARF4.pdf gcc相关的选项 ============= -fomit-frame-pointer -fno-omit-frame-pointer -funwind-tables -fasynchronous-unwind-tables -fno-asynchronous-unwind-tables Generate unwind table in DWARF 2 format, if supported by target machine. The table is exact at each instruction boundary, so it can be used for stack unwinding from asynchronous events (such as debugger or garbage collector). x gcc相关的内置函数libc的函数可能用到这个特性的 C++ exceptions backtrace() __builtin_return_address 可以参考源码 ============ systemtap 里面 unwind.c perf 里面 unwind.c libunwind 应该也有