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