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]

Re: [RFC] if (INNER_THAN (read_sp(), step_sp - 16))


Hellooooooo.

This ugly hack is coming back to haunt me every other year, and if I'd
know about a cleaner way to solve this, I'd already have done it long ago.

You already asked me about this `gem' in August 1999 and I tried to explain
the issue back then (see appended message below).
As of CVS GDB from May 27 2001 this hack is still needed for
Solaris x86 and Linux x86 (at least for a debian 2.2r2 release, for which
I have just run the signals.exp test with and without the hack).

Kevin Buettner also tried to come up with a better solution to no avail
(see second message below).

I think we have two options here:

- Back out the change unconditionally as Andrew suggested and live with
  the signals.exp regressions this will cause.

- Try to refine the test, so that the `serious bugs in debugging native
  Linux x86' are not triggered.
  Which problems are you encountering due to the hack ?

Or perhaps you are able to find a cleaner solution, which would be most
welcome.

Here are the old messages explaining the issue:

: Subject: Re: GDB: an old change in infrun.c
: To: msnyder@cygnus.com (Michael Snyder)
: Date: Sat, 28 Aug 99 15:00:48 MET DST
: Cc: kevinb@cygnus.com
: In-Reply-To: <37BDF4C2.3BD6@cygnus.com>; from "Michael Snyder" at Aug 20, 99 5:37 pm
: 
: Sorry for the late reply, I have been on vacation.
: 
: We didn't meet, but we had some GDB mail exchange in the past (it's also
: interesting to see kevinb work at Cygnus now).
: 
: Unfortunately I am no longer doing much work on GDB nowadays (hopefully
: I will be able to contribute again next year), below is what I found in
: my logs when handling the problem back then.
: 
: I don't know if the problem is still happening with the current GDB source
: (I don't even know if signals.exp is still the same).
: Back then I also added the following comment to signals.exp, which might
: contain some more information as well:
: 
:               # SVR4 and Linux based i*86 systems exhibit this behaviour
:               # as well (it is uncovered by the `continue from a break
:               # in a signal handler' test below).
:               # As these systems use procfs, where we tell the kernel not
:               # to tell gdb about `pass' signals, and the trace flag is
:               # cleared by the kernel before entering the sigtramp
:               # routine, GDB will not notice the execution of the signal
:               # handler.
:               # Upon return from the signal handler, GDB will receive
:               # a SIGTRAP from the set trace flag in the restored context.
:               # The SIGTRAP marks the end of a (albeit long winded)
:               # single step for GDB, causing this test to pass.
: 
: Executing signals.exp on Linux x86 with and without my change might be
: sufficient to verify if the hack is still needed.
: 
: 
: Here are my original notes:
: 
: The problem (observed under Solaris x86, SVR4 x86 and Linux):
: 
: If the inferior has a pending signal and a single step is issued, the
: kernel saves the process context on the stack and forces execution
: of the users signal handler with a cleared Trace bit.
: 
: 
: The testcase:
: 
: gdb.base/signals.exp when we next over a statement with a pending
: alarm signal and a breakpoint in the alarm signal handler.
: 
: 
: The symptom (before my infrun.c change):
: 
: After the `next' is issued, execution continues without an intervening
: stop in sigtramp (due to the cleared trace bit) until the breakpoint
: in the handler is reached. As DECR_PC_AFTER_BREAK is 1 for the affected
: targets, GDB thinks that it just executed a jump to the handler
: code, and does not recognize that a breakpoint was hit. As the breakpoint
: is not recognized, GDB does not adjust the PC for the breakpoint (as it
: normally would), continues stepping with a wrong PC, and all hell breaks
: loose.
: 
: 
: The (admittedly kludgy) solution:
: 
: Detect that we entered a signal handler handler frame, which usually
: pushes the context on the stack and therefor moves the stack pointer
: to a value which is discernible from a normal function call sequence.
: 
: 
: Please let me know if you have any further questions on the issue,
: 
: > Hi Peter, 
: > 
: > I don't think we've met -- I'm Michael Snyder, and I work 
: > on the GDB team at Cygnus.
: > 
: > I have a question about a change that you made last year.
: > I'm trying to understand the code that calls
: > bpstat_stop_status, and under what circumstances it decides
: > to stop and/or to report a breakpoint.
: > 
: > The change I'm referring to was covered by this ChangeLog:
: > Fri Apr 10 22:36:28 1998  Peter Schauer 
: >         * infrun.c (wait_for_inferior):  Handle breakpoint hit in
: >         signal handler without intervening stop in sigtramp.
: > 
: > and looks about like this:
: >         /* Don't even think about breakpoints
: >            if just proceeded over a breakpoint.
: > 
: >            However, if we are trying to proceed over a breakpoint
: >            and end up in sigtramp, then through_sigtramp_breakpoint
: >            will be set and we should check whether we've hit the
: >            step breakpoint.  */
: >         if (stop_signal == TARGET_SIGNAL_TRAP && trap_expected
: >             && through_sigtramp_breakpoint == NULL)
: >           bpstat_clear (&stop_bpstat);
: >         else
: >           {
: >             /* See if there is a breakpoint at the current PC.  */
: >             stop_bpstat = bpstat_stop_status
: >               (&stop_pc,
: >                (DECR_PC_AFTER_BREAK ?
: >             /* Notice the case of stepping through a jump
: >                that lands just after a breakpoint.
: >                Don't confuse that with hitting the breakpoint.
: >                What we check for is that 1) stepping is going on
: >                and 2) the pc before the last insn does not match
: >                the address of the breakpoint before the current pc
: >                and 3) we didn't hit a breakpoint in a signal handler
: >                without an intervening stop in sigtramp, which is
: >                detected by a new stack pointer value below
: >                any usual function calling stack adjustments.  */
: >                 (currently_stepping (ecs)
: >                  && prev_pc != stop_pc - DECR_PC_AFTER_BREAK
: > +                 && !(step_range_end
: > +                      && INNER_THAN (read_sp (), (step_sp - 16)))) :
: >                 0)
: >               );
: >             /* Following in case break condition called a
: >                function.  */
: >             stop_print_frame = 1;
: >           }
: > 
: > Can you tell me what you were trying to accomplish
: > (eg. make it stop, make it keep going, make it print or
: > not print a breakpoint message), and under what 
: > circumstances?
: > 
: > 				Thanks,
: > 				Michael
:
:
: 
: Date: Fri, 17 Sep 1999 14:26:01 -0700
: From: Kevin Buettner <kevinb@cygnus.com>
: To: "Peter.Schauer" <Peter.Schauer@REGENT.E-TECHNIK.TU-MUENCHEN.DE>,
:         kevinb@cygnus.com (Kevin Buettner)
: Subject: Re: RFA: breakpoint.c and infrun.c changes
: 
: On Sep 17,  9:59pm, Peter.Schauer wrote:
: 
: > I did CC you on a reply I sent to msnyder on this issue a few weeks ago,
: > I append it below, in case the message got lost.
: 
: I did indeed receive your reply.  I am sorry for not acknowledging it.
: 
: > :               # SVR4 and Linux based i*86 systems exhibit this behaviour
: > :               # as well (it is uncovered by the `continue from a break
: > :               # in a signal handler' test below).
: > :               # As these systems use procfs, where we tell the kernel not
: > :               # to tell gdb about `pass' signals, and the trace flag is
: > :               # cleared by the kernel before entering the sigtramp
: > :               # routine, GDB will not notice the execution of the signal
: > :               # handler.
: > :               # Upon return from the signal handler, GDB will receive
: > :               # a SIGTRAP from the set trace flag in the restored context.
: > :               # The SIGTRAP marks the end of a (albeit long winded)
: > :               # single step for GDB, causing this test to pass.
: > : 
: > : Executing signals.exp on Linux x86 with and without my change might be
: > : sufficient to verify if the hack is still needed.
: 
: I have done this and (unfortunately) your hack is still needed.  I still
: think there's got to be a better way to do things, but unfortunately
: I don't (yet) know what it is.
: 
: Thanks for your help.
: 
: Kevin

> Hellooooooo, Peter Schauer!
> 
> Back in April of 1998 a patch from you was checked in (you may have
> submitted it some time earlier) for x86 Solaris.  Among other things,
> it contained a test in infrun.c (wait_for_inferior) that looked like:
> 
> 	[stuff...]
> 	(CURRENTLY_STEPPING ()
> 	&& prev_pc != stop_pc - DECR_PC_AFTER_BREAK
> 	&& !(step_range_end
> 	    && read_sp () INNER_THAN (step_sp - 16)));
> 
> A comment explains that the INNER_THAN expression is meant to detect
> hitting a breakpoint in a signal handler without an intervening stop
> in sigtramp.
> 
> The lines have metamorphosed since then, but the expression with
> (step_sp - 16) is still in there, and I would really like to get
> rid of it.  Especially since I have now found that it can cause
> serious bugs in debugging native Linux x86.
> 
> But I have no idea how to detect the situation that you are 
> trying to test for.  So I'd like to toss it back to you.
> Can you find a better way to test for this?  Maybe with 
> (ugh) another state variable?
> 
> And if not, can you put those two lines into an ifdef, 
> so they won't affect targets for which they're not intended?
> 
> 			Thanks a lot, 
> 			Michael

--
Peter Schauer			pes@regent.e-technik.tu-muenchen.de


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