Debugging 确定dwarf中的内联函数地址
我有一个函数的虚拟地址(指令指针),从调用中获得。我需要找出关于它的调试信息 例如,我需要有关Debugging 确定dwarf中的内联函数地址,debugging,elf,dwarf,Debugging,Elf,Dwarf,我有一个函数的虚拟地址(指令指针),从调用中获得。我需要找出关于它的调试信息 例如,我需要有关attach\u backtraces函数的信息 nm -a Backtrace.so | grep attach_backtraces 000000000002cdfe t _ZN2xsL17attach_backtracesENS_3RefE 偏移量0x2cdfe可以通过从PC(IP)中减去.so加载的地址来确定。它与nm的输出相匹配 我从readelf-w Backtrace.so <3&
attach\u backtraces
函数的信息
nm -a Backtrace.so | grep attach_backtraces
000000000002cdfe t _ZN2xsL17attach_backtracesENS_3RefE
偏移量0x2cdfe
可以通过从PC(IP)中减去.so加载的地址来确定。它与nm
的输出相匹配
我从readelf-w Backtrace.so
<3><3a14f>: Abbrev Number: 0
<2><3a150>: Abbrev Number: 161 (DW_TAG_subprogram)
<3a152> DW_AT_name : (indirect string, offset: 0x21bf5): attach_backtraces
<3a156> DW_AT_decl_file : 22
<3a157> DW_AT_decl_line : 201
<3a158> DW_AT_decl_column : 13
<3a159> DW_AT_declaration : 1
<3a159> DW_AT_sibling : <0x3a163>
<3><3a15d>: Abbrev Number: 1 (DW_TAG_formal_parameter)
<3a15e> DW_AT_type : <0x36aac>
<3><3a162>: Abbrev Number: 0
它的定义是:
<1><3f9f5>: Abbrev Number: 27 (DW_TAG_subprogram)
<3f9f6> DW_AT_specification: <0x3a163>
<3f9fa> DW_AT_low_pc : 0x2c59e
<3fa02> DW_AT_high_pc : 0x860
<3fa0a> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<3fa0c> DW_AT_GNU_all_tail_call_sites: 1
<3fa0c> DW_AT_sibling : <0x3fb21>
:缩写编号:27(DW_标记_子程序)
DW_AT_规格:
DW_在_低_pc:0x2c59e
DW_在_高_pc:0x860
在帧基上的数据块:1字节块:9c(数据块操作调用帧cfa)
DW_AT_GNU_所有_tail_call_站点:1
DW_在_同级:
0x2c59e(DW\u位于低电平pc
)-0x860(DW\u位于高电平pc
)=0x2cdfe(目标函数地址)
这个计算正确吗
为什么它的偏移量是0x21bf5而不是预期的0x2cdfe
偏移量0x21bf5
是.debug\u str
部分(收集所有类型、参数、变量和函数的名称)中符号名称的偏移量(“attach\u backtraces”
)
该偏移量与所表示符号的值绝对没有关系(0x2cdfe
)。这些偏移正好彼此接近,让你感到困惑
我错过了什么
通常,函数应具有表示其起始地址的DW\u AT\u low\u pc
属性(输出描述的attach\u backtraces
例程的该属性值应为0x2cdfe
)
我不知道您为什么在这里缺少low\u pc
和high\u pc
一种可能性是,实际上有许多
xs::attach_backtraces(xs::Ref)
例程的实例(如果它在头文件中声明为inline
),并且链接器丢弃了您在readelf-w
输出中查看的实例(该函数将出现在包含该头的所有对象文件中,但链接器仅保留该函数的一个实例)。如果是这种情况,请在readelf-w
输出中查找另一个attach_backtraces
,并显示low_pc
和high_pc
。在矮人转储的第一个块中(我们可以看到函数名的偏移量,0x21bf5)我们还可以看到DW_AT_声明标志,它表明函数的声明没有在这个骰子中完成(参见DWARF 5文档的第2.13节)
要查找声明的完成情况,您应该查找具有DW_AT_specification属性的DIE,该值是对它完成的DIE的引用(如在第二个块中),并且应该在case值中包含该值
注意上面提到的,我想你的第二块不是你想要找到的,因为它引用了另一个模具
当找到正确的块时,应该使用DW_AT_low_pc作为所需的参数(从进程基址到“附加回溯”的偏移量)
希望这有帮助
另外,在我看来,dwarfdump工具显示出比readelf更好的输出
<1><3f9f5>: Abbrev Number: 27 (DW_TAG_subprogram)
<3f9f6> DW_AT_specification: <0x3a163>
<3f9fa> DW_AT_low_pc : 0x2c59e
<3fa02> DW_AT_high_pc : 0x860
<3fa0a> DW_AT_frame_base : 1 byte block: 9c (DW_OP_call_frame_cfa)
<3fa0c> DW_AT_GNU_all_tail_call_sites: 1
<3fa0c> DW_AT_sibling : <0x3fb21>