This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
debug/9509: Incorrect function starts in DWARF2 .debug_line section
- From: carlo at alinoe dot com
- To: gcc-gnats at gcc dot gnu dot org
- Date: 30 Jan 2003 17:13:02 -0000
- Subject: debug/9509: Incorrect function starts in DWARF2 .debug_line section
- Reply-to: carlo at alinoe dot com
>Number: 9509
>Category: debug
>Synopsis: Incorrect function starts in DWARF2 .debug_line section
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: unassigned
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Jan 30 17:16:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Carlo Wood
>Release: 3.2.1
>Organization:
>Environment:
>Description:
The match between (sourcefile-) line numbers and the actual
start of functions is (very) often wrong. This can be
checked with objdump for example.
Using libstdc++ as included with the gcc package as example
(because thats where I first noticed it), issuing for example:
objdump -d -l -j .text /usr/lib/libstdc++.so.5.0.2
shows all function starts and their first line number.
Correct is for example:
0004ab3c <_ZNSt9basic_iosIwSt11char_traitsIwEE4initEPSt15basic_streambufIwS1_E>:
_ZNSt9basic_iosIwSt11char_traitsIwEE4initEPSt15basic_streambufIwS1_E():
/usr/src/redhat/BUILD/gcc-3.2.1-20021208/obj-i386-redhat-linux/i386-redhat-linux/libstdc++-v3/include/bits/basic_ios.tcc:141
4ab3c: 55 push %ebp
4ab3d: 57 push %edi
4ab3e: 56 push %esi
where the sourcefile/line-number immedeately follows the
function header.
However, often we see:
00058078 <_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_bRSt8ios_basecRKSs>:
_ZNKSt9money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_bRSt8ios_basecRKSs():
58078: 55 push %ebp
58079: 89 e5 mov %esp,%ebp
/usr/src/redhat/BUILD/gcc-3.2.1-20021208/obj-i386-redhat-linux/i386-redhat-linux/libstdc++-v3/include/bits/locale_facets.tcc:1205
5807b: 57 push %edi
5807c: 56 push %esi
Where an arbitrary amount of instructions at the start
of the function is skipped.
I found that the reason for this is an incorrect
DW_LNS_advance_pc in the DWARF2 line info of the
*previous* function, just prior to its DW_LNE_end_sequence.
As a result, objdump prints out the above. The real
problem is that the address of the previous function
is pushed inside and behond the start of the next function:
an incorrect value of DW_LNS_advance_pc thus.
I can only show the analysis output of libcwd (my project)
while it tries to decode the .debug_line section in such
a case to make it a little more clear (hopefully).
For example, the start of the above function is decoded
(correctly) as:
BFD : |--> location.M_line = 1
BFD : |DW_LNS_set_file: "/i386-redhat-linux/libstdc++-v3/include/bits/locale_facets.tcc"
BFD : |--> location invalidated.
BFD : |DW_LNE_set_address: 0x58078
BFD : |--> location.M_address = 0x58078
BFD : |DW_LNS_advance_line: 1204
BFD : |--> location invalidated.
BFD : |--> location.M_line = 1205
BFD : |DW_LNS_copy
BFD : |--> location assumed valid.
BFD : |M_store(): M_range.start was 0.
BFD : |DW_LNS_set_file: "/i386-redhat-linux/libstdc++-v3/include/bits/ios_base.h"
BFD : |--> location invalidated.
BFD : |DW_LNS_advance_line: -812
BFD : |--> location invalidated.
BFD : |--> location.M_line = 393
BFD : |DW_LNS_const_add_pc
BFD : |--> location.M_address = 0x58089
BFD : |--> location now valid.
BFD : |M_store(): Registering new range.
BFD : |58078 - 58089; /i386-redhat-linux/libstdc++-v3/include/bits/locale_facets.tcc:1205 : "-DWARF symbol"..
And found to start at 58078 as per direct setting of
the address (with DW_LNE_set_address).
While the END of the *previous* function gives the
following output:
BFD : |M_store(): Registering new range.
BFD : |58064 - 5806e; /i386-redhat-linux/libstdc++-v3/include/bits/locale_facets.tcc:2129 : "-DWARF symbol"..
BFD : |DW_LNS_advance_pc: c
BFD : |--> location.M_address = 0x5807a
BFD : |Skipping M_store: location didn't change.
BFD : |DW_LNE_end_sequence: Address: 0x5807a
BFD : |--> Sequence end.
BFD : |M_store(): Registering new range.
BFD : |5806e - 5807a; /i386-redhat-linux/libstdc++-v3/include/bits/locale_facets.tcc:2131 : "-DWARF symbol"..
BFD : |WARNING: Different start for same function (58078 - 58089; /i386-redhat-linux/libstdc++-v3/include/bits/locale_fac
ets.tcc:1205 : "-DWARF symbol"..)!?
BFD : |WARNING: Different sizes for same function. Not sure what .stabs entry to use.
BFD : |WARNING: Different line numbers for overlapping range (58078 - 58089; /i386-redhat-linux/libstdc++-v3/include/bits/locale_facets.tcc:1205 : "-DWARF symbol"..)!?
The problem here is that 5807a, as is the result from the
"DW_LNS_advance_pc: c", is an address way behond the end
of the current function.
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted: