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; |