This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB 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]

[RFA/sparc] pb doing next over struct-return function


Hello,

This is on sparc - solaris 2.8:

Consider the following code:

        with Ada.Text_IO; use Ada.Text_IO;
        
        procedure Small is
           I : Integer := 123;
        begin
           Put_Line (Integer'Image(I));  -- line 6
           I := I + 1;
        end Small;

Compile it with:

        % gnatmake -g small

And then try to to a next over line 6:

        % gdb small
        (gdb) b small.adb:6
        (gdb) run
        Starting program: /[...]/small 
        
        Breakpoint 1, small () at small.adb:6
        6          Put_Line (Integer'Image(I));
        (gdb) n
         123
        
        Program exited normally.

Ooops, the debugger doesn't stop at line 7! Here is why:

First of all, Integer'Image is a call to a function which transforms
the Integer variable I into a string. The actually name of the function
is: system__img_int__image_integer.

When GDB does the stepping, it eventually lands inside that function.
Finds out that it has stepped inside it by comparing the frame ID of
the previous frame against the step_frame_id, and therefore puts a
breakpoint at the return address and resumes the execution.

Unfortunately, the breakpoint breakpoint location chosen is not
correct, it's one instruction too early, and that causes the breakpoint
to never be hit. Hence the "Program exited normally".

The reason for the incorrect breakpoint location is that GDB
does not see that system__img_int__image_integer is a struct-return
function. So the address pointed by "saved_pc + 8" is a "unimp"
instruction, which of course is never executed unless something
is badly wrong.

Digging deeper, I found that this address is incorrectly computed
because cache->struct_return_p in sparc32_frame_cache() is not
set. And the reason for it not being set is that there is no
debugging information available for system__img_int__image_integer,
because it is part of the GNAT runtime, which is compiled without
debugging information.

So I made a small change to sparc32_frame_cache() to fallback to
a small heuristic that should help determine whether the function
is a struct-return or not based on the instruction found at
"saved_pc + 8". If it is a "unimp", then for chances are the
function won't return there, but one instruction later. And hence,
we must have a struct-return function.

This fixes the problem above, and does not introduce any regression
in the testsuite.

2004-11-22  Joel Brobecker  <brobecker@gnat.com>

        * sparc-tdep.c (is_unimp_insn): New function.
        (sparc32_frame_cache): For functions where there is no debugging
        information to help us determine whether it's a struct-return
        function or not, fallback on checking whether the instruction
        at the return address is a "unimp" instruction or not.

Tested on sparc-solaris. Ok to commit?

Thanks,
-- 
Joel

Attachment: sparc-tdep.c.diff
Description: Text document


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