diff options
Diffstat (limited to 'devel/gdb/files/commit-2c5c2a3')
-rw-r--r-- | devel/gdb/files/commit-2c5c2a3 | 214 |
1 files changed, 0 insertions, 214 deletions
diff --git a/devel/gdb/files/commit-2c5c2a3 b/devel/gdb/files/commit-2c5c2a3 deleted file mode 100644 index 35bdb0354dca..000000000000 --- a/devel/gdb/files/commit-2c5c2a3 +++ /dev/null @@ -1,214 +0,0 @@ -commit 2c5c2a3321706c28cbf1b85a970a2e32912eb0c8 -Author: John Baldwin <jhb@FreeBSD.org> -Date: Fri Jun 24 21:00:04 2016 -0700 - - Fake VFORK_DONE events when following only the parent after a vfork. - - FreeBSD does not currently report a ptrace event for a parent process - after it resumes due to the child exiting the shared memory region after - a vfork. Take the same approach used in linux-nat.c in this case of - sleeping for a while and then reporting a fake VFORK_DONE event. - - gdb/ChangeLog: - - * fbsd-nat.c (struct fbsd_fork_child_info): Rename to ... - (struct fbsd_fork_info): ... this. - (struct fbsd_fork_info) <child>: Rename to ... - (struct fbsd_fork_info) <ptid>: ... this. - (fbsd_pending_children): Update type. - (fbsd_remember_child): Update type and field name. - (fbsd_is_child_pending): Likewise. - (fbsd_pending_vfork_done): New variable. - (fbsd_is_vfork_done_pending): New function. - (fbsd_next_vfork_done): New function. - (fbsd_resume): Don't resume processes with a pending vfork done - event. - (fbsd_wait): Report pending vfork done events. - (fbsd_follow_fork): Delay and record a pending vfork done event - for a vfork parent when detaching the child. - -diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c -index daf4580..fcb7ff5 100644 ---- gdb/fbsd-nat.c -+++ gdb/fbsd-nat.c -@@ -530,13 +530,13 @@ fbsd_update_thread_list (struct target_ops *ops) - sake. FreeBSD versions newer than 9.1 contain both fixes. - */ - --struct fbsd_fork_child_info -+struct fbsd_fork_info - { -- struct fbsd_fork_child_info *next; -- ptid_t child; /* Pid of new child. */ -+ struct fbsd_fork_info *next; -+ ptid_t ptid; - }; - --static struct fbsd_fork_child_info *fbsd_pending_children; -+static struct fbsd_fork_info *fbsd_pending_children; - - /* Record a new child process event that is reported before the - corresponding fork event in the parent. */ -@@ -544,9 +544,9 @@ static struct fbsd_fork_child_info *fbsd_pending_children; - static void - fbsd_remember_child (ptid_t pid) - { -- struct fbsd_fork_child_info *info = XCNEW (struct fbsd_fork_child_info); -+ struct fbsd_fork_info *info = XCNEW (struct fbsd_fork_info); - -- info->child = pid; -+ info->ptid = pid; - info->next = fbsd_pending_children; - fbsd_pending_children = info; - } -@@ -557,25 +557,74 @@ fbsd_remember_child (ptid_t pid) - static ptid_t - fbsd_is_child_pending (pid_t pid) - { -- struct fbsd_fork_child_info *info, *prev; -+ struct fbsd_fork_info *info, *prev; - ptid_t ptid; - - prev = NULL; - for (info = fbsd_pending_children; info; prev = info, info = info->next) - { -- if (ptid_get_pid (info->child) == pid) -+ if (ptid_get_pid (info->ptid) == pid) - { - if (prev == NULL) - fbsd_pending_children = info->next; - else - prev->next = info->next; -- ptid = info->child; -+ ptid = info->ptid; - xfree (info); - return ptid; - } - } - return null_ptid; - } -+ -+static struct fbsd_fork_info *fbsd_pending_vfork_done; -+ -+/* Record a pending vfork done event. */ -+ -+static void -+fbsd_add_vfork_done (ptid_t pid) -+{ -+ struct fbsd_fork_info *info = XCNEW (struct fbsd_fork_info); -+ -+ info->ptid = pid; -+ info->next = fbsd_pending_vfork_done; -+ fbsd_pending_vfork_done = info; -+} -+ -+/* Check for a pending vfork done event for a specific PID. */ -+ -+static int -+fbsd_is_vfork_done_pending (pid_t pid) -+{ -+ struct fbsd_fork_info *info; -+ -+ for (info = fbsd_pending_vfork_done; info != NULL; info = info->next) -+ { -+ if (ptid_get_pid (info->ptid) == pid) -+ return 1; -+ } -+ return 0; -+} -+ -+/* Check for a pending vfork done event. If one is found, remove it -+ from the list and return the PTID. */ -+ -+static ptid -+fbsd_next_vfork_done (void) -+{ -+ struct fbsd_fork_info *info; -+ ptid_t ptid; -+ -+ if (fbsd_pending_vfork_done != NULL) -+ { -+ info = fbsd_pending_vfork_done; -+ fbsd_pending_vfork_done = info->next; -+ ptid = info->ptid; -+ xfree (info); -+ return ptid; -+ } -+ return null_ptid; -+} - #endif - - static int -@@ -616,6 +665,17 @@ static void - fbsd_resume (struct target_ops *ops, - ptid_t ptid, int step, enum gdb_signal signo) - { -+#ifdef TDP_RFPPWAIT -+ pid_t pid; -+ -+ /* Don't PT_CONTINUE a process which has a pending vfork done event. */ -+ if (ptid_equal (minus_one_ptid, ptid)) -+ pid = ptid_get_pid (inferior_ptid); -+ else -+ pid = ptid_get_pid (ptid); -+ if (fbsd_is_vfork_done_pending (pid)) -+ return; -+#endif - - if (debug_fbsd_lwp) - fprintf_unfiltered (gdb_stdlog, -@@ -650,6 +710,12 @@ fbsd_wait (struct target_ops *ops, - - while (1) - { -+ wptid = fbsd_next_vfork_done (); -+ if (!ptid_equal (wptid, null_ptid)) -+ { -+ ourstatus->kind = TARGET_WAITKIND_VFORK_DONE; -+ return wptid; -+ } - wptid = super_wait (ops, ptid, ourstatus, target_options); - if (ourstatus->kind == TARGET_WAITKIND_STOPPED) - { -@@ -828,6 +894,7 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child, - if (!follow_child && detach_fork) - { - struct thread_info *tp = inferior_thread (); -+ int has_vforked = tp->pending_follow.kind == TARGET_WAITKIND_VFORKED; - pid_t child_pid = ptid_get_pid (tp->pending_follow.value.related_pid); - - /* Breakpoints have already been detached from the child by -@@ -835,6 +902,33 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child, - - if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1) - perror_with_name (("ptrace")); -+ -+ if (has_vforked) -+ { -+ /* We can't insert breakpoints until the child process has -+ finished with the shared memory region. The parent -+ process doesn't wait for the child process to exit or -+ exec until after it has been resumed from the ptrace stop -+ to report the fork. Once it has been resumed it doesn't -+ stop again before returning to userland, so there is no -+ reliable way to wait on the parent. -+ -+ We can't stay attached to the child to wait for an exec -+ or exit because it may invoke ptrace(PT_TRACE_ME) -+ (e.g. if the parent process is a debugger forking a new -+ child process). -+ -+ In the end, the best we can do is to make sure it runs -+ for a little while. Hopefully it will be out of range of -+ any breakpoints we reinsert. Usually this is only the -+ single-step breakpoint at vfork's return point. */ -+ -+ usleep (10000); -+ -+ /* Schedule a fake VFORK_DONE event to report on the next -+ wait. */ -+ fbsd_add_vfork_done (inferior_ptid); -+ } - } - - return 0; |