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]

[rfc] sigstep additions


Hello,

This adds more step tests to sigstep.exp. They pass on a ``fixed'' PPC kernel but the breakpoint tests fail on a ``fixed'' i386 kernel.

Can people please test this on their various systems.

Andrew
2004-08-10  Andrew Cagney  <cagney@gnu.org>

	* gdb.base/sigstep.exp (breakpoint_to_handler)
	(skip_over_handler, skip_to_handler): New test procedures.
	(advance, advancei): Add a proper prefix, do not use
	rerun_to_main.
	* gdb.base/sigstep.c (main): Change to use an infinite loop.

Index: testsuite/gdb.base/sigstep.c
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/sigstep.c,v
retrieving revision 1.2
diff -p -u -r1.2 sigstep.c
--- testsuite/gdb.base/sigstep.c	5 Aug 2004 07:28:20 -0000	1.2
+++ testsuite/gdb.base/sigstep.c	11 Aug 2004 00:12:07 -0000
@@ -31,27 +31,38 @@ handler (int sig)
   done = 1;
 } /* handler */
 
+struct itimerval itime;
+struct sigaction action;
+
+/* The enum is so that GDB can easily see these macro values.  */
+enum {
+  itimer_real = ITIMER_REAL,
+  itimer_virtual = ITIMER_VIRTUAL
+} itimer = ITIMER_VIRTUAL;
+
 main ()
 {
+
   /* Set up the signal handler.  */
-  {
-    struct sigaction action;
-    memset (&action, 0, sizeof (action));
-    action.sa_handler = handler;
-    sigaction (SIGVTALRM, &action, NULL);
-  }
+  memset (&action, 0, sizeof (action));
+  action.sa_handler = handler;
+  sigaction (SIGVTALRM, &action, NULL);
+  sigaction (SIGALRM, &action, NULL);
 
-  /* Set up a one-off timer.  A timer, rather than SIGSEGV, is used as
-     after a timer handler finishes the interrupted code can safely
-     resume.  */
-  {
-    struct itimerval itime;
-    memset (&itime, 0, sizeof (itime));
-    itime.it_value.tv_usec = 250 * 1000;
-    setitimer (ITIMER_VIRTUAL, &itime, NULL);
-  }
+  /* The values needed for the itimer.  This needs to be at least long
+     enough for the setitimer() call to return.  */
+  memset (&itime, 0, sizeof (itime));
+  itime.it_value.tv_usec = 250 * 1000;
 
-  /* Wait.  */
-  while (!done);
-  return 0;
-} /* main */
+  /* Loop for ever, constantly taking an interrupt.  */
+  while (1)
+    {
+      /* Set up a one-off timer.  A timer, rather than SIGSEGV, is
+	 used as after a timer handler finishes the interrupted code
+	 can safely resume.  */
+      setitimer (itimer, &itime, NULL);
+      /* Wait.  */
+      while (!done);
+      done = 0;
+    }
+}
Index: testsuite/gdb.base/sigstep.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/sigstep.exp,v
retrieving revision 1.4
diff -p -u -r1.4 sigstep.exp
--- testsuite/gdb.base/sigstep.exp	9 Aug 2004 13:16:16 -0000	1.4
+++ testsuite/gdb.base/sigstep.exp	11 Aug 2004 00:12:07 -0000
@@ -16,10 +16,11 @@
 
 
 # The program sigstep.c creates a very simple backtrace containing one
-# signal handler and signal trampoline.
+# signal handler and signal trampoline.  A flag is set and then the
+# handler returns.  This is repeated at infinitum.
 
 # This test runs the program up to the signal handler, and then
