This is the mail archive of the gdb-patches@sourceware.cygnus.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]

RFD: infrun.c: No bpstat_stop_status call after proceed over break ?


I am currently trying to fix a GDB bug with missing watchpoint triggers
after proceeding over a breakpoint on x86 targets.

Here is an example, using gdb.c++/annota2:

(gdb) b main
Breakpoint 1 at 0x8048b3a: file annota2.cc, line 21.
(gdb) r
Starting program: annota2

Breakpoint 1, main () at annota2.cc:21
21        a.x = 0;
(gdb) watch a.x
Watchpoint 2: a.x
(gdb) c
Continuing.
Watchpoint 2: a.x

Old value = -536882292
New value = 1
main () at annota2.cc:23
23        a.y = 2;
(gdb)


The breakpoint at main is at the instruction which should cause the
watchpoint trigger (a.x = 0).
When continuing over the breakpoint, breakpoints are removed and the target
is single stepped with trap_expected set to one.
After the step GDB does not reexamine the stop reason, missing the watchpoint
trigger at a.x = 0 and stops too late at the second watchpoint trigger.

Here is the relevant code from handle_inferior_event:

        /* 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,
		.
		.

I currently have no idea why we need to special case the proceed over
a breakpoint here, perhaps it is some historic remnant (although I do have
this nagging feeling that I might miss something obvious).

The patch below would get rid of the special case and fix the problem, it
causes no testsuite regressions. Note that bpstat_clear is called and
stop_print_frame is set to 1 unconditionally already a few lines above the
bpstat_stop_status call, so there is no need to do it again.


Any suggestions why we should need the old special case ?


2000-03-12  Peter Schauer  <pes@regent.e-technik.tu-muenchen.de>

	* infrun.c (handle_inferior_event):  Remove special case for stop
	after proceeding over a breakpoint, it caused missed watchpoints.

*** gdb/infrun.c.orig	Thu Feb 24 13:41:46 2000
--- gdb/infrun.c	Mon Mar 13 10:11:50 2000
***************
*** 2076,2110 ****
  	    return;
  	  }
  
! 	/* 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,
! 	    /* Pass TRUE if our reason for stopping is something other
! 	       than hitting a breakpoint.  We do this by checking that
! 	       1) stepping is going on and 2) 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)
! 		 && !(step_range_end
! 		      && INNER_THAN (read_sp (), (step_sp - 16))))
! 	      );
! 	    /* Following in case break condition called a
! 	       function.  */
! 	    stop_print_frame = 1;
! 	  }
  
  	if (stop_signal == TARGET_SIGNAL_TRAP)
  	  ecs->random_signal
--- 2092,2114 ----
  	    return;
  	  }
  
! 	/* See if there is a breakpoint at the current PC.
! 	   Older versions of GDB did not call bpstat_stop_status after
! 	   proceeding over a breakpoint, causing missed watchpoints when
! 	   proceeding over a breakpoint on an instruction which triggers
! 	   a watchpoint.  */
! 	stop_bpstat = bpstat_stop_status
! 	  (&stop_pc,
! 	/* Pass TRUE if our reason for stopping is something other
! 	   than hitting a breakpoint.  We do this by checking that
! 	   1) stepping is going on and 2) 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)
! 	     && !(step_range_end
! 		  && INNER_THAN (read_sp (), (step_sp - 16))))
! 	  );
  
  	if (stop_signal == TARGET_SIGNAL_TRAP)
  	  ecs->random_signal

-- 
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]