This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

debug/9509: Incorrect function starts in DWARF2 .debug_line section


>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:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]