【问题标题】:Determine inlined function address in dwarf确定矮人中的内联函数地址
【发布时间】:2020-04-28 22:25:23
【问题描述】:

我有一个函数的虚拟地址(指令指针),从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?我错过了什么?我的下一步是在偏移量0x2cdfe 处查询函数的 DWARF-info 以获取调试信息。

附言。我正在收集完整的回溯,其中应显示符号名称、文件和行。哪个 C/C++ 库更适合用于从 DWARF 解析/获取信息?

插件:

不,readelf -w 输出中没有其他 attach_backtraces。我发现了

DW_AT_sibling:

它的定义:

不,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(目标函数地址)。

这个计算正确吗?

【问题讨论】:

  • 这个函数是内联的吗?

标签: debugging elf dwarf


【解决方案1】:

在 DWARF 转储 的第一个块中(我们可以看到函数名称的偏移量,0x21bf5),我们还看到 DW_AT_declaration 标志,它表示在此 DIE 中未完成函数声明(请参阅 DWARF 5 文档的第 2.13 节)。

要找到声明的完成,您应该找到具有 DW_AT_specification 属性的 DIE,该值是对它完成的 DIE 的引用(如在您的第二个块中,)并且应该在您的案例值 .

注意上面提到的,我想你的第二个块不是你想要找到的,因为它引用了另一个 DIE 。

当您找到正确的块时,您应该使用 DW_AT_low_pc 作为您需要的参数(从进程基地址偏移到 'attach_backtraces')。

希望这会有所帮助。

另外,从我的角度来看,dwarfdump 工具显示出比 readelf 更好的输出。

【讨论】:

    【解决方案2】:

    为什么它的偏移量是 0x21bf5 而不是预期的 0x2cfe?

    0x21bf5 的偏移量是.debug_str 部分中符号(此处为"attach_backtraces")的名称 的偏移量(其中所有类型、参数、变量和函数的名称为收集)。

    该偏移与所表示符号的绝对没有关系(此处为0x2cdfe)。这些偏移只是碰巧彼此靠近,让你感到困惑。

    我错过了什么?

    通常,函数应具有表示其起始地址的DW_AT_low_pc 属性(您的输出描述的attach_backtraces 例程的该属性的值将是0x2cdfe)。

    我不确定您为什么在这里缺少low_pchigh_pc

    一种可能性是实际上有很多 xs::attach_backtraces(xs::Ref) 例程实例(如果它在头文件中声明为 inline),并且您在 readelf -w 输出中查看的实例已被链接器丢弃(该函数将出现在所有#included 该标头的目标文件中,但链接器将只保留该函数的单个实例)。如果是这种情况,请在readelf -w 输出中查找另一个 attach_backtraces,并显示low_pchigh_pc

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-27
      相关资源
      最近更新 更多