|
Line 0
Link Here
|
|
|
1 |
commit dbaed3853474e7bd824a25bc454a8f2fdd71d2b3 |
| 2 |
Author: John Baldwin <jhb@FreeBSD.org> |
| 3 |
Date: Sat Jul 16 10:14:08 2016 -0700 |
| 4 |
|
| 5 |
Use a real vfork done event on FreeBSD when available. |
| 6 |
|
| 7 |
FreeBSD 12 recently added a new ptrace event to indicate when the vfork |
| 8 |
parent resumes after the child process stops sharing the address space. |
| 9 |
Use this event to report a proper TARGET_WAITKIND_VFORK_DONE rather than |
| 10 |
faking a vfork done event after a delay. |
| 11 |
|
| 12 |
gdb/ChangeLog: |
| 13 |
|
| 14 |
* fbsd-nat.c (fbsd_enable_proc_events): Enable "PTRACE_VFORK" |
| 15 |
events. |
| 16 |
(fbsd_pending_vfork_done): Only define if "PTRACE_VFORK" is not |
| 17 |
defined. |
| 18 |
(fbsd_add_vfork_done): Likewise. |
| 19 |
(fbsd_is_vfork_done_pending): Likewise. |
| 20 |
(fbsd_next_vfork_done): Likewise. |
| 21 |
(fbsd_resume): Only ignore pending vfork done events if |
| 22 |
"PTRACE_VFORK" is not defined. |
| 23 |
(fbsd_wait): Only look for pending vfork done events if |
| 24 |
"PTRACE_VFORK" is not defined. |
| 25 |
[PTRACE_VFORK]: Handle "PL_FLAG_VFORKED" and "PL_FLAG_VFORK_DONE" |
| 26 |
events. |
| 27 |
(fbsd_follow_fork): Only fake a vfork done event if "PTRACE_VFORK" |
| 28 |
is not defined. |
| 29 |
|
| 30 |
diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c |
| 31 |
index 5e4304e..ade62f1 100644 |
| 32 |
--- gdb/fbsd-nat.c |
| 33 |
+++ gdb/fbsd-nat.c |
| 34 |
@@ -435,6 +435,9 @@ fbsd_enable_proc_events (pid_t pid) |
| 35 |
sizeof (events)) == -1) |
| 36 |
perror_with_name (("ptrace")); |
| 37 |
events |= PTRACE_FORK | PTRACE_LWP; |
| 38 |
+#ifdef PTRACE_VFORK |
| 39 |
+ events |= PTRACE_VFORK; |
| 40 |
+#endif |
| 41 |
if (ptrace (PT_SET_EVENT_MASK, pid, (PTRACE_TYPE_ARG3)&events, |
| 42 |
sizeof (events)) == -1) |
| 43 |
perror_with_name (("ptrace")); |
| 44 |
@@ -598,6 +601,7 @@ fbsd_is_child_pending (pid_t pid) |
| 45 |
return null_ptid; |
| 46 |
} |
| 47 |
|
| 48 |
+#ifndef PTRACE_VFORK |
| 49 |
static struct fbsd_fork_info *fbsd_pending_vfork_done; |
| 50 |
|
| 51 |
/* Record a pending vfork done event. */ |
| 52 |
@@ -647,6 +651,7 @@ fbsd_next_vfork_done (void) |
| 53 |
return null_ptid; |
| 54 |
} |
| 55 |
#endif |
| 56 |
+#endif |
| 57 |
|
| 58 |
static int |
| 59 |
resume_one_thread_cb (struct thread_info *tp, void *data) |
| 60 |
@@ -686,7 +691,7 @@ static void |
| 61 |
fbsd_resume (struct target_ops *ops, |
| 62 |
ptid_t ptid, int step, enum gdb_signal signo) |
| 63 |
{ |
| 64 |
-#ifdef TDP_RFPPWAIT |
| 65 |
+#if defined(TDP_RFPPWAIT) && !defined(PTRACE_VFORK) |
| 66 |
pid_t pid; |
| 67 |
|
| 68 |
/* Don't PT_CONTINUE a process which has a pending vfork done event. */ |
| 69 |
@@ -731,12 +736,14 @@ fbsd_wait (struct target_ops *ops, |
| 70 |
|
| 71 |
while (1) |
| 72 |
{ |
| 73 |
+#ifndef PTRACE_VFORK |
| 74 |
wptid = fbsd_next_vfork_done (); |
| 75 |
if (!ptid_equal (wptid, null_ptid)) |
| 76 |
{ |
| 77 |
ourstatus->kind = TARGET_WAITKIND_VFORK_DONE; |
| 78 |
return wptid; |
| 79 |
} |
| 80 |
+#endif |
| 81 |
wptid = super_wait (ops, ptid, ourstatus, target_options); |
| 82 |
if (ourstatus->kind == TARGET_WAITKIND_STOPPED) |
| 83 |
{ |
| 84 |
@@ -812,12 +819,18 @@ fbsd_wait (struct target_ops *ops, |
| 85 |
#ifdef TDP_RFPPWAIT |
| 86 |
if (pl.pl_flags & PL_FLAG_FORKED) |
| 87 |
{ |
| 88 |
+#ifndef PTRACE_VFORK |
| 89 |
struct kinfo_proc kp; |
| 90 |
+#endif |
| 91 |
ptid_t child_ptid; |
| 92 |
pid_t child; |
| 93 |
|
| 94 |
child = pl.pl_child_pid; |
| 95 |
ourstatus->kind = TARGET_WAITKIND_FORKED; |
| 96 |
+#ifdef PTRACE_VFORK |
| 97 |
+ if (pl.pl_flags & PL_FLAG_VFORKED) |
| 98 |
+ ourstatus->kind = TARGET_WAITKIND_VFORKED; |
| 99 |
+#endif |
| 100 |
|
| 101 |
/* Make sure the other end of the fork is stopped too. */ |
| 102 |
child_ptid = fbsd_is_child_pending (child); |
| 103 |
@@ -839,11 +852,13 @@ fbsd_wait (struct target_ops *ops, |
| 104 |
/* Enable additional events on the child process. */ |
| 105 |
fbsd_enable_proc_events (ptid_get_pid (child_ptid)); |
| 106 |
|
| 107 |
+#ifndef PTRACE_VFORK |
| 108 |
/* For vfork, the child process will have the P_PPWAIT |
| 109 |
flag set. */ |
| 110 |
fbsd_fetch_kinfo_proc (child, &kp); |
| 111 |
if (kp.ki_flag & P_PPWAIT) |
| 112 |
ourstatus->kind = TARGET_WAITKIND_VFORKED; |
| 113 |
+#endif |
| 114 |
ourstatus->value.related_pid = child_ptid; |
| 115 |
|
| 116 |
return wptid; |
| 117 |
@@ -857,6 +872,14 @@ fbsd_wait (struct target_ops *ops, |
| 118 |
fbsd_remember_child (wptid); |
| 119 |
continue; |
| 120 |
} |
| 121 |
+ |
| 122 |
+#ifdef PTRACE_VFORK |
| 123 |
+ if (pl.pl_flags & PL_FLAG_VFORK_DONE) |
| 124 |
+ { |
| 125 |
+ ourstatus->kind = TARGET_WAITKIND_VFORK_DONE; |
| 126 |
+ return wptid; |
| 127 |
+ } |
| 128 |
+#endif |
| 129 |
#endif |
| 130 |
|
| 131 |
#ifdef PL_FLAG_EXEC |
| 132 |
@@ -918,7 +941,6 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child, |
| 133 |
if (!follow_child && detach_fork) |
| 134 |
{ |
| 135 |
struct thread_info *tp = inferior_thread (); |
| 136 |
- int has_vforked = tp->pending_follow.kind == TARGET_WAITKIND_VFORKED; |
| 137 |
pid_t child_pid = ptid_get_pid (tp->pending_follow.value.related_pid); |
| 138 |
|
| 139 |
/* Breakpoints have already been detached from the child by |
| 140 |
@@ -927,7 +949,8 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child, |
| 141 |
if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1) |
| 142 |
perror_with_name (("ptrace")); |
| 143 |
|
| 144 |
- if (has_vforked) |
| 145 |
+#ifndef PTRACE_VFORK |
| 146 |
+ if (tp->pending_follow.kind == TARGET_WAITKIND_VFORKED) |
| 147 |
{ |
| 148 |
/* We can't insert breakpoints until the child process has |
| 149 |
finished with the shared memory region. The parent |
| 150 |
@@ -953,6 +976,7 @@ fbsd_follow_fork (struct target_ops *ops, int follow_child, |
| 151 |
wait. */ |
| 152 |
fbsd_add_vfork_done (inferior_ptid); |
| 153 |
} |
| 154 |
+#endif |
| 155 |
} |
| 156 |
|
| 157 |
return 0; |