[patch] Fix to processing end of function stab in dbxread.c

Jim Ingham jingham@apple.com
Thu Jul 11 11:42:00 GMT 2002


Daniel,

We are talking about two different things here - I am talking about  
converting the value in the blank FUN stab that marks the end of a  
function to a read address, NOT correcting an SLINE stab.  That may  
seem confusing given that I was talking about linetables, so I will  
give my previous explanation in a little more detail.

What is happening is that Fred was trying to work around the problem  
that SLINE's only give the start of the region of code assigned to that  
source line.  You rely on the next SLINE to get the end.  However, you  
can't always rely on the last line in a function to be properly  
terminated by a reasonable SLINE stab.  For instance MacOS X's linker  
will coalesce all the out-of-line copies of an inlined function, or of  
lots of the compiler generated C++ goop, and shove them in a separate  
segment at the end of the text section.  When it does that it updates  
all the various debug output.  So we end up with something like  
(StrLength here was an inlined function):

0001abcc - 01 0099 SLINE
0001abf0 - 01 009c SLINE
0001abfc - 01 009d SLINE
0001ac08 - 01 009f SLINE
0001ac20 - 01 00a0 SLINE
0001ac30 - 01 00a2 SLINE
0001ac5c - 01 00a3 SLINE
0001ac88 - 01 00a4 SLINE
0001abcc - 01 0099   FUN _Z14GetPictureSizesPlS_:f(1,1)
00000078 - 00 0099  PSYM resID:p(1,145)
0000007c - 00 0099  PSYM height:p(1,260)=*(1,81)
00000080 - 00 0099  PSYM width:p(1,260)
00000040 - 00 009a  LSYM picture:(1,171)
0001abf0 - 01 0000 LBRAC
0001ac88 - 01 0000 RBRAC
000000d0 - 00 0000   FUN
00031fd4 - 0c 0000   SOL  
/System/Library/Frameworks/CoreServices.framework/Headers/../ 
Frameworks/CarbonCore.framework/Headers/MacTypes.h
00031fd4 - 0c 019c SLINE
00031fe4 - 0c 019c SLINE
00031fd4 - 0c 019c   FUN StrLength:F(1,73)
00000048 - 00 019c  PSYM string:p(1,261)=(1,262)=*(1,263)=k(1,73)
00000000 - 00 0194  LSYM ConstStr255Param:t(1,261)
0000002c - 00 0000   FUN

Now line 0xa4 is going to stretch from 0001ac88 to 00031fd4.  Bad, bad,  
bad...

Fred's fix was to emit a fake linetable entry - with linenumber 0, when  
he sees the end of function stab.  That way, in the linetable there is  
just a region with no associated linenumbers from the end of the  
function to 00031fd4.  The problem was getting "the end of the  
function" from the data in the null FUN stab.  The value of the stab is  
the offset from the beginning of the function.  He was adding that to  
function_start_offset which according to the comment in the file is NOT  
the address of the last function on any system but Solaris.  It is the  
offset to the text section on other platforms, (which is clever,  
because then it is the correct thing to use to relocate the addresses  
in the SLINE entries on all platforms).  But it is not an appropriate  
thing to add to the offset from the end function stab.

Note also that in the one other place where we get the real address  
from the end fun stab (dbxread.c around 1726), we do:

           /* See if this is an end of function stab.  */
           if (pst && nlist.n_type == N_FUN && *namestring == '\000')
           {
             CORE_ADDR valu;

             /* It's value is the size (in bytes) of the function for
                function relative stabs, or the address of the function's
                end for old style stabs.  */
             valu = nlist.n_value + last_function_start;
             if (TEXTHIGH (pst) == 0 || valu > TEXTHIGH (pst))
               TEXTHIGH (pst) = valu;
             break;
           }

again using last_function_start, not function_start_offset.

Jim

On Wednesday, July 10, 2002, at 08:46  PM, Daniel Jacobowitz wrote:

> On Wed, Jul 10, 2002 at 07:08:16PM -0700, Jim Ingham wrote:
>> Index: dbxread.c
>> ===================================================================
>> RCS file: /cvs/src/src/gdb/dbxread.c,v
>> retrieving revision 1.33
>> diff -c -w -r1.33 dbxread.c
>> *** dbxread.c   10 May 2002 07:32:50 -0000      1.33
>> --- dbxread.c   11 Jul 2002 01:58:29 -0000
>> ***************
>> Hi, all...
>>
>> Fred added an extra record_line call which closes off the last SLINE  
>> in
>> a function when we come across the end of function N_FUN stab.  This
>> was a good thing, but unfortunately, he used function_start_offset,
>> which on most systems is just the offset to the TEXT section (the
>> exception being Solaris, where is actually is the real function  
>> start).
>>  He really meant to use last_function_start, which is the real address
>> of the last N_FUN stab seen.
>>
>> I also fixed the comment before sline_found_in_function to accord with
>> its current usage, since the old comment is wrong.  We set
>> sline_found_in_function = 0 at the same time we set
>> last_function_start, but then we set it to 1 when we see the FIRST
>> SLINE in a function, but last_function_start is still good after that.
>> And nobody ever checks it to see if they should use  
>> last_function_start
>> or not...
>
> Well, the archeology is hardly correct.  I added both
> last_function_start and sline_found_in_function recently;
> last_function_start was because I couldn't convince myself that I could
> trust the other.  Note that in the normal N_SLINE handling, we use
> function_start_offset and not last_function_start.  So if your change
> was really correct then all the N_SLINEs for your function would be in
> the wrong places too.
>
> Could you please explain what problem you're trying to fix, and support
> it with some stabs dumps?
>
>>
>> *** 2761,2768 ****
>>     static CORE_ADDR last_function_start;
>>
>>     /* If this is nonzero, we've seen an N_SLINE since the start of  
>> the
>> current
>> !      function.  Initialized to nonzero to assure that
>> last_function_start
>> !      is never used uninitialized.  */
>>     static int sline_found_in_function = 1;
>>
>>     /* If this is nonzero, we've seen a non-gcc N_OPT symbol for this
>> source
>> --- 2761,2768 ----
>>     static CORE_ADDR last_function_start;
>>
>>     /* If this is nonzero, we've seen an N_SLINE since the start of  
>> the
>> current
>> !      function.  We use this to tell us to move the first sline to  
>> the
>> beginning
>> !      of the function regardless of what its given value is. */
>>     static int sline_found_in_function = 1;
>>
>>     /* If this is nonzero, we've seen a non-gcc N_OPT symbol for this
>> source
>> ***************
>> *** 2799,2805 ****
>>         {
>>           /* This N_FUN marks the end of a function.  This closes off
>> the
>>              current block.  */
>> !         record_line (current_subfile, 0, function_start_offset +
>> valu);
>>           within_function = 0;
>>           new = pop_context ();
>>
>> --- 2799,2805 ----
>>         {
>>           /* This N_FUN marks the end of a function.  This closes off
>> the
>>              current block.  */
>> !         record_line (current_subfile, 0, last_function_start +  
>> valu);
>>           within_function = 0;
>>           new = pop_context ();
>>
>> Jim
>> --
>> Jim Ingham                                   jingham@apple.com
>> Developer Tools - gdb
>> Apple Computer
>>
>>
>
> -- 
> Daniel Jacobowitz                           Carnegie Mellon University
> MontaVista Software                         Debian GNU/Linux Developer
>
--
Jim Ingham                                   jingham@apple.com
Developer Tools - gdb
Apple Computer



More information about the Gdb-patches mailing list