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

Re: 3/5 - Rework stepping over longjmp support


A Friday 02 May 2008 15:38:22, Daniel Jacobowitz wrote:
> On Fri, Apr 25, 2008 at 05:15:45PM +0100, Pedro Alves wrote:
> > Still OK?  I'll check the new longjmp.exp test in along with this one.
>
> Looks fine to me.

Thanks.  I've checked this one in, and the test too.

Non-stop mode should be now safer regarding longjmp.

-- 
Pedro Alves
2008-05-04  Pedro Alves  <pedro@codesourcery.com>

	gdb/

	* breakpoint.c (update_breakpoints_after_exec): Delete bp_longjmp
	and bp_longjmp_resume breakpoints.
	(breakpoint_address_is_meaningful): Claim bp_longjmp_resume as
	meaningful.
	(create_longjmp_breakpoint): Don't create bp_longjmp_resume
	breakpoints.  Create bp_longjmp breakpoints as momentary
	breakpoints.
	(enable_longjmp_breakpoint): Delete.
	(set_longjmp_breakpoint): New.
	(disable_longjmp_breakpoint): Delete.
	(delete_longjmp_breakpoint): New.
	(set_longjmp_resume_breakpoint): Delete.
	(set_momentary_breakpoint_at_pc): New.
	(breakpoint_re_set_one): Don't delete bp_longjmp and
	bp_longjmp_resume breakpoints.
	(breakpoint_re_set): Don't create longjmp and longjmp-resume
	breakpoints.

	* infrun.c (step_resume_breakpoint): Add comment.
	(struct execution_control_state): Delete handling_longjmp member.
	(init_execution_control_state). Don't clear handling_longjmp.
	(context_switch): Don't context switch handling_longjmp.
	(handle_inferior_event): If handling a bp_longjmp breakpoint,
	create a bp_longjmp_resume breakpoint, and set it as current
	step_resume_breakpoint, then step over the longjmp breakpoint.  If
	handling a bp_longjmp_resume breakpoint, don't delete the longjmp
	breakpoint, delete the longjmp-resume breakpoint, and stop
	stepping.
	(currently_stepping): Remove handling_longjmp from expression.
	(insert_step_resume_breakpoint_at_sal): Update comment.
	(insert_longjmp_resume_breakpoint): New.

	* breakpoint.h (set_momentary_breakpoint_at_pc): Declare.
	(enable_longjmp_breakpoint, disable_longjmp_breakpoint): Delete
	declarations.
	(set_longjmp_breakpoint, delete_longjmp_breakpoint): Declare.
	(set_longjmp_resume_breakpoint): Delete declaration.

	* gdbthread.h (save_infrun_state): Remove handling_longjmp parameter.
	(load_infrun_state): Delete *handling_longjmp parameter.
	* thread.c (save_infrun_state): Remove handling_longjmp parameter.  Update body.
	(load_infrun_state): Delete *handling_longjmp parameter.  Update body.

	* infcmd.c Include "gdbthread.h".
	(disable_longjmp_breakpoint_cleanup): Delete.
	(delete_longjmp_breakpoint_cleanup): New.
	(step_1): Call set_longjmp_breakpoint instead of
	enable_longjmp_breakpoint.  Use delete_longjmp_breakpoint_cleanup
	instead of disable_longjmp_breakpoint_cleanup when making cleanup.
	(step_1_continuation): Pass thread id in the continuation args to
	step_once.
	(step_once): Add thread parameter.  Pass thread id the the
	continuation.

	* Makefile.in (infcmd.o): Update.

	gdb/testsuite:
	* gdb.cp/annota2.exp: Adjust to breakpoints invalidations at
	different times.

---
 gdb/breakpoint.c                 |  112 ++++++++++++++-------------------------
 gdb/breakpoint.h                 |    9 ++-
 gdb/gdbthread.h                  |    3 -
 gdb/infcmd.c                     |   41 ++++++++++----
 gdb/infrun.c                     |   86 ++++++++++++++++++++---------
 gdb/testsuite/gdb.cp/annota2.exp |    4 -
 gdb/thread.c                     |    4 -
 7 files changed, 141 insertions(+), 118 deletions(-)

