public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* On Digital UNIX, "continue" doesn't continue correctly if a signal isdelivered
@ 2000-05-23 21:22 Guy Harris
  0 siblings, 0 replies; only message in thread
From: Guy Harris @ 2000-05-23 21:22 UTC (permalink / raw)
  To: gdb

On Digital UNIX/Alpha, we have a program that has an interval timer set
up to continuously deliver signals; with GDB 4.18, we find that if you
stop at a breakpoint, and then try to continue from that breakpoint, it
doesn't continue - instead, it stops again at the same breakpoint.

The same thing happens with the GDB that was in the CVS tree as of a
short while ago.

The problem appears to be that various tests in "wait_for_inferior()",
which test whether the current SP is for a frame closer to the top of
the stack than the frame for "step_sp" (or "step_sp - 16") fail, because
"step_sp" hasn't been set.  When continuing from the breakpoint (with
the PRSTEP flag set in the "pr_flags" field of the structure passed to
PIOCRUN, so that it executes only one instruction), it stops in
"__sigtramp", as a SIGALRM was delivered to the process in the interval
since the breakpoint trap; however, GDB doesn't realize that it's in the
signal trampoline, and doesn't properly continue, so that when it next
gets a breakpoint trap after returning from the signal, as it presumably
re-executes the breakpoint instruction, it doesn't realize that it
should drive on, and it just stops.

"step_sp" gets set by "step_1()", "step_once()", and
"until_next_command()", presumably because all those routines call
"proceed()" with "step" set; however, "step_sp" isn't set by
"continue_command()" or any routine between "continue_command()" and
"proceed()", presumably because "proceed()" isn't called with "step" set
in that code path.

However, "proceed()" will be single-stepping, because we're resuming
from a breakpoint, and we need to step over the instruction at which the
breakpoint was placed and then put the breakpoint back, as per:

  if (addr == (CORE_ADDR) -1)
    {
      /* If there is a breakpoint at the address we will resume at,
	 step one instruction before inserting breakpoints
	 so that we do not stop right away (and report a second
	 hit at this breakpoint).  */
 
      if (read_pc () == stop_pc && breakpoint_here_p (read_pc ()))
	oneproc = 1;

in "proceed()".

Making "proceed()" set "step_frame_address" and "step_sp" if "oneproc"
is set but "step" isn't set appears to fix the problem:

Index: gdb/infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.14
diff -c -r1.14 gdb/infrun.c
*** gdb/infrun.c	2000/05/22 09:02:23	1.14
--- gdb/infrun.c	2000/05/24 03:44:38
***************
*** 1040,1048 ****
  #endif /* HP_OS_BUG */
  
    if (oneproc)
!     /* We will get a trace trap after one instruction.
!        Continue it automatically and insert breakpoints then.  */
!     trap_expected = 1;
    else
      {
        int temp = insert_breakpoints ();
--- 1040,1058 ----
  #endif /* HP_OS_BUG */
  
    if (oneproc)
!     {
!       /* We will get a trace trap after one instruction.
! 	 Continue it automatically and insert breakpoints then.  */
!       trap_expected = 1;
! 
!       /* Oh, and if we weren't explicitly told to single-step, our
!          caller may not have updated "step_sp", so do it ourselves. */
!       if (!step)
! 	{
! 	  step_frame_address = FRAME_FP (get_current_frame ());
! 	  step_sp = read_sp ();
! 	}
!     }
    else
      {
        int temp = insert_breakpoints ();

Whether this is the right way to fix this is another matter.  (For
example, perhaps "proceed()" should always set "step_frame_address" and
"step_sp" if it will be passing a non-zero value as the first argument
to "resume()", and the routines in "gdb/infcmd.c" that set them should
leave it up to "proceed()" to do so.)

I've attached a small sample program which exhibits the problem; if run
with "clock" as an argument, it sets up a timer to repeatedly deliver
SIGALRM, and if you set a breakpoint on "procedure()", run the program,
and then type "continue", it will stop again in "procedure()" without
printing "Hello", indicating that it hasn't continued from the
breakpoint.

However, if run with "noclock" as an argument, so that it doesn't
repeatedly get SIGALRM, it *will* print "Hello" before stopping again at
"procedure()".

Applying the patch above makes "continue" behave correctly regardless of
whether the program was run with "clock" or "noclock".

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2000-05-23 21:22 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-05-23 21:22 On Digital UNIX, "continue" doesn't continue correctly if a signal isdelivered Guy Harris

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).