确定矮人中的内联函数地址
Determine inlined function address in dwarf
我有一个函数的虚拟地址(指令指针),从 backtrace 调用中获得。我需要找出关于它的调试信息。
例如,我需要有关attach_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
为什么它的偏移量是 0x21bf5
而不是预期的 0x2cdfe
?我错过了什么?我的下一步是查询 DWARF-info 以获取偏移 0x2cdfe
处的函数以获取调试信息。
PS。我正在收集完整的回溯,其中应显示符号名称、文件和行。 C/C++ 库更适合用于 parse/get 来自 DWARF
的信息?
插件:
不,readelf -w
输出中没有其他 attach_backtraces
。我发现
DW_AT_sibling : <0x3a163>
它的定义:
不,readelf -w
输出中没有其他 attach_backtraces
。我发现
DW_AT_sibling : <0x3a163>
它的定义:
<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>
0x2c59e (DW_AT_low_pc
) - 0x860 (DW_AT_high_pc
) = 0x2cdfe(目标函数地址)。
这个计算正确吗?
Why it's offset is 0x21bf5 and not the expected 0x2cdfe?
偏移量0x21bf5
是符号name在.debug_str
段(这里是"attach_backtraces"
)的偏移量(其中收集所有类型、参数、变量和函数的名称。
该偏移量与所表示符号的 值 完全没有关系(此处为0x2cdfe
)。这些偏移量恰好彼此接近以混淆你。
What a piece do I miss?
通常,一个函数应该有 DW_AT_low_pc
属性来表示它的起始地址(并且输出描述的 attach_backtraces
例程的该属性的值将是 0x2cdfe
)。
我不确定你为什么在这里缺少 low_pc
和 high_pc
。
一种可能性是 xs::attach_backtraces(xs::Ref)
例程实际上有很多实例(如果它在 header 文件中声明为 inline
),并且您正在查看的实例readelf -w
输出被链接器丢弃(该函数将出现在 #include
d 到 header 的所有 object 文件中,但链接器将只保留该函数的一个实例).如果是这种情况,请在 readelf -w
输出中查找 another attach_backtraces
,其中存在 low_pc
和 high_pc
。
在 DWARF 转储的第一个块 <3a150>(我们可以看到函数名称的偏移量 0x21bf5)中,我们还看到 DW_AT_declaration 标志,表示声明此 DIE 中的功能未完成(请参阅 DWARF 5 文档的第 2.13 节)。
要找到声明的完成,您应该找到具有 DW_AT_specification 属性的 DIE,该值是对它完成的 DIE 的引用(如在第二个块中, <3f9f5>) 并且在您的案例中应该有值 <3a150>.
注意上面提到的,我想你的第二个块不是你想要找到的,因为它引用了另一个 DIE <0x3a163>。
当你找到正确的块时,你应该使用 DW_AT_low_pc 作为你需要的参数(从进程基地址偏移到 'attach_backtraces')。
希望对您有所帮助。
此外,从我的角度来看,dwarfdump 工具显示的输出比 readelf 更好。
我有一个函数的虚拟地址(指令指针),从 backtrace 调用中获得。我需要找出关于它的调试信息。
例如,我需要有关attach_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
为什么它的偏移量是 0x21bf5
而不是预期的 0x2cdfe
?我错过了什么?我的下一步是查询 DWARF-info 以获取偏移 0x2cdfe
处的函数以获取调试信息。
PS。我正在收集完整的回溯,其中应显示符号名称、文件和行。 C/C++ 库更适合用于 parse/get 来自 DWARF
的信息?
插件:
不,readelf -w
输出中没有其他 attach_backtraces
。我发现
DW_AT_sibling : <0x3a163>
它的定义:
不,readelf -w
输出中没有其他 attach_backtraces
。我发现
DW_AT_sibling : <0x3a163>
它的定义:
<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>
0x2c59e (DW_AT_low_pc
) - 0x860 (DW_AT_high_pc
) = 0x2cdfe(目标函数地址)。
这个计算正确吗?
Why it's offset is 0x21bf5 and not the expected 0x2cdfe?
偏移量0x21bf5
是符号name在.debug_str
段(这里是"attach_backtraces"
)的偏移量(其中收集所有类型、参数、变量和函数的名称。
该偏移量与所表示符号的 值 完全没有关系(此处为0x2cdfe
)。这些偏移量恰好彼此接近以混淆你。
What a piece do I miss?
通常,一个函数应该有 DW_AT_low_pc
属性来表示它的起始地址(并且输出描述的 attach_backtraces
例程的该属性的值将是 0x2cdfe
)。
我不确定你为什么在这里缺少 low_pc
和 high_pc
。
一种可能性是 xs::attach_backtraces(xs::Ref)
例程实际上有很多实例(如果它在 header 文件中声明为 inline
),并且您正在查看的实例readelf -w
输出被链接器丢弃(该函数将出现在 #include
d 到 header 的所有 object 文件中,但链接器将只保留该函数的一个实例).如果是这种情况,请在 readelf -w
输出中查找 another attach_backtraces
,其中存在 low_pc
和 high_pc
。
在 DWARF 转储的第一个块 <3a150>(我们可以看到函数名称的偏移量 0x21bf5)中,我们还看到 DW_AT_declaration 标志,表示声明此 DIE 中的功能未完成(请参阅 DWARF 5 文档的第 2.13 节)。
要找到声明的完成,您应该找到具有 DW_AT_specification 属性的 DIE,该值是对它完成的 DIE 的引用(如在第二个块中, <3f9f5>) 并且在您的案例中应该有值 <3a150>.
注意上面提到的,我想你的第二个块不是你想要找到的,因为它引用了另一个 DIE <0x3a163>。
当你找到正确的块时,你应该使用 DW_AT_low_pc 作为你需要的参数(从进程基地址偏移到 'attach_backtraces')。
希望对您有所帮助。
此外,从我的角度来看,dwarfdump 工具显示的输出比 readelf 更好。