Ivan Baidakou
Ivan Baidakou

Reputation: 783

Determine inlined function address in dwarf

I have a virtual address (instruction pointer) of the function, obtained from backtrace call. I need to figure out the debug information about it.

For example, I need the information about attach_backtraces function.

nm -a Backtrace.so | grep attach_backtraces
000000000002cdfe t _ZN2xsL17attach_backtracesENS_3RefE

The offset 0x2cdfe can be determined by substracting from PC (IP) the .so loaded address. And it matches the output from nm.

The following infrormation I get from 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

Why it's offset is 0x21bf5 and not the expected 0x2cdfe? What a piece do I miss? My next step would be query DWARF-info for the function at the offset 0x2cdfe to get debug info.

PS. I'm gathering full backtrace, where symbol name, file and line should be presented. What C/C++ library are better to use to parse/get information from DWARF ?

Addon:

No, there are no other attach_backtraces in the readelf -w output. I have found that

DW_AT_sibling : <0x3a163>

and it's definition:

No, there are no other attach_backtraces in the readelf -w output. I have found that

DW_AT_sibling     : <0x3a163>

and it's definition:

<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 (the target function address).

Is this calculation correct?

Upvotes: 1

Views: 1959

Answers (2)

nnnsoft
nnnsoft

Reputation: 56

In first block of DWARF dump <3a150> (where we can see offset to function name, 0x21bf5) we also see DW_AT_declaration flag which indicates that declaration of a function was not completed in this DIE (see section 2.13 of DWARF 5 documentation).

To find the completion of declaration you should find DIE with DW_AT_specification attribute, which value is a reference to DIE which it completes (as in your 2nd block, <3f9f5>) and should have in your case value <3a150>.

Taking care on mentioned above I suppose that your 2nd block is not what you want to find since it references to another DIE <0x3a163>.

When you'll find right block, then you should use DW_AT_low_pc as a parameter you need (offset to 'attach_backtraces' from process base address).

Hope this helps.

Also, from my point of view dwarfdump tool shows a better output than readelf.

Upvotes: 1

Employed Russian
Employed Russian

Reputation: 213955

Why it's offset is 0x21bf5 and not the expected 0x2cdfe?

The offset 0x21bf5 is the offset of the name of the symbol ("attach_backtraces" here) in the .debug_str section (where the names off all types, parameters, variables and functions are collected).

That offset has absolutely no relation to the value of the symbol being represented (0x2cdfe here). These offsets just happened to be close to each other to confuse you.

What a piece do I miss?

Normally, a function should have DW_AT_low_pc attribute which represents its starting address (and the value of that attribute for attach_backtraces routine described by your output would be 0x2cdfe).

I am not sure why you are missing low_pc and high_pc here.

One possibility is that there are actually many instances of xs::attach_backtraces(xs::Ref) routine (if it's declared as inline in a header file), and the instance that you are looking at in readelf -w output was discarded by the linker (the function will appear in all object files which #included that header, but the linker will only keep a single instance of the function). If this is the case, look for another attach_backtraces in readelf -w output, with low_pc and high_pc present.

Upvotes: 2

Related Questions