This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
Re: Problem with "next" in main on sparc
- To: Jim Kingdon <kingdon at redhat dot com>
- Subject: Re: Problem with "next" in main on sparc
- From: Jason Molenda <crash at cygnus dot com>
- Date: Mon, 1 Nov 1999 12:03:58 -0800
- Cc: gdb-patches at sourceware dot cygnus dot com
- References: <199911011938.OAA32716@devserv.devel.redhat.com>
On Mon, Nov 01, 1999 at 02:38:31PM -0500, Jim Kingdon wrote:
>
> 1998-09-08 Jason Molenda (jsm@bugshack.cygnus.com)
>
> * breakpoint.c (bpstat_stop_status): Declare a bp match if the
> current fp matches the bp->fp OR if the current fp is less than
> the bp->fp if we're looking at a bp_step_resume breakpoint.
Ack, ill considered changes come back to haunt me. :-) Let me look
this over later today so I can figure out if I'm a dork or not before
I comment in depth. I'm fully prepared to admit a mistake, but I want
to look it over a little more closely to figure out what I was doing.
FWIW here in my original summary of the problem:
When you do a 'step' on the last line in a function, the program runs
without stopping. This is because Purify inserts calls to the Purify
code right in the program epilogue. GDB detects these calls out to code
with no line numbers, sets a step_resume_breakpoint on the instruction
following the branch insn, and runs the inferior until it hits the
breakpoint.
The problem is where the FP has already been rolled back--we're right at
the very end of the epilogue and we make one more call to the Purify code.
When the breakpoint set after the branch is hit, bpstat_stop_status sees
that there is a breakpoint at $pc, but bpstat_stop_status() checks the
FP in the breakpoint (b->frame) against the current FP.
The FP in the breakpoint is the correct one for our function, but the
current FP has been rolled back to the caller function already--they do
not match. w_f_i does not remove the gdb_step_resume breakpoint and does
another PT_CONTINUE via ptrace() because it thinks it still has to hit
the breakpoint. The program continues until it exits.
Why did the frame address get set incorrectly in the breakpoint? We set
the step_resume_breakpoint _after_ we find outself in the no-line-number
code (see the code around "/* A subroutine call has happened. */"
in w_f_i()). set_momentary_breakpoint() sets up the breakpoint for us
at the SAVED_PC_AFTER_CALL address and we set the 'frame' member of the
breakpoint to be step_frame_address.
And here is the cvs log message I added when I checked this in:
With a bp_step_resume type breakpoint, the frame pointer check exists in
case we recurse and execute the same text section--we want to not stop
there because it would confuse the user. So gdb checks to see that the
frame pointer matches the one recorded in the breakpoint.
If the current frame pointer is less than the frame pointer recorded in
the breakpoint, then something odd is happened and we should declare that
we're at the breakpoint so that we clear it out.
This happens in Purify instrumented executables on PA systems, at least.
They insert some calls out to Purify code in the function epilogue and
it confuses GDB (which assumes that the frame pointer does not move
around through the entire execution of a function).
Jason