Index: src/gdb/breakpoint.c
===================================================================
--- src.orig/gdb/breakpoint.c	2008-05-04 20:15:42.000000000 +0100
+++ src/gdb/breakpoint.c	2008-05-04 20:20:14.000000000 +0100
@@ -145,8 +145,6 @@ static int watchpoint_check (void *);
 
 static void maintenance_info_breakpoints (char *, int);
 
-static void create_longjmp_breakpoint (char *);
-
 static void create_overlay_event_breakpoint (char *);
 
 static int hw_breakpoint_used_count (void);
@@ -1486,6 +1484,14 @@ update_breakpoints_after_exec (void)
 	continue;
       }
 
+    /* Longjmp and longjmp-resume breakpoints are also meaningless
+       after an exec.  */
+    if (b->type == bp_longjmp || b->type == bp_longjmp_resume)
+      {
+	delete_breakpoint (b);
+	continue;
+      }
+
     /* Don't delete an exec catchpoint, because else the inferior
        won't stop when it ought!
 
@@ -4081,7 +4087,6 @@ set_default_breakpoint (int valid, CORE_
       bp_read_watchpoint
       bp_access_watchpoint
       bp_catch_exec
-      bp_longjmp_resume
       bp_catch_fork
       bp_catch_vork */
 
@@ -4095,7 +4100,6 @@ breakpoint_address_is_meaningful (struct
 	  && type != bp_read_watchpoint
 	  && type != bp_access_watchpoint
 	  && type != bp_catch_exec
-	  && type != bp_longjmp_resume
 	  && type != bp_catch_fork
 	  && type != bp_catch_vfork);
 }
@@ -4453,20 +4457,9 @@ create_longjmp_breakpoint (char *func_na
   struct breakpoint *b;
   struct minimal_symbol *m;
 
-  if (func_name == NULL)
-    b = create_internal_breakpoint (0, bp_longjmp_resume);
-  else
-    {
-      if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL)
-	return;
- 
-      b = create_internal_breakpoint (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
-    }
-
-  b->enable_state = bp_disabled;
-  b->silent = 1;
-  if (func_name)
-    b->addr_string = xstrdup (func_name);
+  if ((m = lookup_minimal_symbol_text (func_name, NULL)) == NULL)
+    return;
+  set_momentary_breakpoint_at_pc (SYMBOL_VALUE_ADDRESS (m), bp_longjmp);
   update_global_location_list ();
 }
 
