aboutsummaryrefslogtreecommitdiff
path: root/devel/gdb/files/commit-2c5c2a3
diff options
context:
space:
mode:
Diffstat (limited to 'devel/gdb/files/commit-2c5c2a3')
-rw-r--r--devel/gdb/files/commit-2c5c2a3214
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;