bfd/dwarf2: break equal-range function ties by DIE offset, not pointer
Fixes addr2line to use DIE offset for tie-breaking, improving consistency.
This patch addresses an issue in binutils’ addr2line tool where tie-breaking between functions with identical source code ranges was based on pointer comparison of struct funcinfo. Since these pointers could vary due to memory allocation order, addr2line sometimes reported different inlined functions for the same address. The change proposes using the Debug Information Entry (DIE) offset instead, which is a stable identifier, ensuring consistent reporting of inlined functions.
- proposer
Proposes breaking ties in `lookup_address_in_function_table` by using DIE offset instead of `struct funcinfo` pointers, which vary due to allocator behavior.
“Those come from bfd_zalloc. Addresses increase within an objalloc chunk, but a new chunk can land below the old one, so which of the two functions addr2line named depended on where the allocator happened to put them. On the same binary, 23 of 200 addr2line -f -i runs named a different inlined function for the same address. Only the function name moved; file and line never did.”
In Details
This patch modifies the DWARF parsing logic within binutils' BFD library, specifically in bfd/dwarf2.c, affecting the addr2line utility. The lookup_address_in_function_table function currently resolves addresses to functions. When multiple functions cover the same address range (common with inlined subroutines), it breaks ties by comparing struct funcinfo pointers. This approach is unstable as these pointers depend on bfd_zalloc's allocation order. The patch proposes using the Debug Information Entry (DIE) offset, a stable identifier, for tie-breaking to ensure deterministic results.
- addr2line
- A utility that translates addresses into line number and function name information from object files, using DWARF debugging information.
- BFD
- Binary File Descriptor library, a part of binutils that provides a common interface for reading and writing various executable binary file formats.
- DWARF
- A debugging data format used by many compilers and debuggers to store information about source code, variables, types, and scopes.
- DIE
- Debug Information Entry. A fundamental unit within DWARF data, representing a symbol, type, or other program construct.
- inlined subroutine
- A function call that has been replaced by the actual code of the called function at the call site by the compiler, to improve performance. In DWARF, this is represented by a DW_TAG_inlined_subroutine DIE.
- objalloc
- An object allocator, likely within BFD, used for managing memory for DWARF data structures.