1

I'm trying to parse the DWARF debug info to determine the functions from a stack trace address. If it works for my C functions (compiled with gcc), it doesn't for my C++ functions (compiled with g++)

My C functions all have a in the .debug_info table a DW_AT_low_pc and a DW_AT_low_high attribute which tell me what memory range this function is, e.g.

<1><17433>: Abbrev Number: 33 (DW_TAG_subprogram)
    <17434>   DW_AT_external    : 1
    <17434>   DW_AT_name        : (indirect string, offset: 0x4704): TLSCursor_init
    <17438>   DW_AT_decl_file   : 1
    <17439>   DW_AT_decl_line   : 46
    <1743a>   DW_AT_linkage_name: (indirect string, offset: 0x4536): _Z14TLSCursor_initP9TLSCursorP13TCPConnection
    <1743e>   DW_AT_low_pc      : 0x1178ce
    <17442>   DW_AT_high_pc     : 0x1b
    <17446>   DW_AT_frame_base  : 1 byte block: 9c  (DW_OP_call_frame_cfa)
    <17448>   DW_AT_GNU_all_call_sites: 1
    <17448>   DW_AT_sibling     : <0x17469>`

Most of my C++ methods, however most do NOT have such attributes:

`<2><144de>: Abbrev Number: 7 (DW_TAG_subprogram)
    <144df>   DW_AT_external    : 1
    <144df>   DW_AT_name        : (indirect string, offset: 0x3505): ~TLSNumber
    <144e3>   DW_AT_decl_file   : 3
    <144e4>   DW_AT_decl_line   : 23
    <144e5>   DW_AT_linkage_name: (indirect string, offset: 0x3510): _ZN9TLSNumberD4Ev
    <144e9>   DW_AT_accessibility: 1    (public)
    <144ea>   DW_AT_declaration : 1
    <144ea>   DW_AT_object_pointer: <0x144f2>
    <144ee>   DW_AT_sibling     : <0x144fd>

Is there any reason for this? How can I determine the address range of a function in that case?

intboolstring
  • 6,891
  • 5
  • 30
  • 44
user7094
  • 215
  • 2
  • 7

1 Answers1

3

DWARF method definitions can be split into an "abstract" and "concrete" parts. For example, it might be used when you have a function that is inlined in multiple locations. All of the pc-invariant information is stored in the abstract entry, while the concrete entries will have a pointer to the abstract entry and add the pc values for this specific instance of the method.

Look through your dwarf info for another DW_AT_abstract_origin which points back to this.

Also, there's a DW_AT_declaration tag on this subprogram die which tells you that this is a declaration (e.g. from a header file), not necessarily a definition. I may be wrong about this being an abstract/concrete pair, it could be that this information is duplicated in a declaration die later in the dwarf.

Jason Molenda
  • 14,835
  • 1
  • 59
  • 61