Change detach_breakpoints to take a ptid instead of a pid
authorJoel Brobecker <brobecker@gnat.com>
Thu, 16 Aug 2012 23:54:50 +0000 (23:54 +0000)
committerJoel Brobecker <brobecker@gnat.com>
Thu, 16 Aug 2012 23:54:50 +0000 (23:54 +0000)
Before this change, detach_breakpoints would take a pid, and then
set inferior_ptid to a ptid that it constructs using pid_to_ptid (pid).
Unfortunately, this ptid is not necessarily valid.  Consider for
instance the case of ia64-hpux, where ttrace refuses a register-read
operation if the LWP is not provided.

This problems shows up when GDB is trying to handle fork events.
Assuming GDB is configured to follow the parent, GDB will try to
detach from the child. But before doing so, it needs to remove
all breakpoints inside that child.  On ia64, this involves reading
inferior (the child's) memory. And on ia64-hpux, reading memory
requires us to read the bsp and bspstore registers, in order to
determine where that memory is relative to the value of those
registers, and thus to determine which ttrace operation to use in
order to fetch that memory (see ia64_hpux_xfer_memory).

This patch therefore changes detach_breakpoints to take a ptid instead
of a pid, and then updates all callers.

One of the consequences of this patch is that it trips an assert
on GNU/Linux targets.  But this assert appears to have not actual
purpose, and is thus removed.

gdb/ChangeLog:

        * breakpoint.h (detach_breakpoints): pid parameter is now a ptid.
        * breakpoint.c (detach_breakpoints): Change pid parameter into
        a ptid.  Adjust code accordingly.
        * infrun.c (handle_inferior_event): Delete variable child_pid.
        Update call to detach_breakpoints to pass the child ptid for
        fork events.
        * linux-nat.c (linux_nat_iterate_watchpoint_lwps): Remove
        assert that inferior_ptid's lwp is zero.
        (linux_handle_extended_wait): Update call to detach_breakpoints.
        * inf-ttrace.c (inf_ttrace_follow_fork): Update call to
        detach_breakpoints.

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

index f40d5979646e73b51d2e2be5cef35ba05ba00b3b..f52139f6442e062f8fd2e0e239d009fe2d92ef72 100644 (file)
@@ -1,3 +1,17 @@
+2012-08-16  Joel Brobecker  <brobecker@adacore.com>
+
+       * breakpoint.h (detach_breakpoints): pid parameter is now a ptid.
+       * breakpoint.c (detach_breakpoints): Change pid parameter into
+       a ptid.  Adjust code accordingly.
+       * infrun.c (handle_inferior_event): Delete variable child_pid.
+       Update call to detach_breakpoints to pass the child ptid for
+       fork events.
+       * linux-nat.c (linux_nat_iterate_watchpoint_lwps): Remove
+       assert that inferior_ptid's lwp is zero.
+       (linux_handle_extended_wait): Update call to detach_breakpoints.
+       * inf-ttrace.c (inf_ttrace_follow_fork): Update call to
+       detach_breakpoints.
+
 2012-08-16  Joel Brobecker  <brobecker@adacore.com>
 
        * inf-ttrace.c (inf_ttrace_follow_fork): When following the
index 7ea5ba6feff533d2bf428536c6e9b43c26a132f0..c693d420d5de6d27ff8aa4e7a0f0dccbf056cf1e 100644 (file)
@@ -3500,18 +3500,18 @@ update_breakpoints_after_exec (void)
 }
 
 int
-detach_breakpoints (int pid)
+detach_breakpoints (ptid_t ptid)
 {
   struct bp_location *bl, **blp_tmp;
   int val = 0;
   struct cleanup *old_chain = save_inferior_ptid ();
   struct inferior *inf = current_inferior ();
 
-  if (pid == PIDGET (inferior_ptid))
+  if (PIDGET (ptid) == PIDGET (inferior_ptid))
     error (_("Cannot detach breakpoints of inferior_ptid"));
 
   /* Set inferior_ptid; remove_breakpoint_1 uses this global.  */
-  inferior_ptid = pid_to_ptid (pid);
+  inferior_ptid = ptid;
   ALL_BP_LOCATIONS (bl, blp_tmp)
   {
     if (bl->pspace != inf->pspace)
index 4e4f875d14c917bf3c971c87ea0ac9b41b00c31a..4c6171f4e469e8c06b0597716fa0bac7999378bc 100644 (file)
@@ -1284,7 +1284,7 @@ extern void update_breakpoints_after_exec (void);
 
    It is an error to use this function on the process whose id is
    inferior_ptid.  */
-extern int detach_breakpoints (int);
+extern int detach_breakpoints (ptid_t ptid);
 
 /* This function is called when program space PSPACE is about to be
    deleted.  It takes care of updating breakpoints to not reference
index ddcbd428b8b15c0e53b1140adf55f139724599f2..2b9e7f536de6e83fd04a661ccd12f36fd91cce86 100644 (file)
@@ -457,7 +457,7 @@ inf_ttrace_follow_fork (struct target_ops *ops, int follow_child)
       inf->pspace = parent_inf->pspace;
       inf->aspace = parent_inf->aspace;
       copy_terminal_info (inf, parent_inf);
-      detach_breakpoints (pid);
+      detach_breakpoints (ptid_build (pid, lwpid, 0));
 
       target_terminal_ours ();
       fprintf_unfiltered (gdb_stdlog,
@@ -471,7 +471,7 @@ inf_ttrace_follow_fork (struct target_ops *ops, int follow_child)
         of fork events, we do not need to do this, because breakpoints
         should have already been removed earlier.  */
       if (tts.tts_event == TTEVT_VFORK)
-       detach_breakpoints (fpid);
+       detach_breakpoints (ptid_build (fpid, flwpid, 0));
 
       target_terminal_ours ();
       fprintf_unfiltered (gdb_stdlog,
index 666308605af9f984ee3ad4edb3fc0851973609bb..9628170ba405b1d1782c08ac5be2fc95f9daec6a 100644 (file)
@@ -3497,11 +3497,9 @@ handle_inferior_event (struct execution_control_state *ecs)
         vfork follow are detached.  */
       if (ecs->ws.kind != TARGET_WAITKIND_VFORKED)
        {
-         int child_pid = ptid_get_pid (ecs->ws.value.related_pid);
-
          /* This won't actually modify the breakpoint list, but will
             physically remove the breakpoints from the child.  */
-         detach_breakpoints (child_pid);
+         detach_breakpoints (ecs->ws.value.related_pid);
        }
 
       if (singlestep_breakpoints_inserted_p)
index 9844b0c49313bd1920b6aacd9dbe0a13b775a864..351656514553334c5a942ccda16878fc213a7ad7 100644 (file)
@@ -1307,7 +1307,6 @@ linux_nat_iterate_watchpoint_lwps
       pid_t child_pid = GET_PID (inferior_ptid);
       ptid_t child_ptid = ptid_build (child_pid, child_pid, 0);
 
-      gdb_assert (!is_lwp (inferior_ptid));
       gdb_assert (find_lwp_pid (child_ptid) == NULL);
       child_lp = add_lwp (child_ptid);
       child_lp->stopped = 1;
@@ -2314,7 +2313,7 @@ linux_handle_extended_wait (struct lwp_info *lp, int status,
 
          /* This won't actually modify the breakpoint list, but will
             physically remove the breakpoints from the child.  */
-         detach_breakpoints (new_pid);
+         detach_breakpoints (ptid_build (new_pid, new_pid, 0));
 
          /* Retain child fork in ptrace (stopped) state.  */
          if (!find_fork_pid (new_pid))