我使用backtrace
和backtrace_symbols
在程序中抛出自定义异常时获取堆栈跟踪(目前,在Linux.
trace_size = backtrace(stack_traces, MAX_STACK_FRAMES);
messages = backtrace_symbols(stack_traces, trace_size);
字符串
从堆栈跟踪中,我能够循环遍历每个帧,并提取程序在该帧的地址。
根据函数定义的位置,我得到两种类型的地址:
1.图书馆地址:
/path/to/library.so(mangled_function_name+0x75) [0x7f02bcdfa849]
^^^^^^^^^^^^^^
型
1.可执行地址:
/path/to/executable(mangled_function_name?+0x90) [0x403336]
^^^^^^^^
型[0x7f02bcdfa849]
和[0x403336]
是我关心的问题。
我想把这些地址传递给addr2line
。
然而,对于属于共享库的地址,这将不起作用,我了解到我首先需要计算解析地址与库加载的基址的偏移量。
addr2line -e /path/to/library.so 0x7f02bcdfa849 # won't work
# or
addr2line -e /path/to/executable 0x403336 # works just fine
型
我知道我可以使用::dladdr
来找到基址,并从中找到偏移量。
但是,在运行时,我如何判断我是否需要进行这种转换?比如,我如何判断一个地址在运行时是否属于一个共享库?
我试着简单地检查.so
是否显示在堆栈跟踪的框架中,但感觉......不对。
1条答案
按热度按时间k5ifujac1#
::dladdr1
有我需要的信息。如果我有
addr_ptr
,它是共享库或共享exe中的地址,我可以通过调用::dladdr1
并使用返回的::link_map
数据结构来获取要从addr_ptr
中减去的基址。::link_map
有一个名为l_addr
的字段,对于exe为0,对于链接库为非零。因此,给定一个具有解析地址的
addr_ptr
:字符串
final_ptr
现在有正确的值传递给addr2line