@@ -4475,30 +4468,31 @@ create_longjmp_breakpoint (char *func_na
    set_longjmp_resume_breakpoint() to figure out where we are going. */
 
 void
-enable_longjmp_breakpoint (void)
+set_longjmp_breakpoint (void)
 {
   struct breakpoint *b;
 
-  ALL_BREAKPOINTS (b)
-    if (b->type == bp_longjmp)
+  if (gdbarch_get_longjmp_target_p (current_gdbarch))
     {
-      b->enable_state = bp_enabled;
-      update_global_location_list ();
+      create_longjmp_breakpoint ("longjmp");
+      create_longjmp_breakpoint ("_longjmp");
+      create_longjmp_breakpoint ("siglongjmp");
+      create_longjmp_breakpoint ("_siglongjmp");
     }
 }
 
+/* Delete all longjmp breakpoints from THREAD.  */
 void
-disable_longjmp_breakpoint (void)
+delete_longjmp_breakpoint (int thread)
 {
-  struct breakpoint *b;
+  struct breakpoint *b, *temp;
 
-  ALL_BREAKPOINTS (b)
-    if (b->type == bp_longjmp
-	|| b->type == bp_longjmp_resume)
-    {
-      b->enable_state = bp_disabled;
-      update_global_location_list ();
-    }
+  ALL_BREAKPOINTS_SAFE (b, temp)
+    if (b->type == bp_longjmp)
+      {
+	if (b->thread == thread)
+	  delete_breakpoint (b);
+      }
 }
 
 static void
@@ -4791,30 +4785,6 @@ hw_watchpoint_used_count (enum bptype ty
   return i;
 }
 
-/* Call this after hitting the longjmp() breakpoint.  Use this to set
-   a new breakpoint at the target of the jmp_buf.
-
-   FIXME - This ought to be done by setting a temporary breakpoint
-   that gets deleted automatically... */
-
-void
-set_longjmp_resume_breakpoint (CORE_ADDR pc, struct frame_id frame_id)
-{
-  struct breakpoint *b;
-
-  ALL_BREAKPOINTS (b)
-    if (b->type == bp_longjmp_resume)
-    {
-      b->loc->requested_address = pc;
-      b->loc->address = adjust_breakpoint_address (b->loc->requested_address,
-                                                   b->type);
-      b->enable_state = bp_enabled;
-      b->frame_id = frame_id;
-      update_global_location_list ();
-      return;
-    }
-}
-
 void
 disable_watchpoints_before_interactive_call_start (void)
 {
@@ -4878,6 +4848,19 @@ set_momentary_breakpoint (struct symtab_
 
   return b;
 }
+
+struct breakpoint *
+set_momentary_breakpoint_at_pc (CORE_ADDR pc, enum bptype type)
+{
+  struct symtab_and_line sal;
+
+  sal = find_pc_line (pc, 0);
+  sal.pc = pc;
+  sal.section = find_pc_overlay (pc);
+  sal.explicit_pc = 1;
+
+  return set_momentary_breakpoint (sal, null_frame_id, type);
+}
 
 
 /* Tell the user we have just set a breakpoint B.  */
@@ -7529,10 +7512,8 @@ breakpoint_re_set_one (void *bint)
     default:
       printf_filtered (_("Deleting unknown breakpoint type %d\n"), b->type);
       /* fall through */
-      /* Delete longjmp and overlay event breakpoints; they will be
-         reset later by breakpoint_re_set.  */
-    case bp_longjmp:
-    case bp_longjmp_resume:
+      /* Delete overlay event breakpoints; they will be reset later by
+         breakpoint_re_set.  */
     case bp_overlay_event:
       delete_breakpoint (b);
       break;
@@ -7554,6 +7535,8 @@ breakpoint_re_set_one (void *bint)
     case bp_watchpoint_scope:
     case bp_call_dummy:
     case bp_step_resume:
+    case bp_longjmp:
+    case bp_longjmp_resume:
       break;
     }
 
@@ -7581,15 +7564,6 @@ breakpoint_re_set (void)
   }
   set_language (save_language);
   input_radix = save_input_radix;
-
-  if (gdbarch_get_longjmp_target_p (current_gdbarch))
-    {
-      create_longjmp_breakpoint ("longjmp");
-      create_longjmp_breakpoint ("_longjmp");
-      create_longjmp_breakpoint ("siglongjmp");
-      create_longjmp_breakpoint ("_siglongjmp");
-      create_longjmp_breakpoint (NULL);
-    }
   
   create_overlay_event_breakpoint ("_ovly_debug_event");
 }
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c	2008-05-04 20:15:45.000000000 +0100
+++ src/gdb/infrun.c	2008-05-04 20:20:14.000000000 +0100
@@ -279,6 +279,7 @@ struct regcache *stop_registers;
 
 static int stop_print_frame;
 
+/* Step-resume or longjmp-resume breakpoint.  */
 static struct breakpoint *step_resume_breakpoint = NULL;
 
 /* This is a cached copy of the pid/waitstatus of the last event
@@ -1380,7 +1381,6 @@ struct execution_control_state
   struct symtab_and_line sal;
   int current_line;
   struct symtab *current_symtab;
-  int handling_longjmp;		/* FIXME */
   ptid_t ptid;
   ptid_t saved_inferior_ptid;
   int step_after_step_resume_breakpoint;
