gcc/g++ is generating the same DWARF DW_AT_ranges info for two different
functions. This makes translation from a PC address to the function difficult
since a given PC can map to two different functions.

Using the following test file:

    // Compile as "g++ -O2 -ggdb --save-temps -o t t.cc"
    
    #include <vector>
    
    using namespace std;
    
    int main ()
    {
      vector<int> V(10);
      V[10] = 1;
    }
the DWARF info emitted by gcc assigns a block of addresses to two
different functions, get_allocator and _S_get_pool.  Here is an edited
dump of the DWARF info produced by readelf.

 <2><2523>: Abbrev Number: 38 (DW_TAG_subprogram)
     DW_AT_name        : (indirect string, offset: 0x1d35): get_allocator       
 <1><3807>: Abbrev Number: 77 (DW_TAG_subprogram)
     DW_AT_specification: <2523>        
     DW_AT_inline      : 3      (declared as inline and inlined)
 <3><39de>: Abbrev Number: 92 (DW_TAG_inlined_subroutine)
     DW_AT_abstract_origin: <3807>      
     DW_AT_ranges      : 0x5c8  
    000005c8 080488c9 080488d0
    000005c8 08048a50 08048af6
    000005c8 080488dc 080488e2
    000005c8 <End of list>

 <2><227c>: Abbrev Number: 64 (DW_TAG_subprogram)
     DW_AT_name        : (indirect string, offset: 0x666): _S_get_pool  
 <1><2e03>: Abbrev Number: 77 (DW_TAG_subprogram)
     DW_AT_specification: <227c>        
     DW_AT_inline      : 3      (declared as inline and inlined)
 <6><3a12>: Abbrev Number: 92 (DW_TAG_inlined_subroutine)
     DW_AT_abstract_origin: <2e03>      
     DW_AT_ranges      : 0x628  
    00000628 080488c9 080488d0
    00000628 08048a50 08048af6
    00000628 080488dc 080488e2
    00000628 <End of list>

When one function inlines another, and all of the associated code is generated
for the inlinee with no code generated for the inliner, my reading of the draft
DWARF 3 spec, which describes DW_AT_ranges, would indicate that no  
DW_AT_low_pc, DW_AT_high_pc, or DW_AT_ranges attributes should be generated for
the inliner function:

  2.16 Code Addresses and Ranges

  Any debugging information entry describing an entity that has a
  machine code address or range of machine code addresses, which
  includes compilation units, module initialization, subroutines,
  ordinary blocks, try/catch blocks, labels and the like, may have " A
  DW_AT_low_pc attribute for a single address, " A DW_AT_low_pc and
  DW_AT_high_pc pair of attributes for a single contiguous range of
  addresses, or " A DW_AT_ranges attribute for a non-contiguous range of
  addresses. If an entity has no associated machine code, none of these
  attributes are specified.

My understanding, perhaps incorrect, is that the entire purpose of using the
DW_AT_ranges attribute, instead of the DW_AT_low_pc/DW_AT_high_pc attributes,
is to be able to accurately describe situations like this, where code from
different functions is interleaved due to optimization.  No given address 
should appear in more than one DW_AT_ranges entry.

-- 
           Summary: g++ generates same DW_AT_ranges info for two different
                    functions
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: debug
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: fnf at specifixinc dot com
                CC: fnf at specifixinc dot com,gcc-bugs at gcc dot gnu dot
                    org
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=20967

Reply via email to