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]

[patch/rfc] Simplify stepping-through sigtramp; Fix step out of handler


Hello,

The attached patch modifies infrun so that, when skipping uninteresting functions, the inferior is simply single-stepped through the signal trampolines. This replaces logic that was trying to handle:

- signaled into sigtramp (i.e., signal delivered)
Now handled by my other patch, and in the case of gnu/linux which jumps direct to the handler, useless.


- returned into sigtramp (step, next)
Which already does a single step (as the comments note unwinding through signal trampolines isn't so reliable).


A follow-on patch would be to detect a step-out-of-handler and implement that by setting a breakpoint at the signal trampoline return address.

On NetBSD/PPC, due to a kernel bug (gdb/1639), sees stepi into the trampoline fixed but step still broken.

On GNU/Linux i386 step out of handler now works.

Baring comment I'll commit in a day or so,
Andrew
2004-05-08  Andrew Cagney  <cagney@redhat.com>

	* infrun.c (handle_inferior_event): Simplify code handling
	step-into or return-from a signal trampoline.

Index: testsuite/ChangeLog
2004-05-08  Andrew Cagney  <cagney@redhat.com>

	* gdb.base/sigstep.exp (advancei): Update KFAILs.  gdb/1613 is
	fixed but revealed gdb/1639.

Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.152
diff -p -u -r1.152 infrun.c
--- infrun.c	8 May 2004 22:26:09 -0000	1.152
+++ infrun.c	9 May 2004 18:48:56 -0000
@@ -2477,75 +2477,16 @@ process_event_stop_test:
      But we can update it every time we leave the step range.  */
   ecs->update_step_sp = 1;
 
-  /* Did we just step into a singal trampoline (either by stepping out
-     of a handler, or by taking a signal)?  */
-  if (get_frame_type (get_current_frame ()) == SIGTRAMP_FRAME
-      && !frame_id_eq (get_frame_id (get_current_frame ()), step_frame_id))
+  if (step_range_end != 1
+      && (step_over_calls == STEP_OVER_UNDEBUGGABLE
+	  || step_over_calls == STEP_OVER_ALL)
+      && get_frame_type (get_current_frame ()) == SIGTRAMP_FRAME)
     {
-      {
-	struct frame_id current_frame = get_frame_id (get_current_frame ());
-
-	if (frame_id_inner (current_frame, step_frame_id))
-	  {
-	    /* We have just taken a signal; go until we are back to
-	       the point where we took it and one more.  */
-
-	    /* This code is needed at least in the following case:
-	       The user types "next" and then a signal arrives (before
-	       the "next" is done).  */
-
-	    /* Note that if we are stopped at a breakpoint, then we need
-	       the step_resume breakpoint to override any breakpoints at
-	       the same location, so that we will still step over the
-	       breakpoint even though the signal happened.  */
-	    struct symtab_and_line sr_sal;
-
-	    init_sal (&sr_sal);
-	    sr_sal.symtab = NULL;
-	    sr_sal.line = 0;
-	    sr_sal.pc = prev_pc;
-	    /* We could probably be setting the frame to
-	       step_frame_id; I don't think anyone thought to try it.  */
-	    check_for_old_step_resume_breakpoint ();
-	    step_resume_breakpoint =
-	      set_momentary_breakpoint (sr_sal, null_frame_id, bp_step_resume);
-	    if (breakpoints_inserted)
-	      insert_breakpoints ();
-	  }
-	else
-	  {
-	    /* We just stepped out of a signal handler and into
-	       its calling trampoline.
-
-	       Normally, we'd call step_over_function from
-	       here, but for some reason GDB can't unwind the
-	       stack correctly to find the real PC for the point
-	       user code where the signal trampoline will return
-	       -- FRAME_SAVED_PC fails, at least on HP-UX 10.20.
-	       But signal trampolines are pretty small stubs of
-	       code, anyway, so it's OK instead to just
-	       single-step out.  Note: assuming such trampolines
-	       don't exhibit recursion on any platform... */
-	    find_pc_partial_function (stop_pc, &ecs->stop_func_name,
-				      &ecs->stop_func_start,
-				      &ecs->stop_func_end);
-	    /* Readjust stepping range */
-	    step_range_start = ecs->stop_func_start;
-	    step_range_end = ecs->stop_func_end;
-	    ecs->stepping_through_sigtramp = 1;
-	  }
-      }
-
-
-      /* If this is stepi or nexti, make sure that the stepping range
-         gets us past that instruction.  */
-      if (step_range_end == 1)
-	/* FIXME: Does this run afoul of the code below which, if
-	   we step into the middle of a line, resets the stepping
-	   range?  */
-	step_range_end = (step_range_start = prev_pc) + 1;
-
-      ecs->remove_breakpoints_on_following_step = 1;
+      /* The inferior, while doing a "step" or "next", has ended up in
+	 a signal trampoline (either by a signal being delivered or by
+	 the signal handler returning).  Just single-step until the
+	 inferior leaves the trampoline (either by calling the handler
+	 or returning).  */
       keep_going (ecs);
       return;
     }
Index: testsuite/gdb.base/sigstep.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.base/sigstep.exp,v
retrieving revision 1.2
diff -p -u -r1.2 sigstep.exp
--- testsuite/gdb.base/sigstep.exp	23 Apr 2004 16:44:25 -0000	1.2
+++ testsuite/gdb.base/sigstep.exp	9 May 2004 18:49:00 -0000
@@ -87,7 +87,8 @@ proc advance { i } {
 	    exp_continue
 	}
 	-re "Program exited normally.*${gdb_prompt} $" {
-	    kfail gdb/1613 "$test (program exited)"
+	    setup_kfail powerpc-*-*bsd* gdb/1639
+	    fail "$test (program exited)"
 	}
 	-re "(while ..done|return 0).*${gdb_prompt} $" {
 	    # After stepping out of a function /r signal-handler, GDB will
@@ -122,13 +123,13 @@ proc advancei { i } {
 	-re "signal handler called.*${gdb_prompt} $" {
 	    pass "$test"
 	}
-	-re "Program exited normally.*${gdb_prompt} $" {
-	    kfail gdb/1613 "$test (program exited)"
-	    set program_exited 1
-	}
 	-re "main .*${gdb_prompt} $" {
 	    fail "$test (in main)"
 	}
+	-re "Program exited normally.*${gdb_prompt} $" {
+	    fail "$test (program exited)"
+	    set program_exited 1
+	}
 	-re "Make handler return now.*y or n. $" {
 	    send_gdb "y\n"
 	    exp_continue
@@ -151,12 +152,16 @@ proc advancei { i } {
 	    send_gdb "y\n"
 	    exp_continue
 	}
+	-re "Program exited normally.*${gdb_prompt} $" {
+	    kfail gdb/1639 "$test (program exited)"
+	    set program_exited 1
+	}
 	-re "The program is not being run.*${gdb_prompt} $" {
 	    if { $program_exited } {
 		# Previously kfailed with an exit
-		pass "$test (The program is not being run)"
+		pass "$test (the program is not being run)"
 	    } else {
-		fail "$test"
+		fail "$test (the program is not being run)"
 	    }
 	}
     }

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