gdb/
authorPedro Alves <palves@redhat.com>
Sun, 4 May 2008 19:39:00 +0000 (19:39 +0000)
committerPedro Alves <palves@redhat.com>
Sun, 4 May 2008 19:39:00 +0000 (19:39 +0000)
* 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 (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.

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

gdb/ChangeLog
gdb/breakpoint.c
gdb/breakpoint.h
gdb/gdbthread.h
gdb/infcmd.c
gdb/infrun.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/annota2.exp
gdb/thread.c

index 98ce9b1..c933612 100644 (file)
@@ -1,3 +1,61 @@
+2008-05-04  Pedro Alves  <pedro@codesourcery.com>
+
+       * 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 (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.
+
 2008-05-04  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        Set CU BASE_ADDRESS already from partial DIEs.
index 737558e..1e7f361 100644 (file)
@@ -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_ADDR addr, struct symtab *symtab,
       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 breakpoint *bpt)
          && 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_name)
   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_name)
    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 type, int *other_type_used)
   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_and_line sal, struct frame_id frame_id,
 
   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);
+}
 \f
 
 /* 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 d37e790..80544e4 100644 (file)
@@ -687,6 +687,9 @@ extern void breakpoint_re_set_thread (struct breakpoint *);
 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_exec (void);
    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 e8bfde4..5f9e985 100644 (file)
@@ -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 ptid,
                               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 ptid,
                               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 3165a26..b75c524 100644 (file)
@@ -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 from_tty)
 }
 
 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_inst, char *count_string)
   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_inst, char *count_string)
 
   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"), name);
      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_arg *arg, int error_p)
   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_arg *arg, int error_p)
         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_arg *arg, int error_p)
    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"), name);
        (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 8c4c410..a1bb287 100644 (file)
@@ -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_breakpoint_at_frame (struct frame_info *step_fram
 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 execution_control_state *ecs)
   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_state *ecs)
                         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_state *ecs)
                         &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 (struct frame_info *next_frame)
   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 7071545..1e93035 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-04  Pedro Alves  <pedro@codesourcery.com>
+
+       * gdb.cp/annota2.exp: Adjust to breakpoints invalidations at
+       different times.
+
 2008-05-04  Jan Kratochvil  <jan.kratochvil@redhat.com>
 
        * gdb.dwarf2/dw2-ranges.S: Merge the secondary section with `.fini'.
index 2dd9f4b..7291106 100644 (file)
@@ -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 3de3289..c36bb4a 100644 (file)
@@ -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;