@@ -1402,6 +1402,8 @@ static void insert_step_resume_breakpoin
 static void insert_step_resume_breakpoint_at_caller (struct frame_info *);
 static void insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
 						  struct frame_id sr_id);
+static void insert_longjmp_resume_breakpoint (CORE_ADDR);
+
 static void stop_stepping (struct execution_control_state *ecs);
 static void prepare_to_wait (struct execution_control_state *ecs);
 static void keep_going (struct execution_control_state *ecs);
@@ -1546,7 +1548,6 @@ init_execution_control_state (struct exe
   ecs->stepping_over_breakpoint = 0;
   ecs->random_signal = 0;
   ecs->step_after_step_resume_breakpoint = 0;
-  ecs->handling_longjmp = 0;	/* FIXME */
   ecs->stepping_through_solib_after_catch = 0;
   ecs->stepping_through_solib_catchpoints = NULL;
   ecs->sal = find_pc_line (prev_pc, 0);
@@ -1601,7 +1602,7 @@ context_switch (struct execution_control
 			 stepping_over_breakpoint, step_resume_breakpoint,
 			 step_range_start,
 			 step_range_end, &step_frame_id,
-			 ecs->handling_longjmp, ecs->stepping_over_breakpoint,
+			 ecs->stepping_over_breakpoint,
 			 ecs->stepping_through_solib_after_catch,
 			 ecs->stepping_through_solib_catchpoints,
 			 ecs->current_line, ecs->current_symtab);
@@ -1611,7 +1612,7 @@ context_switch (struct execution_control
 			 &stepping_over_breakpoint, &step_resume_breakpoint,
 			 &step_range_start,
 			 &step_range_end, &step_frame_id,
-			 &ecs->handling_longjmp, &ecs->stepping_over_breakpoint,
+			 &ecs->stepping_over_breakpoint,
 			 &ecs->stepping_through_solib_after_catch,
 			 &ecs->stepping_through_solib_catchpoints,
 			 &ecs->current_line, &ecs->current_symtab);
@@ -2574,38 +2575,50 @@ process_event_stop_test:
     switch (what.main_action)
       {
       case BPSTAT_WHAT_SET_LONGJMP_RESUME:
-	/* If we hit the breakpoint at longjmp, disable it for the
-	   duration of this command.  Then, install a temporary
-	   breakpoint at the target of the jmp_buf. */
-        if (debug_infrun)
-	  fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
-	disable_longjmp_breakpoint ();
+	/* If we hit the breakpoint at longjmp while stepping, we
+	   install a momentary breakpoint at the target of the
+	   jmp_buf.  */
+
+	if (debug_infrun)
+	  fprintf_unfiltered (gdb_stdlog,
+			      "infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME\n");
+
+	ecs->stepping_over_breakpoint = 1;
+
 	if (!gdbarch_get_longjmp_target_p (current_gdbarch)
 	    || !gdbarch_get_longjmp_target (current_gdbarch,
 					    get_current_frame (), &jmp_buf_pc))
 	  {
+	    if (debug_infrun)
+	      fprintf_unfiltered (gdb_stdlog, "\
+infrun: BPSTAT_WHAT_SET_LONGJMP_RESUME (!gdbarch_get_longjmp_target)\n");
 	    keep_going (ecs);
 	    return;
 	  }
 
-	/* Need to blow away step-resume breakpoint, as it
-	   interferes with us */
+	/* We're going to replace the current step-resume breakpoint
+	   with a longjmp-resume breakpoint.  */
 	if (step_resume_breakpoint != NULL)
-	  {
-	    delete_step_resume_breakpoint (&step_resume_breakpoint);
-	  }
+	  delete_step_resume_breakpoint (&step_resume_breakpoint);
+
+	/* Insert a breakpoint at resume address.  */
+	insert_longjmp_resume_breakpoint (jmp_buf_pc);
 
-	set_longjmp_resume_breakpoint (jmp_buf_pc, null_frame_id);
-	ecs->handling_longjmp = 1;	/* FIXME */
 	keep_going (ecs);
 	return;
 
       case BPSTAT_WHAT_CLEAR_LONGJMP_RESUME:
         if (debug_infrun)
-	  fprintf_unfiltered (gdb_stdlog, "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
-	disable_longjmp_breakpoint ();
-	ecs->handling_longjmp = 0;	/* FIXME */
-	break;
+	  fprintf_unfiltered (gdb_stdlog,
+			      "infrun: BPSTAT_WHAT_CLEAR_LONGJMP_RESUME\n");
+
+	gdb_assert (step_resume_breakpoint != NULL);
+	delete_step_resume_breakpoint (&step_resume_breakpoint);
+
+	stop_step = 1;
+	print_stop_reason (END_STEPPING_RANGE, 0);
+	stop_stepping (ecs);
+	return;
 
       case BPSTAT_WHAT_SINGLE:
         if (debug_infrun)
@@ -3168,9 +3181,8 @@ process_event_stop_test:
 static int
 currently_stepping (struct execution_control_state *ecs)
 {
-  return ((!ecs->handling_longjmp
-	   && ((step_range_end && step_resume_breakpoint == NULL)
-	       || stepping_over_breakpoint))
+  return (((step_range_end && step_resume_breakpoint == NULL)
+	   || stepping_over_breakpoint)
 	  || ecs->stepping_through_solib_after_catch
 	  || bpstat_should_step ());
 }
@@ -3257,8 +3269,8 @@ static void
 insert_step_resume_breakpoint_at_sal (struct symtab_and_line sr_sal,
 				      struct frame_id sr_id)
 {
-  /* There should never be more than one step-resume breakpoint per
-     thread, so we should never be setting a new
+  /* There should never be more than one step-resume or longjmp-resume
+     breakpoint per thread, so we should never be setting a new
      step_resume_breakpoint when one is already active.  */
   gdb_assert (step_resume_breakpoint == NULL);
 
@@ -3326,6 +3338,28 @@ insert_step_resume_breakpoint_at_caller 
   insert_step_resume_breakpoint_at_sal (sr_sal, frame_unwind_id (next_frame));
 }
 
+/* Insert a "longjmp-resume" breakpoint at PC.  This is used to set a
+   new breakpoint at the target of a jmp_buf.  The handling of
+   longjmp-resume uses the same mechanisms used for handling
+   "step-resume" breakpoints.  */
+
+static void
+insert_longjmp_resume_breakpoint (CORE_ADDR pc)
+{
+  /* There should never be more than one step-resume or longjmp-resume
+     breakpoint per thread, so we should never be setting a new
+     longjmp_resume_breakpoint when one is already active.  */
+  gdb_assert (step_resume_breakpoint == NULL);
+
+  if (debug_infrun)
+    fprintf_unfiltered (gdb_stdlog,
+			"infrun: inserting longjmp-resume breakpoint at 0x%s\n",
+			paddr_nz (pc));
+
+  step_resume_breakpoint =
+    set_momentary_breakpoint_at_pc (pc, bp_longjmp_resume);
+}
+
 static void
 stop_stepping (struct execution_control_state *ecs)
 {
Index: src/gdb/breakpoint.h
===================================================================
--- src.orig/gdb/breakpoint.h	2008-05-04 20:15:42.000000000 +0100
+++ src/gdb/breakpoint.h	2008-05-04 20:20:14.000000000 +0100
@@ -687,6 +687,9 @@ extern void breakpoint_re_set_thread (st
 extern struct breakpoint *set_momentary_breakpoint
   (struct symtab_and_line, struct frame_id, enum bptype);
 
+extern struct breakpoint *set_momentary_breakpoint_at_pc
+  (CORE_ADDR pc, enum bptype type);
+
 extern void set_ignore_count (int, int, int);
 
 extern void set_default_breakpoint (int, CORE_ADDR, struct symtab *, int);
@@ -755,12 +758,12 @@ extern void update_breakpoints_after_exe
    inferior_ptid.  */
 extern int detach_breakpoints (int);
 
-extern void enable_longjmp_breakpoint (void);
-extern void disable_longjmp_breakpoint (void);
+extern void set_longjmp_breakpoint (void);
+extern void delete_longjmp_breakpoint (int thread);
+
 extern void enable_overlay_breakpoints (void);
 extern void disable_overlay_breakpoints (void);
 
-extern void set_longjmp_resume_breakpoint (CORE_ADDR, struct frame_id);
 /* These functions respectively disable or reenable all currently
    enabled watchpoints.  When disabled, the watchpoints are marked
    call_disabled.  When reenabled, they are marked enabled.
Index: src/gdb/gdbthread.h
===================================================================
--- src.orig/gdb/gdbthread.h	2008-05-04 20:15:44.000000000 +0100
+++ src/gdb/gdbthread.h	2008-05-04 20:20:14.000000000 +0100
@@ -50,7 +50,6 @@ struct thread_info
   int current_line;
   struct symtab *current_symtab;
   int trap_expected;
-  int handling_longjmp;
   int stepping_over_breakpoint;
 
   /* This is set TRUE when a catchpoint of a shared library event
@@ -123,7 +122,6 @@ extern void save_infrun_state (ptid_t pt
 			       CORE_ADDR step_range_start,
 			       CORE_ADDR step_range_end,
 			       const struct frame_id *step_frame_id,
-			       int       handling_longjmp,
 			       int       another_trap,
 			       int       stepping_through_solib_after_catch,
 			       bpstat    stepping_through_solib_catchpoints,
@@ -139,7 +137,6 @@ extern void load_infrun_state (ptid_t pt
 			       CORE_ADDR *step_range_start,
 			       CORE_ADDR *step_range_end,
 			       struct frame_id *step_frame_id,
-			       int       *handling_longjmp,
 			       int       *another_trap,
 			       int       *stepping_through_solib_affter_catch,
 			       bpstat    *stepping_through_solib_catchpoints,
Index: src/gdb/thread.c
===================================================================
--- src.orig/gdb/thread.c	2008-05-04 20:15:45.000000000 +0100
+++ src/gdb/thread.c	2008-05-04 20:20:14.000000000 +0100
@@ -319,7 +319,6 @@ load_infrun_state (ptid_t ptid,
 		   CORE_ADDR *step_range_start,
 		   CORE_ADDR *step_range_end,
 		   struct frame_id *step_frame_id,
-		   int *handling_longjmp,
 		   int *stepping_over_breakpoint,
 		   int *stepping_through_solib_after_catch,
 		   bpstat *stepping_through_solib_catchpoints,
@@ -340,7 +339,6 @@ load_infrun_state (ptid_t ptid,
   *step_range_start = tp->step_range_start;
   *step_range_end = tp->step_range_end;
   *step_frame_id = tp->step_frame_id;
-  *handling_longjmp = tp->handling_longjmp;
   *stepping_over_breakpoint = tp->stepping_over_breakpoint;
   *stepping_through_solib_after_catch =
     tp->stepping_through_solib_after_catch;
@@ -360,7 +358,6 @@ save_infrun_state (ptid_t ptid,
 		   CORE_ADDR step_range_start,
 		   CORE_ADDR step_range_end,
 		   const struct frame_id *step_frame_id,
-		   int handling_longjmp,
 		   int stepping_over_breakpoint,
 		   int stepping_through_solib_after_catch,
 		   bpstat stepping_through_solib_catchpoints,
@@ -381,7 +378,6 @@ save_infrun_state (ptid_t ptid,
   tp->step_range_start = step_range_start;
   tp->step_range_end = step_range_end;
   tp->step_frame_id = (*step_frame_id);
-  tp->handling_longjmp = handling_longjmp;
   tp->stepping_over_breakpoint = stepping_over_breakpoint;
   tp->stepping_through_solib_after_catch = stepping_through_solib_after_catch;
   tp->stepping_through_solib_catchpoints = stepping_through_solib_catchpoints;
Index: src/gdb/infcmd.c
===================================================================
--- src.orig/gdb/infcmd.c	2008-05-04 20:15:45.000000000 +0100
+++ src/gdb/infcmd.c	2008-05-04 20:20:14.000000000 +0100
@@ -107,7 +107,7 @@ static void signal_command (char *, int)
 static void jump_command (char *, int);
 
 static void step_1 (int, int, char *);
-static void step_once (int skip_subroutines, int single_inst, int count);
+static void step_once (int skip_subroutines, int single_inst, int count, int thread);
 static void step_1_continuation (struct continuation_arg *arg, int error_p);
 
 static void next_command (char *, int);
@@ -693,9 +693,10 @@ nexti_command (char *count_string, int f
 }
 
 static void
-disable_longjmp_breakpoint_cleanup (void *ignore)
+delete_longjmp_breakpoint_cleanup (void *arg)
 {
-  disable_longjmp_breakpoint ();
+  int thread = * (int *) arg;
+  delete_longjmp_breakpoint (thread);
 }
 
 static void
@@ -705,6 +706,7 @@ step_1 (int skip_subroutines, int single
   struct frame_info *frame;
   struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
   int async_exec = 0;
+  int *thread_p = NULL;
 
   ERROR_NO_INFERIOR;
 
@@ -728,8 +730,17 @@ step_1 (int skip_subroutines, int single
 
   if (!single_inst || skip_subroutines)		/* leave si command alone */
     {
-      enable_longjmp_breakpoint ();
-      make_cleanup (disable_longjmp_breakpoint_cleanup, 0 /*ignore*/);
+      thread_p = xmalloc (sizeof (int));
+      make_cleanup (xfree, thread_p);
+
+      if (in_thread_list (inferior_ptid))
+ 	*thread_p = pid_to_thread_id (inferior_ptid);
+      else
+ 	*thread_p = -1;
+
+      set_longjmp_breakpoint ();
+
+      make_cleanup (delete_longjmp_breakpoint_cleanup, thread_p);
     }
 
   /* In synchronous case, all is well, just use the regular for loop. */
@@ -790,10 +801,11 @@ which has no line number information.\n"
      and handle them one at the time, through step_once(). */
   else
     {
-      step_once (skip_subroutines, single_inst, count);
-      /* We are running, and the contination is installed.  It will
+      step_once (skip_subroutines, single_inst, count, *thread_p);
+      /* We are running, and the continuation is installed.  It will
 	 disable the longjmp breakpoint as appropriate.  */
       discard_cleanups (cleanups);
+      xfree (thread_p);
     }
 }
 
@@ -808,10 +820,12 @@ step_1_continuation (struct continuation
   int count;
   int skip_subroutines;
   int single_inst;
+  int thread;
       
   skip_subroutines = arg->data.integer;
   single_inst      = arg->next->data.integer;
   count            = arg->next->next->data.integer;
+  thread           = arg->next->next->next->data.integer;
 
   if (error_p || !step_multi || !stop_step)
     {
@@ -819,11 +833,11 @@ step_1_continuation (struct continuation
 	 that is not stepping, or there are no further steps
 	 to make.  Cleanup.  */
       if (!single_inst || skip_subroutines)
-	disable_longjmp_breakpoint ();
+	delete_longjmp_breakpoint (thread);
       step_multi = 0;
     }
   else
-    step_once (skip_subroutines, single_inst, count - 1);
+    step_once (skip_subroutines, single_inst, count - 1, thread);
 }
 
 /* Do just one step operation. If count >1 we will have to set up a
@@ -834,11 +848,12 @@ step_1_continuation (struct continuation
    called in case of step n with n>1, after the first step operation has
    been completed.*/
 static void 
-step_once (int skip_subroutines, int single_inst, int count)
+step_once (int skip_subroutines, int single_inst, int count, int thread)
 { 
   struct continuation_arg *arg1; 
   struct continuation_arg *arg2;
   struct continuation_arg *arg3; 
+  struct continuation_arg *arg4;
   struct frame_info *frame;
 
   if (count > 0)
@@ -894,12 +909,16 @@ which has no line number information.\n"
 	(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
       arg3 =
 	(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
+      arg4 =
+	(struct continuation_arg *) xmalloc (sizeof (struct continuation_arg));
       arg1->next = arg2;
       arg1->data.integer = skip_subroutines;
       arg2->next = arg3;
       arg2->data.integer = single_inst;
-      arg3->next = NULL;
+      arg3->next = arg4;
       arg3->data.integer = count;
+      arg4->next = NULL;
+      arg4->data.integer = thread;
       add_intermediate_continuation (step_1_continuation, arg1);
     }
 }
Index: src/gdb/testsuite/gdb.cp/annota2.exp
===================================================================
--- src.orig/gdb/testsuite/gdb.cp/annota2.exp	2008-05-04 20:15:46.000000000 +0100
+++ src/gdb/testsuite/gdb.cp/annota2.exp	2008-05-04 20:20:14.000000000 +0100
@@ -190,9 +190,9 @@ gdb_expect {
 #
 send_gdb "next\n"
 gdb_expect {
-   -re "\r\n\032\032post-prompt\r\n\r\n\032\032starting\r\n\r\n(\032\032frames-invalid\r\n\r\n)*\032\032watchpoint 3\r\n.*atchpoint 3: a.x\r\n\r\nOld value = 0\r\nNew value = 1\r\n\r\n\032\032frame-begin 0 $hex\r\n\r\n\032\032frame-function-name\r\nmain\r\n\032\032frame-args\r\n \\(\\)\r\n\032\032frame-source-begin\r\n at \r\n\032\032frame-source-file\r\n.*$srcfile\r\n\032\032frame-source-file-end\r\n:\r\n\032\032frame-source-line\r\n$decimal\r\n\032\032frame-source-end\r\n\r\n\r\n\032\032source .*$srcfile.*beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n.*$gdb_prompt$" \
+   -re "\r\n\032\032post-prompt\r\n\r\n(\032\032breakpoints-invalid\r\n\r\n)*\032\032starting\r\n\r\n(\032\032frames-invalid\r\n\r\n)*\032\032watchpoint 3\r\n.*atchpoint 3: a.x\r\n\r\nOld value = 0\r\nNew value = 1\r\n\r\n\032\032frame-begin 0 $hex\r\n\r\n\032\032frame-function-name\r\nmain\r\n\032\032frame-args\r\n \\(\\)\r\n\032\032frame-source-begin\r\n at \r\n\032\032frame-source-file\r\n.*$srcfile\r\n\032\032frame-source-file-end\r\n:\r\n\032\032frame-source-line\r\n$decimal\r\n\032\032frame-source-end\r\n\r\n\r\n\032\032source .*$srcfile.*beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n.*$gdb_prompt$" \
 	   { pass "watch triggered on a.x" }
-   -re "\r\n\032\032post-prompt\r\n\r\n\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032source .*$srcfile.*beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \
+   -re "\r\n\032\032post-prompt\r\n\r\n(\032\032breakpoints-invalid\r\n\r\n)*\032\032starting\r\n\r\n\032\032frames-invalid\r\n\r\n\032\032source .*$srcfile.*beg:$hex\r\n\r\n\032\032frame-end\r\n\r\n\032\032stopped\r\n$gdb_prompt$" \
 	   { kfail "gdb/38" "watch triggered on a.x" }
    -re ".*$gdb_prompt$"  { fail "watch triggered on a.x" }
    timeout    { fail "watch triggered on a.x (timeout)" }

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