From d80ee84fe21876c78f66e60b70e335e8dab99d07 Mon Sep 17 00:00:00 2001 From: Joel Brobecker Date: Thu, 16 Aug 2012 23:54:50 +0000 Subject: [PATCH] Change detach_breakpoints to take a ptid instead of a pid 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 | 14 ++++++++++++++ gdb/breakpoint.c | 6 +++--- gdb/breakpoint.h | 2 +- gdb/inf-ttrace.c | 4 ++-- gdb/infrun.c | 4 +--- gdb/linux-nat.c | 3 +-- 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f40d597964..f52139f644 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2012-08-16 Joel Brobecker + + * 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 * inf-ttrace.c (inf_ttrace_follow_fork): When following the diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 7ea5ba6fef..c693d420d5 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -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) diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h index 4e4f875d14..4c6171f4e4 100644 --- a/gdb/breakpoint.h +++ b/gdb/breakpoint.h @@ -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 diff --git a/gdb/inf-ttrace.c b/gdb/inf-ttrace.c index ddcbd428b8..2b9e7f536d 100644 --- a/gdb/inf-ttrace.c +++ b/gdb/inf-ttrace.c @@ -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, diff --git a/gdb/infrun.c b/gdb/infrun.c index 666308605a..9628170ba4 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -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) diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 9844b0c493..3516565145 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -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)) -- 2.34.1