-# attempts to step/next the inferior back to main.
+# attempts to step/next out of the handler and back into main.
 
 if [target_info exists gdb,nosignals] {
     verbose "Skipping sigstep.exp because of nosignals."
@@ -71,12 +72,12 @@ gdb_expect_list "backtrace for nexti" ".
 
 proc advance { i } {
     global gdb_prompt
+    set prefix "$i from handler"
 
     # Get us back into the handler
-    rerun_to_main
-    gdb_test "continue" ".* handler .*" "continue to handler for $i"
+    gdb_test "continue" ".* handler .*" "$prefix; continue to handler"
 
-    set test "$i out of handler"
+    set test "$prefix; leave handler"
     gdb_test_multiple "$i" "${test}" {
 	-re "done = 1;.*${gdb_prompt} $" {
 	    send_gdb "$i\n"
@@ -90,7 +91,7 @@ proc advance { i } {
 	    setup_kfail powerpc-*-*bsd* gdb/1639
 	    fail "$test (program exited)"
 	}
-	-re "(while ..done|return 0).*${gdb_prompt} $" {
+	-re "(while ..done|done = 0).*${gdb_prompt} $" {
 	    # After stepping out of a function /r signal-handler, GDB will
 	    # advance the inferior until it is at the first instruction of
 	    # a code-line.  While typically things return to the middle of
@@ -104,13 +105,13 @@ proc advance { i } {
 
 proc advancei { i } {
     global gdb_prompt
+    set prefix "$i from handleri"
     set program_exited 0
 
     # Get us back into the handler
-    rerun_to_main
-    gdb_test "continue" ".* handler .*" "continue to handler for $i"
+    gdb_test "continue" ".* handler .*" "$prefix; continue to handler"
 
-    set test "$i into signal trampoline"
+    set test "$prefix; leave handler"
     gdb_test_multiple "$i" "${test}" {
         -re "Cannot insert breakpoint 0.*${gdb_prompt} $" {
             # Some platforms use a special read-only page for signal
@@ -144,7 +145,7 @@ proc advancei { i } {
 	}
     }
 
-    set test "$i out of signal trampoline"
+    set test "$prefix; leave signal trampoline"
     gdb_test_multiple "$i" "${test}" {
 	-re "while .*${gdb_prompt} $" {
 	    pass "$test (in main)"
@@ -175,6 +176,8 @@ proc advancei { i } {
     }
 }
 
+# Check that we can step/next our way out of a signal handler.
+
 advance step
 advancei stepi
 
@@ -183,3 +186,114 @@ advancei nexti
 
 advancei finish
 advancei return
+gdb_test "set done = 1" "" "Set done as return will have skipped it"
+
+
+# Check that we can step/next our way into a signal handler.
+
+# Use the real-time itimer, as otherwize the process never gets enough
+# time to expire the timer.
+
+delete_breakpoints
+set infinite_loop [gdb_get_line_number {while (!done)}]
+gdb_test "set itimer = itimer_real"
+gdb_test "break [gdb_get_line_number {done = 0}]"
+
+
+# Try single-stepping when there's a signal pending, a breakpoint at
+# the current instruction and a breakpoint in the handler.
+
+proc skip_to_handler { i } {
+    global gdb_prompt
+    global infinite_loop
+    set prefix "$i to handler"
+    
+    # Run around to the done
+    set test "$prefix; resync"
+    gdb_test_multiple "continue" "$test" {
+	-re "done = 0.*$gdb_prompt " {
+	    pass "$test"
+	}
+	# other patterns can go here
+    }
+    
+    # Advance to the infinite loop
+    gdb_test "advance $infinite_loop" "" "$prefix; advance to infinite loop"
+
+    # Make the signal pending
+    sleep 1
+    
+    gdb_test "break handler" "" "$prefix; break handler"
+    gdb_test "$i" " handler .*" "$prefix; performing $i"
+    gdb_test "clear handler" "" "$prefix; clear handler"
+}
+
+skip_to_handler step
+skip_to_handler next
+skip_to_handler continue
+
+
+# Try single-stepping et.al. when the handler is a no-op.
+
+proc skip_over_handler { i } {
+    global gdb_prompt
+    global infinite_loop
+    set prefix "$i over handler"
+    
+    # Run around to the done
+    set test "$prefix; resync"
+    gdb_test_multiple "continue" "$test" {
+	-re "done = 0.*$gdb_prompt " {
+	    pass "$test"
+	}
+	# other patterns can go here
+    }
+    
+    # Advance to the infinite loop
+    gdb_test "advance $infinite_loop" "" "$prefix; advance to infinite loop"
+
+    # Make the signal pending
+    sleep 1
+    
+    gdb_test "$i" "done = 0.*" "$prefix; performing $i"
+}
+
+skip_over_handler step
+skip_over_handler next
+skip_over_handler continue
+
+
+# Try single instruction stepping when there's a signal pending and a
+# breakpoint in the handler.
+
+proc breakpoint_to_handler { i } {
+    global gdb_prompt
+    global infinite_loop
+    set prefix "$i breakpoint to handler"
+    
+    # Run around to the done
+    set test "$prefix; resync"
+    gdb_test_multiple "continue" "$test" {
+	-re "done = 0.*$gdb_prompt " {
+	    pass "$test"
+	}
+	# other patterns can go here
+    }
+    
+    gdb_test "break $infinite_loop" "" "$prefix; break infinite loop"
+    gdb_test "break handler" "" "$prefix; break handler"
+
+    # Continue to the infinite loop
+    gdb_test "continue" "while ..done.*" "$prefix; continue to infinite loop"
+
+    # Make the signal pending
+    sleep 1
+    
+    gdb_test "$i" " handler .*" "$prefix; performing $i"
+    gdb_test "clear $infinite_loop" "" "$prefix; clear infinite loop"
+    gdb_test "clear handler" "" "$prefix; clear handler"
+}
+
+breakpoint_to_handler step
+breakpoint_to_handler next
+breakpoint_to_handler continue

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