* breakpoint.c (mark_breakpoints_out): Make public.
authorPedro Alves <palves@redhat.com>
Tue, 8 Jul 2008 10:59:57 +0000 (10:59 +0000)
committerPedro Alves <palves@redhat.com>
Tue, 8 Jul 2008 10:59:57 +0000 (10:59 +0000)
(update_breakpoints_after_exec): Don't call mark_breakpoints_out
here.  Update comment.
* breakpoint.h (mark_breakpoints_out): Declare.

* linux-nat.c (linux_handle_extended_wait): On
TARGET_WAITKIND_EXECD, call mark_breakpoints_out.
* inf-ttrace.c (inf_ttrace_wait): Likewise.

gdb/ChangeLog
gdb/breakpoint.c
gdb/breakpoint.h
gdb/inf-ttrace.c
gdb/linux-nat.c

index 784ad45cd81fd39a6ee02a9af39525564b43a703..82d805ffb769d0822a9d5cf150de6461e87915e0 100644 (file)
@@ -1,3 +1,14 @@
+2008-07-08  Pedro Alves  <pedro@codesourcery.com>
+
+       * breakpoint.c (mark_breakpoints_out): Make public.
+       (update_breakpoints_after_exec): Don't call mark_breakpoints_out
+       here.  Update comment.
+       * breakpoint.h (mark_breakpoints_out): Declare.
+
+       * linux-nat.c (linux_handle_extended_wait): On
+       TARGET_WAITKIND_EXECD, call mark_breakpoints_out.
+       * inf-ttrace.c (inf_ttrace_wait): Likewise.
+
 2008-07-08  Pedro Alves  <pedro@codesourcery.com>
 
        * infrun.c (follow_exec): Reset shared libraries before adding the
index e774bca940be655720f350511215edecb3afaac0..9d7bf71576d622aa39032272ce9eeba446bbbd3a 100644 (file)
@@ -188,8 +188,6 @@ static int single_step_breakpoint_inserted_here_p (CORE_ADDR pc);
 
 static void free_bp_location (struct bp_location *loc);
 
-static void mark_breakpoints_out (void);
-
 static struct bp_location *
 allocate_bp_location (struct breakpoint *bpt, enum bptype bp_type);
 
@@ -1443,12 +1441,19 @@ update_breakpoints_after_exec (void)
 {
   struct breakpoint *b;
   struct breakpoint *temp;
+  struct bp_location *bploc;
   struct cleanup *cleanup;
 
-  /* Doing this first prevents the badness of having delete_breakpoint()
-     write a breakpoint's current "shadow contents" to lift the bp.  That
-     shadow is NOT valid after an exec()! */
-  mark_breakpoints_out ();
+  /* We're about to delete breakpoints from GDB's lists.  If the
+     INSERTED flag is true, GDB will try to lift the breakpoints by
+     writing the breakpoints' "shadow contents" back into memory.  The
+     "shadow contents" are NOT valid after an exec, so GDB should not
+     do that.  Instead, the target is responsible from marking
+     breakpoints out as soon as it detects an exec.  We don't do that
+     here instead, because there may be other attempts to delete
+     breakpoints after detecting an exec and before reaching here.  */
+  ALL_BP_LOCATIONS (bploc)
+    gdb_assert (!bploc->inserted);
 
   /* The binary we used to debug is now gone, and we're updating
      breakpoints for the new binary.  Until we're done, we should not
@@ -1699,7 +1704,7 @@ remove_breakpoint (struct bp_location *b, insertion_state_t is)
 
 /* Clear the "inserted" flag in all breakpoints.  */
 
-static void
+void
 mark_breakpoints_out (void)
 {
   struct bp_location *bpt;
index 2c98d64e8bc6d01902ee3e949d3d2dbbfb3a8cf3..4636a13351cc7c97c42f57e05b238ed1cb3eb54e 100644 (file)
@@ -826,6 +826,9 @@ extern void disable_breakpoint (struct breakpoint *);
 
 extern void enable_breakpoint (struct breakpoint *);
 
+/* Clear the "inserted" flag in all breakpoints.  */
+extern void mark_breakpoints_out (void);
+
 extern void make_breakpoint_permanent (struct breakpoint *);
 
 extern struct breakpoint *create_solib_event_breakpoint (CORE_ADDR);
index 8a8399ad956d278d854cf5cec37ac48b5ecae3d8..95c296e4a24b8b48cda6297bd178f617ad68f348 100644 (file)
@@ -904,6 +904,12 @@ inf_ttrace_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
                  tts.tts_u.tts_exec.tts_pathlen, 0) == -1)
        perror_with_name (("ttrace"));
       ourstatus->value.execd_pathname[tts.tts_u.tts_exec.tts_pathlen] = 0;
+
+      /* At this point, all inserted breakpoints are gone.  Doing this
+        as soon as we detect an exec prevents the badness of deleting
+        a breakpoint writing the current "shadow contents" to lift
+        the bp.  That shadow is NOT valid after an exec.  */
+      mark_breakpoints_out ();
       break;
 
     case TTEVT_EXIT:
index 964337884e088394e41c961b05f88288354e6242..ce3df53f5dbc99bb45400e813056c0318b312b9d 100644 (file)
@@ -1758,6 +1758,16 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
          linux_parent_pid = 0;
        }
 
+      /* At this point, all inserted breakpoints are gone.  Doing this
+        as soon as we detect an exec prevents the badness of deleting
+        a breakpoint writing the current "shadow contents" to lift
+        the bp.  That shadow is NOT valid after an exec.
+
+        Note that we have to do this after the detach_breakpoints
+        call above, otherwise breakpoints wouldn't be lifted from the
+        parent on a vfork, because detach_breakpoints would think
+        that breakpoints are not inserted.  */
+      mark_breakpoints_out ();
       return 0;
     }