| @@ -1,1038 +1,1039 @@ | | | @@ -1,1038 +1,1039 @@ |
1 | /* $NetBSD: t_ptrace_wait.c,v 1.60 2017/01/14 19:17:10 kamil Exp $ */ | | 1 | /* $NetBSD: t_ptrace_wait.c,v 1.61 2017/01/25 17:01:57 kamil Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2016 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2016 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
15 | * | | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 16 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 17 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 18 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 19 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 20 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
26 | * POSSIBILITY OF SUCH DAMAGE. | | 26 | * POSSIBILITY OF SUCH DAMAGE. |
27 | */ | | 27 | */ |
28 | | | 28 | |
29 | #include <sys/cdefs.h> | | 29 | #include <sys/cdefs.h> |
30 | __RCSID("$NetBSD: t_ptrace_wait.c,v 1.60 2017/01/14 19:17:10 kamil Exp $"); | | 30 | __RCSID("$NetBSD: t_ptrace_wait.c,v 1.61 2017/01/25 17:01:57 kamil Exp $"); |
31 | | | 31 | |
32 | #include <sys/param.h> | | 32 | #include <sys/param.h> |
33 | #include <sys/types.h> | | 33 | #include <sys/types.h> |
34 | #include <sys/ptrace.h> | | 34 | #include <sys/ptrace.h> |
35 | #include <sys/resource.h> | | 35 | #include <sys/resource.h> |
36 | #include <sys/stat.h> | | 36 | #include <sys/stat.h> |
37 | #include <sys/sysctl.h> | | 37 | #include <sys/sysctl.h> |
38 | #include <sys/wait.h> | | 38 | #include <sys/wait.h> |
39 | #include <machine/reg.h> | | 39 | #include <machine/reg.h> |
| | | 40 | #include <elf.h> |
40 | #include <err.h> | | 41 | #include <err.h> |
41 | #include <errno.h> | | 42 | #include <errno.h> |
42 | #include <lwp.h> | | 43 | #include <lwp.h> |
43 | #include <signal.h> | | 44 | #include <signal.h> |
44 | #include <stdint.h> | | 45 | #include <stdint.h> |
45 | #include <stdio.h> | | 46 | #include <stdio.h> |
46 | #include <stdlib.h> | | 47 | #include <stdlib.h> |
47 | #include <strings.h> | | 48 | #include <strings.h> |
48 | #include <unistd.h> | | 49 | #include <unistd.h> |
49 | | | 50 | |
50 | #include <atf-c.h> | | 51 | #include <atf-c.h> |
51 | | | 52 | |
52 | #include "h_macros.h" | | 53 | #include "h_macros.h" |
53 | | | 54 | |
54 | #include "t_ptrace_wait.h" | | 55 | #include "t_ptrace_wait.h" |
55 | #include "msg.h" | | 56 | #include "msg.h" |
56 | | | 57 | |
57 | #define PARENT_TO_CHILD(info, fds, msg) \ | | 58 | #define PARENT_TO_CHILD(info, fds, msg) \ |
58 | ATF_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0) | | 59 | ATF_REQUIRE(msg_write_child(info " to child " # fds, &fds, &msg, sizeof(msg)) == 0) |
59 | | | 60 | |
60 | #define CHILD_FROM_PARENT(info, fds, msg) \ | | 61 | #define CHILD_FROM_PARENT(info, fds, msg) \ |
61 | FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0) | | 62 | FORKEE_ASSERT(msg_read_parent(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0) |
62 | | | 63 | |
63 | #define CHILD_TO_PARENT(info, fds, msg) \ | | 64 | #define CHILD_TO_PARENT(info, fds, msg) \ |
64 | FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0) | | 65 | FORKEE_ASSERT(msg_write_parent(info " to parent " # fds, &fds, &msg, sizeof(msg)) == 0) |
65 | | | 66 | |
66 | #define PARENT_FROM_CHILD(info, fds, msg) \ | | 67 | #define PARENT_FROM_CHILD(info, fds, msg) \ |
67 | ATF_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0) | | 68 | ATF_REQUIRE(msg_read_child(info " from parent " # fds, &fds, &msg, sizeof(msg)) == 0) |
68 | | | 69 | |
69 | | | 70 | |
70 | ATF_TC(traceme1); | | 71 | ATF_TC(traceme1); |
71 | ATF_TC_HEAD(traceme1, tc) | | 72 | ATF_TC_HEAD(traceme1, tc) |
72 | { | | 73 | { |
73 | atf_tc_set_md_var(tc, "descr", | | 74 | atf_tc_set_md_var(tc, "descr", |
74 | "Verify SIGSTOP followed by _exit(2) in a child"); | | 75 | "Verify SIGSTOP followed by _exit(2) in a child"); |
75 | } | | 76 | } |
76 | | | 77 | |
77 | ATF_TC_BODY(traceme1, tc) | | 78 | ATF_TC_BODY(traceme1, tc) |
78 | { | | 79 | { |
79 | const int exitval = 5; | | 80 | const int exitval = 5; |
80 | const int sigval = SIGSTOP; | | 81 | const int sigval = SIGSTOP; |
81 | pid_t child, wpid; | | 82 | pid_t child, wpid; |
82 | #if defined(TWAIT_HAVE_STATUS) | | 83 | #if defined(TWAIT_HAVE_STATUS) |
83 | int status; | | 84 | int status; |
84 | #endif | | 85 | #endif |
85 | | | 86 | |
86 | printf("Before forking process PID=%d\n", getpid()); | | 87 | printf("Before forking process PID=%d\n", getpid()); |
87 | ATF_REQUIRE((child = fork()) != -1); | | 88 | ATF_REQUIRE((child = fork()) != -1); |
88 | if (child == 0) { | | 89 | if (child == 0) { |
89 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 90 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
90 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 91 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
91 | | | 92 | |
92 | printf("Before raising %s from child\n", strsignal(sigval)); | | 93 | printf("Before raising %s from child\n", strsignal(sigval)); |
93 | FORKEE_ASSERT(raise(sigval) == 0); | | 94 | FORKEE_ASSERT(raise(sigval) == 0); |
94 | | | 95 | |
95 | printf("Before exiting of the child process\n"); | | 96 | printf("Before exiting of the child process\n"); |
96 | _exit(exitval); | | 97 | _exit(exitval); |
97 | } | | 98 | } |
98 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 99 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
99 | | | 100 | |
100 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 101 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
101 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 102 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
102 | | | 103 | |
103 | validate_status_stopped(status, sigval); | | 104 | validate_status_stopped(status, sigval); |
104 | | | 105 | |
105 | printf("Before resuming the child process where it left off and " | | 106 | printf("Before resuming the child process where it left off and " |
106 | "without signal to be sent\n"); | | 107 | "without signal to be sent\n"); |
107 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 108 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
108 | | | 109 | |
109 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 110 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
110 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 111 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
111 | | | 112 | |
112 | validate_status_exited(status, exitval); | | 113 | validate_status_exited(status, exitval); |
113 | | | 114 | |
114 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 115 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
115 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 116 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
116 | } | | 117 | } |
117 | | | 118 | |
118 | ATF_TC(traceme2); | | 119 | ATF_TC(traceme2); |
119 | ATF_TC_HEAD(traceme2, tc) | | 120 | ATF_TC_HEAD(traceme2, tc) |
120 | { | | 121 | { |
121 | atf_tc_set_md_var(tc, "descr", | | 122 | atf_tc_set_md_var(tc, "descr", |
122 | "Verify SIGSTOP followed by _exit(2) in a child"); | | 123 | "Verify SIGSTOP followed by _exit(2) in a child"); |
123 | } | | 124 | } |
124 | | | 125 | |
125 | static int traceme2_caught = 0; | | 126 | static int traceme2_caught = 0; |
126 | | | 127 | |
127 | static void | | 128 | static void |
128 | traceme2_sighandler(int sig) | | 129 | traceme2_sighandler(int sig) |
129 | { | | 130 | { |
130 | FORKEE_ASSERT_EQ(sig, SIGINT); | | 131 | FORKEE_ASSERT_EQ(sig, SIGINT); |
131 | | | 132 | |
132 | ++traceme2_caught; | | 133 | ++traceme2_caught; |
133 | } | | 134 | } |
134 | | | 135 | |
135 | ATF_TC_BODY(traceme2, tc) | | 136 | ATF_TC_BODY(traceme2, tc) |
136 | { | | 137 | { |
137 | const int exitval = 5; | | 138 | const int exitval = 5; |
138 | const int sigval = SIGSTOP, sigsent = SIGINT; | | 139 | const int sigval = SIGSTOP, sigsent = SIGINT; |
139 | pid_t child, wpid; | | 140 | pid_t child, wpid; |
140 | struct sigaction sa; | | 141 | struct sigaction sa; |
141 | #if defined(TWAIT_HAVE_STATUS) | | 142 | #if defined(TWAIT_HAVE_STATUS) |
142 | int status; | | 143 | int status; |
143 | #endif | | 144 | #endif |
144 | | | 145 | |
145 | printf("Before forking process PID=%d\n", getpid()); | | 146 | printf("Before forking process PID=%d\n", getpid()); |
146 | ATF_REQUIRE((child = fork()) != -1); | | 147 | ATF_REQUIRE((child = fork()) != -1); |
147 | if (child == 0) { | | 148 | if (child == 0) { |
148 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 149 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
149 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 150 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
150 | | | 151 | |
151 | sa.sa_handler = traceme2_sighandler; | | 152 | sa.sa_handler = traceme2_sighandler; |
152 | sa.sa_flags = SA_SIGINFO; | | 153 | sa.sa_flags = SA_SIGINFO; |
153 | sigemptyset(&sa.sa_mask); | | 154 | sigemptyset(&sa.sa_mask); |
154 | | | 155 | |
155 | FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); | | 156 | FORKEE_ASSERT(sigaction(sigsent, &sa, NULL) != -1); |
156 | | | 157 | |
157 | printf("Before raising %s from child\n", strsignal(sigval)); | | 158 | printf("Before raising %s from child\n", strsignal(sigval)); |
158 | FORKEE_ASSERT(raise(sigval) == 0); | | 159 | FORKEE_ASSERT(raise(sigval) == 0); |
159 | | | 160 | |
160 | FORKEE_ASSERT_EQ(traceme2_caught, 1); | | 161 | FORKEE_ASSERT_EQ(traceme2_caught, 1); |
161 | | | 162 | |
162 | printf("Before exiting of the child process\n"); | | 163 | printf("Before exiting of the child process\n"); |
163 | _exit(exitval); | | 164 | _exit(exitval); |
164 | } | | 165 | } |
165 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 166 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
166 | | | 167 | |
167 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 168 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
168 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 169 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
169 | | | 170 | |
170 | validate_status_stopped(status, sigval); | | 171 | validate_status_stopped(status, sigval); |
171 | | | 172 | |
172 | printf("Before resuming the child process where it left off and with " | | 173 | printf("Before resuming the child process where it left off and with " |
173 | "signal %s to be sent\n", strsignal(sigsent)); | | 174 | "signal %s to be sent\n", strsignal(sigsent)); |
174 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); | | 175 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); |
175 | | | 176 | |
176 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 177 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
177 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 178 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
178 | | | 179 | |
179 | validate_status_exited(status, exitval); | | 180 | validate_status_exited(status, exitval); |
180 | | | 181 | |
181 | printf("Before calling %s() for the exited child\n", TWAIT_FNAME); | | 182 | printf("Before calling %s() for the exited child\n", TWAIT_FNAME); |
182 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 183 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
183 | } | | 184 | } |
184 | | | 185 | |
185 | ATF_TC(traceme3); | | 186 | ATF_TC(traceme3); |
186 | ATF_TC_HEAD(traceme3, tc) | | 187 | ATF_TC_HEAD(traceme3, tc) |
187 | { | | 188 | { |
188 | atf_tc_set_md_var(tc, "descr", | | 189 | atf_tc_set_md_var(tc, "descr", |
189 | "Verify SIGSTOP followed by termination by a signal in a child"); | | 190 | "Verify SIGSTOP followed by termination by a signal in a child"); |
190 | } | | 191 | } |
191 | | | 192 | |
192 | ATF_TC_BODY(traceme3, tc) | | 193 | ATF_TC_BODY(traceme3, tc) |
193 | { | | 194 | { |
194 | const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */; | | 195 | const int sigval = SIGSTOP, sigsent = SIGINT /* Without core-dump */; |
195 | pid_t child, wpid; | | 196 | pid_t child, wpid; |
196 | #if defined(TWAIT_HAVE_STATUS) | | 197 | #if defined(TWAIT_HAVE_STATUS) |
197 | int status; | | 198 | int status; |
198 | #endif | | 199 | #endif |
199 | | | 200 | |
200 | printf("Before forking process PID=%d\n", getpid()); | | 201 | printf("Before forking process PID=%d\n", getpid()); |
201 | ATF_REQUIRE((child = fork()) != -1); | | 202 | ATF_REQUIRE((child = fork()) != -1); |
202 | if (child == 0) { | | 203 | if (child == 0) { |
203 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 204 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
204 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 205 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
205 | | | 206 | |
206 | printf("Before raising %s from child\n", strsignal(sigval)); | | 207 | printf("Before raising %s from child\n", strsignal(sigval)); |
207 | FORKEE_ASSERT(raise(sigval) == 0); | | 208 | FORKEE_ASSERT(raise(sigval) == 0); |
208 | | | 209 | |
209 | /* NOTREACHED */ | | 210 | /* NOTREACHED */ |
210 | FORKEE_ASSERTX(0 && | | 211 | FORKEE_ASSERTX(0 && |
211 | "Child should be terminated by a signal from its parent"); | | 212 | "Child should be terminated by a signal from its parent"); |
212 | } | | 213 | } |
213 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 214 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
214 | | | 215 | |
215 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 216 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
216 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 217 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
217 | | | 218 | |
218 | validate_status_stopped(status, sigval); | | 219 | validate_status_stopped(status, sigval); |
219 | | | 220 | |
220 | printf("Before resuming the child process where it left off and with " | | 221 | printf("Before resuming the child process where it left off and with " |
221 | "signal %s to be sent\n", strsignal(sigsent)); | | 222 | "signal %s to be sent\n", strsignal(sigsent)); |
222 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); | | 223 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigsent) != -1); |
223 | | | 224 | |
224 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 225 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
225 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 226 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
226 | | | 227 | |
227 | validate_status_signaled(status, sigsent, 0); | | 228 | validate_status_signaled(status, sigsent, 0); |
228 | | | 229 | |
229 | printf("Before calling %s() for the exited child\n", TWAIT_FNAME); | | 230 | printf("Before calling %s() for the exited child\n", TWAIT_FNAME); |
230 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 231 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
231 | } | | 232 | } |
232 | | | 233 | |
233 | ATF_TC(traceme4); | | 234 | ATF_TC(traceme4); |
234 | ATF_TC_HEAD(traceme4, tc) | | 235 | ATF_TC_HEAD(traceme4, tc) |
235 | { | | 236 | { |
236 | atf_tc_set_md_var(tc, "descr", | | 237 | atf_tc_set_md_var(tc, "descr", |
237 | "Verify SIGSTOP followed by SIGCONT and _exit(2) in a child"); | | 238 | "Verify SIGSTOP followed by SIGCONT and _exit(2) in a child"); |
238 | } | | 239 | } |
239 | | | 240 | |
240 | ATF_TC_BODY(traceme4, tc) | | 241 | ATF_TC_BODY(traceme4, tc) |
241 | { | | 242 | { |
242 | const int exitval = 5; | | 243 | const int exitval = 5; |
243 | const int sigval = SIGSTOP, sigsent = SIGCONT; | | 244 | const int sigval = SIGSTOP, sigsent = SIGCONT; |
244 | pid_t child, wpid; | | 245 | pid_t child, wpid; |
245 | #if defined(TWAIT_HAVE_STATUS) | | 246 | #if defined(TWAIT_HAVE_STATUS) |
246 | int status; | | 247 | int status; |
247 | #endif | | 248 | #endif |
248 | | | 249 | |
249 | printf("Before forking process PID=%d\n", getpid()); | | 250 | printf("Before forking process PID=%d\n", getpid()); |
250 | ATF_REQUIRE((child = fork()) != -1); | | 251 | ATF_REQUIRE((child = fork()) != -1); |
251 | if (child == 0) { | | 252 | if (child == 0) { |
252 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 253 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
253 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 254 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
254 | | | 255 | |
255 | printf("Before raising %s from child\n", strsignal(sigval)); | | 256 | printf("Before raising %s from child\n", strsignal(sigval)); |
256 | FORKEE_ASSERT(raise(sigval) == 0); | | 257 | FORKEE_ASSERT(raise(sigval) == 0); |
257 | | | 258 | |
258 | printf("Before raising %s from child\n", strsignal(sigsent)); | | 259 | printf("Before raising %s from child\n", strsignal(sigsent)); |
259 | FORKEE_ASSERT(raise(sigsent) == 0); | | 260 | FORKEE_ASSERT(raise(sigsent) == 0); |
260 | | | 261 | |
261 | printf("Before exiting of the child process\n"); | | 262 | printf("Before exiting of the child process\n"); |
262 | _exit(exitval); | | 263 | _exit(exitval); |
263 | } | | 264 | } |
264 | printf("Parent process PID=%d, child's PID=%d\n", getpid(),child); | | 265 | printf("Parent process PID=%d, child's PID=%d\n", getpid(),child); |
265 | | | 266 | |
266 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 267 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
267 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 268 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
268 | | | 269 | |
269 | validate_status_stopped(status, sigval); | | 270 | validate_status_stopped(status, sigval); |
270 | | | 271 | |
271 | printf("Before resuming the child process where it left off and " | | 272 | printf("Before resuming the child process where it left off and " |
272 | "without signal to be sent\n"); | | 273 | "without signal to be sent\n"); |
273 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 274 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
274 | | | 275 | |
275 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 276 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
276 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 277 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
277 | | | 278 | |
278 | validate_status_stopped(status, sigsent); | | 279 | validate_status_stopped(status, sigsent); |
279 | | | 280 | |
280 | printf("Before resuming the child process where it left off and " | | 281 | printf("Before resuming the child process where it left off and " |
281 | "without signal to be sent\n"); | | 282 | "without signal to be sent\n"); |
282 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 283 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
283 | | | 284 | |
284 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 285 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
285 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 286 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
286 | | | 287 | |
287 | validate_status_exited(status, exitval); | | 288 | validate_status_exited(status, exitval); |
288 | | | 289 | |
289 | printf("Before calling %s() for the exited child\n", TWAIT_FNAME); | | 290 | printf("Before calling %s() for the exited child\n", TWAIT_FNAME); |
290 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 291 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
291 | } | | 292 | } |
292 | | | 293 | |
293 | #if defined(TWAIT_HAVE_PID) | | 294 | #if defined(TWAIT_HAVE_PID) |
294 | ATF_TC(attach1); | | 295 | ATF_TC(attach1); |
295 | ATF_TC_HEAD(attach1, tc) | | 296 | ATF_TC_HEAD(attach1, tc) |
296 | { | | 297 | { |
297 | atf_tc_set_md_var(tc, "descr", | | 298 | atf_tc_set_md_var(tc, "descr", |
298 | "Assert that tracer sees process termination before the parent"); | | 299 | "Assert that tracer sees process termination before the parent"); |
299 | } | | 300 | } |
300 | | | 301 | |
301 | ATF_TC_BODY(attach1, tc) | | 302 | ATF_TC_BODY(attach1, tc) |
302 | { | | 303 | { |
303 | struct msg_fds parent_tracee, parent_tracer; | | 304 | struct msg_fds parent_tracee, parent_tracer; |
304 | const int exitval_tracee = 5; | | 305 | const int exitval_tracee = 5; |
305 | const int exitval_tracer = 10; | | 306 | const int exitval_tracer = 10; |
306 | pid_t tracee, tracer, wpid; | | 307 | pid_t tracee, tracer, wpid; |
307 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ | | 308 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ |
308 | #if defined(TWAIT_HAVE_STATUS) | | 309 | #if defined(TWAIT_HAVE_STATUS) |
309 | int status; | | 310 | int status; |
310 | #endif | | 311 | #endif |
311 | | | 312 | |
312 | printf("Spawn tracee\n"); | | 313 | printf("Spawn tracee\n"); |
313 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); | | 314 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); |
314 | tracee = atf_utils_fork(); | | 315 | tracee = atf_utils_fork(); |
315 | if (tracee == 0) { | | 316 | if (tracee == 0) { |
316 | // Wait for parent to let us exit | | 317 | // Wait for parent to let us exit |
317 | CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); | | 318 | CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); |
318 | _exit(exitval_tracee); | | 319 | _exit(exitval_tracee); |
319 | } | | 320 | } |
320 | | | 321 | |
321 | printf("Spawn debugger\n"); | | 322 | printf("Spawn debugger\n"); |
322 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); | | 323 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); |
323 | tracer = atf_utils_fork(); | | 324 | tracer = atf_utils_fork(); |
324 | if (tracer == 0) { | | 325 | if (tracer == 0) { |
325 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); | | 326 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); |
326 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); | | 327 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); |
327 | | | 328 | |
328 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ | | 329 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ |
329 | FORKEE_REQUIRE_SUCCESS( | | 330 | FORKEE_REQUIRE_SUCCESS( |
330 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 331 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
331 | | | 332 | |
332 | forkee_status_stopped(status, SIGSTOP); | | 333 | forkee_status_stopped(status, SIGSTOP); |
333 | | | 334 | |
334 | /* Resume tracee with PT_CONTINUE */ | | 335 | /* Resume tracee with PT_CONTINUE */ |
335 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); | | 336 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); |
336 | | | 337 | |
337 | /* Inform parent that tracer has attached to tracee */ | | 338 | /* Inform parent that tracer has attached to tracee */ |
338 | CHILD_TO_PARENT("tracer ready", parent_tracer, msg); | | 339 | CHILD_TO_PARENT("tracer ready", parent_tracer, msg); |
339 | | | 340 | |
340 | /* Wait for parent to tell use that tracee should have exited */ | | 341 | /* Wait for parent to tell use that tracee should have exited */ |
341 | CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); | | 342 | CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); |
342 | | | 343 | |
343 | /* Wait for tracee and assert that it exited */ | | 344 | /* Wait for tracee and assert that it exited */ |
344 | FORKEE_REQUIRE_SUCCESS( | | 345 | FORKEE_REQUIRE_SUCCESS( |
345 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 346 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
346 | | | 347 | |
347 | forkee_status_exited(status, exitval_tracee); | | 348 | forkee_status_exited(status, exitval_tracee); |
348 | printf("Tracee %d exited with %d\n", tracee, exitval_tracee); | | 349 | printf("Tracee %d exited with %d\n", tracee, exitval_tracee); |
349 | | | 350 | |
350 | printf("Before exiting of the tracer process\n"); | | 351 | printf("Before exiting of the tracer process\n"); |
351 | _exit(exitval_tracer); | | 352 | _exit(exitval_tracer); |
352 | } | | 353 | } |
353 | | | 354 | |
354 | printf("Wait for the tracer to attach to the tracee\n"); | | 355 | printf("Wait for the tracer to attach to the tracee\n"); |
355 | PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); | | 356 | PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); |
356 | | | 357 | |
357 | printf("Resume the tracee and let it exit\n"); | | 358 | printf("Resume the tracee and let it exit\n"); |
358 | PARENT_TO_CHILD("exit tracee", parent_tracee, msg); | | 359 | PARENT_TO_CHILD("exit tracee", parent_tracee, msg); |
359 | | | 360 | |
360 | printf("Detect that tracee is zombie\n"); | | 361 | printf("Detect that tracee is zombie\n"); |
361 | await_zombie(tracee); | | 362 | await_zombie(tracee); |
362 | | | 363 | |
363 | | | 364 | |
364 | printf("Assert that there is no status about tracee %d - " | | 365 | printf("Assert that there is no status about tracee %d - " |
365 | "Tracer must detect zombie first - calling %s()\n", tracee, | | 366 | "Tracer must detect zombie first - calling %s()\n", tracee, |
366 | TWAIT_FNAME); | | 367 | TWAIT_FNAME); |
367 | TWAIT_REQUIRE_SUCCESS( | | 368 | TWAIT_REQUIRE_SUCCESS( |
368 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); | | 369 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); |
369 | | | 370 | |
370 | printf("Tell the tracer child should have exited\n"); | | 371 | printf("Tell the tracer child should have exited\n"); |
371 | PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); | | 372 | PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); |
372 | printf("Wait for tracer to finish its job and exit - calling %s()\n", | | 373 | printf("Wait for tracer to finish its job and exit - calling %s()\n", |
373 | TWAIT_FNAME); | | 374 | TWAIT_FNAME); |
374 | | | 375 | |
375 | printf("Wait from tracer child to complete waiting for tracee\n"); | | 376 | printf("Wait from tracer child to complete waiting for tracee\n"); |
376 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), | | 377 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), |
377 | tracer); | | 378 | tracer); |
378 | | | 379 | |
379 | validate_status_exited(status, exitval_tracer); | | 380 | validate_status_exited(status, exitval_tracer); |
380 | | | 381 | |
381 | printf("Wait for tracee to finish its job and exit - calling %s()\n", | | 382 | printf("Wait for tracee to finish its job and exit - calling %s()\n", |
382 | TWAIT_FNAME); | | 383 | TWAIT_FNAME); |
383 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), | | 384 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), |
384 | tracee); | | 385 | tracee); |
385 | | | 386 | |
386 | validate_status_exited(status, exitval_tracee); | | 387 | validate_status_exited(status, exitval_tracee); |
387 | | | 388 | |
388 | msg_close(&parent_tracer); | | 389 | msg_close(&parent_tracer); |
389 | msg_close(&parent_tracee); | | 390 | msg_close(&parent_tracee); |
390 | } | | 391 | } |
391 | #endif | | 392 | #endif |
392 | | | 393 | |
393 | #if defined(TWAIT_HAVE_PID) | | 394 | #if defined(TWAIT_HAVE_PID) |
394 | ATF_TC(attach2); | | 395 | ATF_TC(attach2); |
395 | ATF_TC_HEAD(attach2, tc) | | 396 | ATF_TC_HEAD(attach2, tc) |
396 | { | | 397 | { |
397 | atf_tc_set_md_var(tc, "descr", | | 398 | atf_tc_set_md_var(tc, "descr", |
398 | "Assert that any tracer sees process termination before its " | | 399 | "Assert that any tracer sees process termination before its " |
399 | "parent"); | | 400 | "parent"); |
400 | } | | 401 | } |
401 | | | 402 | |
402 | ATF_TC_BODY(attach2, tc) | | 403 | ATF_TC_BODY(attach2, tc) |
403 | { | | 404 | { |
404 | struct msg_fds parent_tracer, parent_tracee; | | 405 | struct msg_fds parent_tracer, parent_tracee; |
405 | const int exitval_tracee = 5; | | 406 | const int exitval_tracee = 5; |
406 | const int exitval_tracer1 = 10, exitval_tracer2 = 20; | | 407 | const int exitval_tracer1 = 10, exitval_tracer2 = 20; |
407 | pid_t tracee, tracer, wpid; | | 408 | pid_t tracee, tracer, wpid; |
408 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ | | 409 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ |
409 | #if defined(TWAIT_HAVE_STATUS) | | 410 | #if defined(TWAIT_HAVE_STATUS) |
410 | int status; | | 411 | int status; |
411 | #endif | | 412 | #endif |
412 | | | 413 | |
413 | printf("Spawn tracee\n"); | | 414 | printf("Spawn tracee\n"); |
414 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); | | 415 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); |
415 | tracee = atf_utils_fork(); | | 416 | tracee = atf_utils_fork(); |
416 | if (tracee == 0) { | | 417 | if (tracee == 0) { |
417 | /* Wait for message from the parent */ | | 418 | /* Wait for message from the parent */ |
418 | CHILD_FROM_PARENT("Message 1", parent_tracee, msg); | | 419 | CHILD_FROM_PARENT("Message 1", parent_tracee, msg); |
419 | _exit(exitval_tracee); | | 420 | _exit(exitval_tracee); |
420 | } | | 421 | } |
421 | | | 422 | |
422 | printf("Spawn debugger\n"); | | 423 | printf("Spawn debugger\n"); |
423 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); | | 424 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); |
424 | tracer = atf_utils_fork(); | | 425 | tracer = atf_utils_fork(); |
425 | if (tracer == 0) { | | 426 | if (tracer == 0) { |
426 | /* Fork again and drop parent to reattach to PID 1 */ | | 427 | /* Fork again and drop parent to reattach to PID 1 */ |
427 | tracer = atf_utils_fork(); | | 428 | tracer = atf_utils_fork(); |
428 | if (tracer != 0) | | 429 | if (tracer != 0) |
429 | _exit(exitval_tracer1); | | 430 | _exit(exitval_tracer1); |
430 | | | 431 | |
431 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); | | 432 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); |
432 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); | | 433 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); |
433 | | | 434 | |
434 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ | | 435 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ |
435 | FORKEE_REQUIRE_SUCCESS( | | 436 | FORKEE_REQUIRE_SUCCESS( |
436 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 437 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
437 | | | 438 | |
438 | forkee_status_stopped(status, SIGSTOP); | | 439 | forkee_status_stopped(status, SIGSTOP); |
439 | | | 440 | |
440 | /* Resume tracee with PT_CONTINUE */ | | 441 | /* Resume tracee with PT_CONTINUE */ |
441 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); | | 442 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); |
442 | | | 443 | |
443 | /* Inform parent that tracer has attached to tracee */ | | 444 | /* Inform parent that tracer has attached to tracee */ |
444 | CHILD_TO_PARENT("Message 1", parent_tracer, msg); | | 445 | CHILD_TO_PARENT("Message 1", parent_tracer, msg); |
445 | CHILD_FROM_PARENT("Message 2", parent_tracer, msg); | | 446 | CHILD_FROM_PARENT("Message 2", parent_tracer, msg); |
446 | | | 447 | |
447 | /* Wait for tracee and assert that it exited */ | | 448 | /* Wait for tracee and assert that it exited */ |
448 | FORKEE_REQUIRE_SUCCESS( | | 449 | FORKEE_REQUIRE_SUCCESS( |
449 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 450 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
450 | | | 451 | |
451 | forkee_status_exited(status, exitval_tracee); | | 452 | forkee_status_exited(status, exitval_tracee); |
452 | | | 453 | |
453 | printf("Before exiting of the tracer process\n"); | | 454 | printf("Before exiting of the tracer process\n"); |
454 | _exit(exitval_tracer2); | | 455 | _exit(exitval_tracer2); |
455 | } | | 456 | } |
456 | printf("Wait for the tracer process (direct child) to exit calling " | | 457 | printf("Wait for the tracer process (direct child) to exit calling " |
457 | "%s()\n", TWAIT_FNAME); | | 458 | "%s()\n", TWAIT_FNAME); |
458 | TWAIT_REQUIRE_SUCCESS( | | 459 | TWAIT_REQUIRE_SUCCESS( |
459 | wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); | | 460 | wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); |
460 | | | 461 | |
461 | validate_status_exited(status, exitval_tracer1); | | 462 | validate_status_exited(status, exitval_tracer1); |
462 | | | 463 | |
463 | printf("Wait for the non-exited tracee process with %s()\n", | | 464 | printf("Wait for the non-exited tracee process with %s()\n", |
464 | TWAIT_FNAME); | | 465 | TWAIT_FNAME); |
465 | TWAIT_REQUIRE_SUCCESS( | | 466 | TWAIT_REQUIRE_SUCCESS( |
466 | wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); | | 467 | wpid = TWAIT_GENERIC(tracee, NULL, WNOHANG), 0); |
467 | | | 468 | |
468 | printf("Wait for the tracer to attach to the tracee\n"); | | 469 | printf("Wait for the tracer to attach to the tracee\n"); |
469 | PARENT_FROM_CHILD("Message 1", parent_tracer, msg); | | 470 | PARENT_FROM_CHILD("Message 1", parent_tracer, msg); |
470 | printf("Resume the tracee and let it exit\n"); | | 471 | printf("Resume the tracee and let it exit\n"); |
471 | PARENT_TO_CHILD("Message 1", parent_tracee, msg); | | 472 | PARENT_TO_CHILD("Message 1", parent_tracee, msg); |
472 | | | 473 | |
473 | printf("Detect that tracee is zombie\n"); | | 474 | printf("Detect that tracee is zombie\n"); |
474 | await_zombie(tracee); | | 475 | await_zombie(tracee); |
475 | | | 476 | |
476 | printf("Assert that there is no status about tracee - " | | 477 | printf("Assert that there is no status about tracee - " |
477 | "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); | | 478 | "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); |
478 | TWAIT_REQUIRE_SUCCESS( | | 479 | TWAIT_REQUIRE_SUCCESS( |
479 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); | | 480 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); |
480 | | | 481 | |
481 | printf("Resume the tracer and let it detect exited tracee\n"); | | 482 | printf("Resume the tracer and let it detect exited tracee\n"); |
482 | PARENT_TO_CHILD("Message 2", parent_tracer, msg); | | 483 | PARENT_TO_CHILD("Message 2", parent_tracer, msg); |
483 | | | 484 | |
484 | printf("Wait for tracee to finish its job and exit - calling %s()\n", | | 485 | printf("Wait for tracee to finish its job and exit - calling %s()\n", |
485 | TWAIT_FNAME); | | 486 | TWAIT_FNAME); |
486 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), | | 487 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), |
487 | tracee); | | 488 | tracee); |
488 | | | 489 | |
489 | validate_status_exited(status, exitval_tracee); | | 490 | validate_status_exited(status, exitval_tracee); |
490 | | | 491 | |
491 | msg_close(&parent_tracer); | | 492 | msg_close(&parent_tracer); |
492 | msg_close(&parent_tracee); | | 493 | msg_close(&parent_tracee); |
493 | | | 494 | |
494 | } | | 495 | } |
495 | #endif | | 496 | #endif |
496 | | | 497 | |
497 | ATF_TC(attach3); | | 498 | ATF_TC(attach3); |
498 | ATF_TC_HEAD(attach3, tc) | | 499 | ATF_TC_HEAD(attach3, tc) |
499 | { | | 500 | { |
500 | atf_tc_set_md_var(tc, "descr", | | 501 | atf_tc_set_md_var(tc, "descr", |
501 | "Assert that tracer parent can PT_ATTACH to its child"); | | 502 | "Assert that tracer parent can PT_ATTACH to its child"); |
502 | } | | 503 | } |
503 | | | 504 | |
504 | ATF_TC_BODY(attach3, tc) | | 505 | ATF_TC_BODY(attach3, tc) |
505 | { | | 506 | { |
506 | struct msg_fds parent_tracee; | | 507 | struct msg_fds parent_tracee; |
507 | const int exitval_tracee = 5; | | 508 | const int exitval_tracee = 5; |
508 | pid_t tracee, wpid; | | 509 | pid_t tracee, wpid; |
509 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ | | 510 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ |
510 | #if defined(TWAIT_HAVE_STATUS) | | 511 | #if defined(TWAIT_HAVE_STATUS) |
511 | int status; | | 512 | int status; |
512 | #endif | | 513 | #endif |
513 | | | 514 | |
514 | printf("Spawn tracee\n"); | | 515 | printf("Spawn tracee\n"); |
515 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); | | 516 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); |
516 | tracee = atf_utils_fork(); | | 517 | tracee = atf_utils_fork(); |
517 | if (tracee == 0) { | | 518 | if (tracee == 0) { |
518 | CHILD_FROM_PARENT("Message 1", parent_tracee, msg); | | 519 | CHILD_FROM_PARENT("Message 1", parent_tracee, msg); |
519 | printf("Parent should now attach to tracee\n"); | | 520 | printf("Parent should now attach to tracee\n"); |
520 | | | 521 | |
521 | CHILD_FROM_PARENT("Message 2", parent_tracee, msg); | | 522 | CHILD_FROM_PARENT("Message 2", parent_tracee, msg); |
522 | /* Wait for message from the parent */ | | 523 | /* Wait for message from the parent */ |
523 | _exit(exitval_tracee); | | 524 | _exit(exitval_tracee); |
524 | } | | 525 | } |
525 | PARENT_TO_CHILD("Message 1", parent_tracee, msg); | | 526 | PARENT_TO_CHILD("Message 1", parent_tracee, msg); |
526 | | | 527 | |
527 | printf("Before calling PT_ATTACH for tracee %d\n", tracee); | | 528 | printf("Before calling PT_ATTACH for tracee %d\n", tracee); |
528 | ATF_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); | | 529 | ATF_REQUIRE(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); |
529 | | | 530 | |
530 | printf("Wait for the stopped tracee process with %s()\n", | | 531 | printf("Wait for the stopped tracee process with %s()\n", |
531 | TWAIT_FNAME); | | 532 | TWAIT_FNAME); |
532 | TWAIT_REQUIRE_SUCCESS( | | 533 | TWAIT_REQUIRE_SUCCESS( |
533 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 534 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
534 | | | 535 | |
535 | validate_status_stopped(status, SIGSTOP); | | 536 | validate_status_stopped(status, SIGSTOP); |
536 | | | 537 | |
537 | printf("Resume tracee with PT_CONTINUE\n"); | | 538 | printf("Resume tracee with PT_CONTINUE\n"); |
538 | ATF_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); | | 539 | ATF_REQUIRE(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); |
539 | | | 540 | |
540 | printf("Let the tracee exit now\n"); | | 541 | printf("Let the tracee exit now\n"); |
541 | PARENT_TO_CHILD("Message 2", parent_tracee, msg); | | 542 | PARENT_TO_CHILD("Message 2", parent_tracee, msg); |
542 | | | 543 | |
543 | printf("Wait for tracee to exit with %s()\n", TWAIT_FNAME); | | 544 | printf("Wait for tracee to exit with %s()\n", TWAIT_FNAME); |
544 | TWAIT_REQUIRE_SUCCESS( | | 545 | TWAIT_REQUIRE_SUCCESS( |
545 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 546 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
546 | | | 547 | |
547 | validate_status_exited(status, exitval_tracee); | | 548 | validate_status_exited(status, exitval_tracee); |
548 | | | 549 | |
549 | printf("Before calling %s() for tracee\n", TWAIT_FNAME); | | 550 | printf("Before calling %s() for tracee\n", TWAIT_FNAME); |
550 | TWAIT_REQUIRE_FAILURE(ECHILD, | | 551 | TWAIT_REQUIRE_FAILURE(ECHILD, |
551 | wpid = TWAIT_GENERIC(tracee, &status, 0)); | | 552 | wpid = TWAIT_GENERIC(tracee, &status, 0)); |
552 | | | 553 | |
553 | msg_close(&parent_tracee); | | 554 | msg_close(&parent_tracee); |
554 | } | | 555 | } |
555 | | | 556 | |
556 | ATF_TC(attach4); | | 557 | ATF_TC(attach4); |
557 | ATF_TC_HEAD(attach4, tc) | | 558 | ATF_TC_HEAD(attach4, tc) |
558 | { | | 559 | { |
559 | atf_tc_set_md_var(tc, "descr", | | 560 | atf_tc_set_md_var(tc, "descr", |
560 | "Assert that tracer child can PT_ATTACH to its parent"); | | 561 | "Assert that tracer child can PT_ATTACH to its parent"); |
561 | } | | 562 | } |
562 | | | 563 | |
563 | ATF_TC_BODY(attach4, tc) | | 564 | ATF_TC_BODY(attach4, tc) |
564 | { | | 565 | { |
565 | struct msg_fds parent_tracee; | | 566 | struct msg_fds parent_tracee; |
566 | const int exitval_tracer = 5; | | 567 | const int exitval_tracer = 5; |
567 | pid_t tracer, wpid; | | 568 | pid_t tracer, wpid; |
568 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ | | 569 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ |
569 | #if defined(TWAIT_HAVE_STATUS) | | 570 | #if defined(TWAIT_HAVE_STATUS) |
570 | int status; | | 571 | int status; |
571 | #endif | | 572 | #endif |
572 | | | 573 | |
573 | printf("Spawn tracer\n"); | | 574 | printf("Spawn tracer\n"); |
574 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); | | 575 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); |
575 | tracer = atf_utils_fork(); | | 576 | tracer = atf_utils_fork(); |
576 | if (tracer == 0) { | | 577 | if (tracer == 0) { |
577 | | | 578 | |
578 | /* Wait for message from the parent */ | | 579 | /* Wait for message from the parent */ |
579 | CHILD_FROM_PARENT("Message 1", parent_tracee, msg); | | 580 | CHILD_FROM_PARENT("Message 1", parent_tracee, msg); |
580 | | | 581 | |
581 | printf("Attach to parent PID %d with PT_ATTACH from child\n", | | 582 | printf("Attach to parent PID %d with PT_ATTACH from child\n", |
582 | getppid()); | | 583 | getppid()); |
583 | FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); | | 584 | FORKEE_ASSERT(ptrace(PT_ATTACH, getppid(), NULL, 0) != -1); |
584 | | | 585 | |
585 | printf("Wait for the stopped parent process with %s()\n", | | 586 | printf("Wait for the stopped parent process with %s()\n", |
586 | TWAIT_FNAME); | | 587 | TWAIT_FNAME); |
587 | FORKEE_REQUIRE_SUCCESS( | | 588 | FORKEE_REQUIRE_SUCCESS( |
588 | wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); | | 589 | wpid = TWAIT_GENERIC(getppid(), &status, 0), getppid()); |
589 | | | 590 | |
590 | forkee_status_stopped(status, SIGSTOP); | | 591 | forkee_status_stopped(status, SIGSTOP); |
591 | | | 592 | |
592 | printf("Resume parent with PT_DETACH\n"); | | 593 | printf("Resume parent with PT_DETACH\n"); |
593 | FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) | | 594 | FORKEE_ASSERT(ptrace(PT_DETACH, getppid(), (void *)1, 0) |
594 | != -1); | | 595 | != -1); |
595 | | | 596 | |
596 | /* Tell parent we are ready */ | | 597 | /* Tell parent we are ready */ |
597 | CHILD_TO_PARENT("Message 1", parent_tracee, msg); | | 598 | CHILD_TO_PARENT("Message 1", parent_tracee, msg); |
598 | | | 599 | |
599 | _exit(exitval_tracer); | | 600 | _exit(exitval_tracer); |
600 | } | | 601 | } |
601 | | | 602 | |
602 | printf("Wait for the tracer to become ready\n"); | | 603 | printf("Wait for the tracer to become ready\n"); |
603 | PARENT_TO_CHILD("Message 1", parent_tracee, msg); | | 604 | PARENT_TO_CHILD("Message 1", parent_tracee, msg); |
604 | printf("Allow the tracer to exit now\n"); | | 605 | printf("Allow the tracer to exit now\n"); |
605 | PARENT_FROM_CHILD("Message 1", parent_tracee, msg); | | 606 | PARENT_FROM_CHILD("Message 1", parent_tracee, msg); |
606 | | | 607 | |
607 | printf("Wait for tracer to exit with %s()\n", TWAIT_FNAME); | | 608 | printf("Wait for tracer to exit with %s()\n", TWAIT_FNAME); |
608 | TWAIT_REQUIRE_SUCCESS( | | 609 | TWAIT_REQUIRE_SUCCESS( |
609 | wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); | | 610 | wpid = TWAIT_GENERIC(tracer, &status, 0), tracer); |
610 | | | 611 | |
611 | validate_status_exited(status, exitval_tracer); | | 612 | validate_status_exited(status, exitval_tracer); |
612 | | | 613 | |
613 | printf("Before calling %s() for tracer\n", TWAIT_FNAME); | | 614 | printf("Before calling %s() for tracer\n", TWAIT_FNAME); |
614 | TWAIT_REQUIRE_FAILURE(ECHILD, | | 615 | TWAIT_REQUIRE_FAILURE(ECHILD, |
615 | wpid = TWAIT_GENERIC(tracer, &status, 0)); | | 616 | wpid = TWAIT_GENERIC(tracer, &status, 0)); |
616 | | | 617 | |
617 | msg_close(&parent_tracee); | | 618 | msg_close(&parent_tracee); |
618 | } | | 619 | } |
619 | | | 620 | |
620 | #if defined(TWAIT_HAVE_PID) | | 621 | #if defined(TWAIT_HAVE_PID) |
621 | ATF_TC(attach5); | | 622 | ATF_TC(attach5); |
622 | ATF_TC_HEAD(attach5, tc) | | 623 | ATF_TC_HEAD(attach5, tc) |
623 | { | | 624 | { |
624 | atf_tc_set_md_var(tc, "descr", | | 625 | atf_tc_set_md_var(tc, "descr", |
625 | "Assert that tracer sees its parent when attached to tracer " | | 626 | "Assert that tracer sees its parent when attached to tracer " |
626 | "(check getppid(2))"); | | 627 | "(check getppid(2))"); |
627 | } | | 628 | } |
628 | | | 629 | |
629 | ATF_TC_BODY(attach5, tc) | | 630 | ATF_TC_BODY(attach5, tc) |
630 | { | | 631 | { |
631 | struct msg_fds parent_tracer, parent_tracee; | | 632 | struct msg_fds parent_tracer, parent_tracee; |
632 | const int exitval_tracee = 5; | | 633 | const int exitval_tracee = 5; |
633 | const int exitval_tracer = 10; | | 634 | const int exitval_tracer = 10; |
634 | pid_t parent, tracee, tracer, wpid; | | 635 | pid_t parent, tracee, tracer, wpid; |
635 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ | | 636 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ |
636 | #if defined(TWAIT_HAVE_STATUS) | | 637 | #if defined(TWAIT_HAVE_STATUS) |
637 | int status; | | 638 | int status; |
638 | #endif | | 639 | #endif |
639 | | | 640 | |
640 | printf("Spawn tracee\n"); | | 641 | printf("Spawn tracee\n"); |
641 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); | | 642 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); |
642 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); | | 643 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); |
643 | tracee = atf_utils_fork(); | | 644 | tracee = atf_utils_fork(); |
644 | if (tracee == 0) { | | 645 | if (tracee == 0) { |
645 | parent = getppid(); | | 646 | parent = getppid(); |
646 | | | 647 | |
647 | /* Emit message to the parent */ | | 648 | /* Emit message to the parent */ |
648 | CHILD_TO_PARENT("tracee ready", parent_tracee, msg); | | 649 | CHILD_TO_PARENT("tracee ready", parent_tracee, msg); |
649 | CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); | | 650 | CHILD_FROM_PARENT("exit tracee", parent_tracee, msg); |
650 | | | 651 | |
651 | FORKEE_ASSERT_EQ(parent, getppid()); | | 652 | FORKEE_ASSERT_EQ(parent, getppid()); |
652 | | | 653 | |
653 | _exit(exitval_tracee); | | 654 | _exit(exitval_tracee); |
654 | } | | 655 | } |
655 | printf("Wait for child to record its parent identifier (pid)\n"); | | 656 | printf("Wait for child to record its parent identifier (pid)\n"); |
656 | PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); | | 657 | PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); |
657 | | | 658 | |
658 | printf("Spawn debugger\n"); | | 659 | printf("Spawn debugger\n"); |
659 | tracer = atf_utils_fork(); | | 660 | tracer = atf_utils_fork(); |
660 | if (tracer == 0) { | | 661 | if (tracer == 0) { |
661 | /* No IPC to communicate with the child */ | | 662 | /* No IPC to communicate with the child */ |
662 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); | | 663 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); |
663 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); | | 664 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); |
664 | | | 665 | |
665 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ | | 666 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ |
666 | FORKEE_REQUIRE_SUCCESS( | | 667 | FORKEE_REQUIRE_SUCCESS( |
667 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 668 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
668 | | | 669 | |
669 | forkee_status_stopped(status, SIGSTOP); | | 670 | forkee_status_stopped(status, SIGSTOP); |
670 | | | 671 | |
671 | /* Resume tracee with PT_CONTINUE */ | | 672 | /* Resume tracee with PT_CONTINUE */ |
672 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); | | 673 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); |
673 | | | 674 | |
674 | /* Inform parent that tracer has attached to tracee */ | | 675 | /* Inform parent that tracer has attached to tracee */ |
675 | CHILD_TO_PARENT("tracer ready", parent_tracer, msg); | | 676 | CHILD_TO_PARENT("tracer ready", parent_tracer, msg); |
676 | | | 677 | |
677 | /* Wait for parent to tell use that tracee should have exited */ | | 678 | /* Wait for parent to tell use that tracee should have exited */ |
678 | CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); | | 679 | CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); |
679 | | | 680 | |
680 | /* Wait for tracee and assert that it exited */ | | 681 | /* Wait for tracee and assert that it exited */ |
681 | FORKEE_REQUIRE_SUCCESS( | | 682 | FORKEE_REQUIRE_SUCCESS( |
682 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 683 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
683 | | | 684 | |
684 | forkee_status_exited(status, exitval_tracee); | | 685 | forkee_status_exited(status, exitval_tracee); |
685 | | | 686 | |
686 | printf("Before exiting of the tracer process\n"); | | 687 | printf("Before exiting of the tracer process\n"); |
687 | _exit(exitval_tracer); | | 688 | _exit(exitval_tracer); |
688 | } | | 689 | } |
689 | | | 690 | |
690 | printf("Wait for the tracer to attach to the tracee\n"); | | 691 | printf("Wait for the tracer to attach to the tracee\n"); |
691 | PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); | | 692 | PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); |
692 | | | 693 | |
693 | printf("Resume the tracee and let it exit\n"); | | 694 | printf("Resume the tracee and let it exit\n"); |
694 | PARENT_TO_CHILD("exit tracee", parent_tracee, msg); | | 695 | PARENT_TO_CHILD("exit tracee", parent_tracee, msg); |
695 | | | 696 | |
696 | printf("Detect that tracee is zombie\n"); | | 697 | printf("Detect that tracee is zombie\n"); |
697 | await_zombie(tracee); | | 698 | await_zombie(tracee); |
698 | | | 699 | |
699 | printf("Assert that there is no status about tracee - " | | 700 | printf("Assert that there is no status about tracee - " |
700 | "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); | | 701 | "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); |
701 | TWAIT_REQUIRE_SUCCESS( | | 702 | TWAIT_REQUIRE_SUCCESS( |
702 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); | | 703 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); |
703 | | | 704 | |
704 | printf("Tell the tracer child should have exited\n"); | | 705 | printf("Tell the tracer child should have exited\n"); |
705 | PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); | | 706 | PARENT_TO_CHILD("wait for tracee exit", parent_tracer, msg); |
706 | | | 707 | |
707 | printf("Wait from tracer child to complete waiting for tracee\n"); | | 708 | printf("Wait from tracer child to complete waiting for tracee\n"); |
708 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), | | 709 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), |
709 | tracer); | | 710 | tracer); |
710 | | | 711 | |
711 | validate_status_exited(status, exitval_tracer); | | 712 | validate_status_exited(status, exitval_tracer); |
712 | | | 713 | |
713 | printf("Wait for tracee to finish its job and exit - calling %s()\n", | | 714 | printf("Wait for tracee to finish its job and exit - calling %s()\n", |
714 | TWAIT_FNAME); | | 715 | TWAIT_FNAME); |
715 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), | | 716 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), |
716 | tracee); | | 717 | tracee); |
717 | | | 718 | |
718 | validate_status_exited(status, exitval_tracee); | | 719 | validate_status_exited(status, exitval_tracee); |
719 | | | 720 | |
720 | msg_close(&parent_tracer); | | 721 | msg_close(&parent_tracer); |
721 | msg_close(&parent_tracee); | | 722 | msg_close(&parent_tracee); |
722 | } | | 723 | } |
723 | #endif | | 724 | #endif |
724 | | | 725 | |
725 | #if defined(TWAIT_HAVE_PID) | | 726 | #if defined(TWAIT_HAVE_PID) |
726 | ATF_TC(attach6); | | 727 | ATF_TC(attach6); |
727 | ATF_TC_HEAD(attach6, tc) | | 728 | ATF_TC_HEAD(attach6, tc) |
728 | { | | 729 | { |
729 | atf_tc_set_md_var(tc, "descr", | | 730 | atf_tc_set_md_var(tc, "descr", |
730 | "Assert that tracer sees its parent when attached to tracer " | | 731 | "Assert that tracer sees its parent when attached to tracer " |
731 | "(check sysctl(7) and struct kinfo_proc2)"); | | 732 | "(check sysctl(7) and struct kinfo_proc2)"); |
732 | } | | 733 | } |
733 | | | 734 | |
734 | ATF_TC_BODY(attach6, tc) | | 735 | ATF_TC_BODY(attach6, tc) |
735 | { | | 736 | { |
736 | struct msg_fds parent_tracee, parent_tracer; | | 737 | struct msg_fds parent_tracee, parent_tracer; |
737 | const int exitval_tracee = 5; | | 738 | const int exitval_tracee = 5; |
738 | const int exitval_tracer = 10; | | 739 | const int exitval_tracer = 10; |
739 | pid_t parent, tracee, tracer, wpid; | | 740 | pid_t parent, tracee, tracer, wpid; |
740 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ | | 741 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ |
741 | #if defined(TWAIT_HAVE_STATUS) | | 742 | #if defined(TWAIT_HAVE_STATUS) |
742 | int status; | | 743 | int status; |
743 | #endif | | 744 | #endif |
744 | int name[CTL_MAXNAME]; | | 745 | int name[CTL_MAXNAME]; |
745 | struct kinfo_proc2 kp; | | 746 | struct kinfo_proc2 kp; |
746 | size_t len = sizeof(kp); | | 747 | size_t len = sizeof(kp); |
747 | unsigned int namelen; | | 748 | unsigned int namelen; |
748 | | | 749 | |
749 | printf("Spawn tracee\n"); | | 750 | printf("Spawn tracee\n"); |
750 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); | | 751 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); |
751 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); | | 752 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); |
752 | tracee = atf_utils_fork(); | | 753 | tracee = atf_utils_fork(); |
753 | if (tracee == 0) { | | 754 | if (tracee == 0) { |
754 | parent = getppid(); | | 755 | parent = getppid(); |
755 | | | 756 | |
756 | /* Emit message to the parent */ | | 757 | /* Emit message to the parent */ |
757 | CHILD_TO_PARENT("Message 1", parent_tracee, msg); | | 758 | CHILD_TO_PARENT("Message 1", parent_tracee, msg); |
758 | CHILD_FROM_PARENT("Message 2", parent_tracee, msg); | | 759 | CHILD_FROM_PARENT("Message 2", parent_tracee, msg); |
759 | | | 760 | |
760 | namelen = 0; | | 761 | namelen = 0; |
761 | name[namelen++] = CTL_KERN; | | 762 | name[namelen++] = CTL_KERN; |
762 | name[namelen++] = KERN_PROC2; | | 763 | name[namelen++] = KERN_PROC2; |
763 | name[namelen++] = KERN_PROC_PID; | | 764 | name[namelen++] = KERN_PROC_PID; |
764 | name[namelen++] = getpid(); | | 765 | name[namelen++] = getpid(); |
765 | name[namelen++] = len; | | 766 | name[namelen++] = len; |
766 | name[namelen++] = 1; | | 767 | name[namelen++] = 1; |
767 | | | 768 | |
768 | FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0); | | 769 | FORKEE_ASSERT(sysctl(name, namelen, &kp, &len, NULL, 0) == 0); |
769 | FORKEE_ASSERT_EQ(parent, kp.p_ppid); | | 770 | FORKEE_ASSERT_EQ(parent, kp.p_ppid); |
770 | | | 771 | |
771 | _exit(exitval_tracee); | | 772 | _exit(exitval_tracee); |
772 | } | | 773 | } |
773 | | | 774 | |
774 | printf("Wait for child to record its parent identifier (pid)\n"); | | 775 | printf("Wait for child to record its parent identifier (pid)\n"); |
775 | PARENT_FROM_CHILD("Message 1", parent_tracee, msg); | | 776 | PARENT_FROM_CHILD("Message 1", parent_tracee, msg); |
776 | | | 777 | |
777 | printf("Spawn debugger\n"); | | 778 | printf("Spawn debugger\n"); |
778 | tracer = atf_utils_fork(); | | 779 | tracer = atf_utils_fork(); |
779 | if (tracer == 0) { | | 780 | if (tracer == 0) { |
780 | /* No IPC to communicate with the child */ | | 781 | /* No IPC to communicate with the child */ |
781 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); | | 782 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); |
782 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); | | 783 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); |
783 | | | 784 | |
784 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ | | 785 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ |
785 | FORKEE_REQUIRE_SUCCESS( | | 786 | FORKEE_REQUIRE_SUCCESS( |
786 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 787 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
787 | | | 788 | |
788 | forkee_status_stopped(status, SIGSTOP); | | 789 | forkee_status_stopped(status, SIGSTOP); |
789 | | | 790 | |
790 | /* Resume tracee with PT_CONTINUE */ | | 791 | /* Resume tracee with PT_CONTINUE */ |
791 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); | | 792 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); |
792 | | | 793 | |
793 | /* Inform parent that tracer has attached to tracee */ | | 794 | /* Inform parent that tracer has attached to tracee */ |
794 | CHILD_TO_PARENT("Message 1", parent_tracer, msg); | | 795 | CHILD_TO_PARENT("Message 1", parent_tracer, msg); |
795 | | | 796 | |
796 | CHILD_FROM_PARENT("Message 2", parent_tracer, msg); | | 797 | CHILD_FROM_PARENT("Message 2", parent_tracer, msg); |
797 | | | 798 | |
798 | /* Wait for tracee and assert that it exited */ | | 799 | /* Wait for tracee and assert that it exited */ |
799 | FORKEE_REQUIRE_SUCCESS( | | 800 | FORKEE_REQUIRE_SUCCESS( |
800 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 801 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
801 | | | 802 | |
802 | forkee_status_exited(status, exitval_tracee); | | 803 | forkee_status_exited(status, exitval_tracee); |
803 | | | 804 | |
804 | printf("Before exiting of the tracer process\n"); | | 805 | printf("Before exiting of the tracer process\n"); |
805 | _exit(exitval_tracer); | | 806 | _exit(exitval_tracer); |
806 | } | | 807 | } |
807 | | | 808 | |
808 | printf("Wait for the tracer to attach to the tracee\n"); | | 809 | printf("Wait for the tracer to attach to the tracee\n"); |
809 | PARENT_FROM_CHILD("Message 1", parent_tracer, msg); | | 810 | PARENT_FROM_CHILD("Message 1", parent_tracer, msg); |
810 | | | 811 | |
811 | printf("Resume the tracee and let it exit\n"); | | 812 | printf("Resume the tracee and let it exit\n"); |
812 | PARENT_TO_CHILD("Message 1", parent_tracee, msg); | | 813 | PARENT_TO_CHILD("Message 1", parent_tracee, msg); |
813 | | | 814 | |
814 | printf("Detect that tracee is zombie\n"); | | 815 | printf("Detect that tracee is zombie\n"); |
815 | await_zombie(tracee); | | 816 | await_zombie(tracee); |
816 | | | 817 | |
817 | printf("Assert that there is no status about tracee - " | | 818 | printf("Assert that there is no status about tracee - " |
818 | "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); | | 819 | "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); |
819 | TWAIT_REQUIRE_SUCCESS( | | 820 | TWAIT_REQUIRE_SUCCESS( |
820 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); | | 821 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); |
821 | | | 822 | |
822 | printf("Resume the tracer and let it detect exited tracee\n"); | | 823 | printf("Resume the tracer and let it detect exited tracee\n"); |
823 | PARENT_TO_CHILD("Message 2", parent_tracer, msg); | | 824 | PARENT_TO_CHILD("Message 2", parent_tracer, msg); |
824 | | | 825 | |
825 | printf("Wait for tracer to finish its job and exit - calling %s()\n", | | 826 | printf("Wait for tracer to finish its job and exit - calling %s()\n", |
826 | TWAIT_FNAME); | | 827 | TWAIT_FNAME); |
827 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), | | 828 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), |
828 | tracer); | | 829 | tracer); |
829 | | | 830 | |
830 | validate_status_exited(status, exitval_tracer); | | 831 | validate_status_exited(status, exitval_tracer); |
831 | | | 832 | |
832 | printf("Wait for tracee to finish its job and exit - calling %s()\n", | | 833 | printf("Wait for tracee to finish its job and exit - calling %s()\n", |
833 | TWAIT_FNAME); | | 834 | TWAIT_FNAME); |
834 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), | | 835 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), |
835 | tracee); | | 836 | tracee); |
836 | | | 837 | |
837 | validate_status_exited(status, exitval_tracee); | | 838 | validate_status_exited(status, exitval_tracee); |
838 | | | 839 | |
839 | msg_close(&parent_tracee); | | 840 | msg_close(&parent_tracee); |
840 | msg_close(&parent_tracer); | | 841 | msg_close(&parent_tracer); |
841 | } | | 842 | } |
842 | #endif | | 843 | #endif |
843 | | | 844 | |
844 | #if defined(TWAIT_HAVE_PID) | | 845 | #if defined(TWAIT_HAVE_PID) |
845 | ATF_TC(attach7); | | 846 | ATF_TC(attach7); |
846 | ATF_TC_HEAD(attach7, tc) | | 847 | ATF_TC_HEAD(attach7, tc) |
847 | { | | 848 | { |
848 | atf_tc_set_md_var(tc, "descr", | | 849 | atf_tc_set_md_var(tc, "descr", |
849 | "Assert that tracer sees its parent when attached to tracer " | | 850 | "Assert that tracer sees its parent when attached to tracer " |
850 | "(check /proc/curproc/status 3rd column)"); | | 851 | "(check /proc/curproc/status 3rd column)"); |
851 | } | | 852 | } |
852 | | | 853 | |
853 | ATF_TC_BODY(attach7, tc) | | 854 | ATF_TC_BODY(attach7, tc) |
854 | { | | 855 | { |
855 | struct msg_fds parent_tracee, parent_tracer; | | 856 | struct msg_fds parent_tracee, parent_tracer; |
856 | int rv; | | 857 | int rv; |
857 | const int exitval_tracee = 5; | | 858 | const int exitval_tracee = 5; |
858 | const int exitval_tracer = 10; | | 859 | const int exitval_tracer = 10; |
859 | pid_t parent, tracee, tracer, wpid; | | 860 | pid_t parent, tracee, tracer, wpid; |
860 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ | | 861 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ |
861 | #if defined(TWAIT_HAVE_STATUS) | | 862 | #if defined(TWAIT_HAVE_STATUS) |
862 | int status; | | 863 | int status; |
863 | #endif | | 864 | #endif |
864 | FILE *fp; | | 865 | FILE *fp; |
865 | struct stat st; | | 866 | struct stat st; |
866 | const char *fname = "/proc/curproc/status"; | | 867 | const char *fname = "/proc/curproc/status"; |
867 | char s_executable[MAXPATHLEN]; | | 868 | char s_executable[MAXPATHLEN]; |
868 | int s_pid, s_ppid; | | 869 | int s_pid, s_ppid; |
869 | /* | | 870 | /* |
870 | * Format: | | 871 | * Format: |
871 | * EXECUTABLE PID PPID ... | | 872 | * EXECUTABLE PID PPID ... |
872 | */ | | 873 | */ |
873 | | | 874 | |
874 | ATF_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT)); | | 875 | ATF_REQUIRE((rv = stat(fname, &st)) == 0 || (errno == ENOENT)); |
875 | if (rv != 0) { | | 876 | if (rv != 0) { |
876 | atf_tc_skip("/proc/curproc/status not found"); | | 877 | atf_tc_skip("/proc/curproc/status not found"); |
877 | } | | 878 | } |
878 | | | 879 | |
879 | printf("Spawn tracee\n"); | | 880 | printf("Spawn tracee\n"); |
880 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); | | 881 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); |
881 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); | | 882 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); |
882 | tracee = atf_utils_fork(); | | 883 | tracee = atf_utils_fork(); |
883 | if (tracee == 0) { | | 884 | if (tracee == 0) { |
884 | parent = getppid(); | | 885 | parent = getppid(); |
885 | | | 886 | |
886 | // Wait for parent to let us exit | | 887 | // Wait for parent to let us exit |
887 | CHILD_TO_PARENT("tracee ready", parent_tracee, msg); | | 888 | CHILD_TO_PARENT("tracee ready", parent_tracee, msg); |
888 | CHILD_FROM_PARENT("tracee exit", parent_tracee, msg); | | 889 | CHILD_FROM_PARENT("tracee exit", parent_tracee, msg); |
889 | | | 890 | |
890 | FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); | | 891 | FORKEE_ASSERT((fp = fopen(fname, "r")) != NULL); |
891 | fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); | | 892 | fscanf(fp, "%s %d %d", s_executable, &s_pid, &s_ppid); |
892 | FORKEE_ASSERT(fclose(fp) == 0); | | 893 | FORKEE_ASSERT(fclose(fp) == 0); |
893 | FORKEE_ASSERT_EQ(parent, s_ppid); | | 894 | FORKEE_ASSERT_EQ(parent, s_ppid); |
894 | | | 895 | |
895 | _exit(exitval_tracee); | | 896 | _exit(exitval_tracee); |
896 | } | | 897 | } |
897 | | | 898 | |
898 | printf("Wait for child to record its parent identifier (pid)\n"); | | 899 | printf("Wait for child to record its parent identifier (pid)\n"); |
899 | PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); | | 900 | PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); |
900 | | | 901 | |
901 | printf("Spawn debugger\n"); | | 902 | printf("Spawn debugger\n"); |
902 | tracer = atf_utils_fork(); | | 903 | tracer = atf_utils_fork(); |
903 | if (tracer == 0) { | | 904 | if (tracer == 0) { |
904 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); | | 905 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); |
905 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); | | 906 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); |
906 | | | 907 | |
907 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ | | 908 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ |
908 | FORKEE_REQUIRE_SUCCESS( | | 909 | FORKEE_REQUIRE_SUCCESS( |
909 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 910 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
910 | | | 911 | |
911 | forkee_status_stopped(status, SIGSTOP); | | 912 | forkee_status_stopped(status, SIGSTOP); |
912 | | | 913 | |
913 | /* Resume tracee with PT_CONTINUE */ | | 914 | /* Resume tracee with PT_CONTINUE */ |
914 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); | | 915 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); |
915 | | | 916 | |
916 | /* Inform parent that tracer has attached to tracee */ | | 917 | /* Inform parent that tracer has attached to tracee */ |
917 | CHILD_TO_PARENT("tracer ready", parent_tracer, msg); | | 918 | CHILD_TO_PARENT("tracer ready", parent_tracer, msg); |
918 | | | 919 | |
919 | /* Wait for parent to tell use that tracee should have exited */ | | 920 | /* Wait for parent to tell use that tracee should have exited */ |
920 | CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); | | 921 | CHILD_FROM_PARENT("wait for tracee exit", parent_tracer, msg); |
921 | | | 922 | |
922 | /* Wait for tracee and assert that it exited */ | | 923 | /* Wait for tracee and assert that it exited */ |
923 | FORKEE_REQUIRE_SUCCESS( | | 924 | FORKEE_REQUIRE_SUCCESS( |
924 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 925 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
925 | | | 926 | |
926 | forkee_status_exited(status, exitval_tracee); | | 927 | forkee_status_exited(status, exitval_tracee); |
927 | | | 928 | |
928 | printf("Before exiting of the tracer process\n"); | | 929 | printf("Before exiting of the tracer process\n"); |
929 | _exit(exitval_tracer); | | 930 | _exit(exitval_tracer); |
930 | } | | 931 | } |
931 | printf("Wait for the tracer to attach to the tracee\n"); | | 932 | printf("Wait for the tracer to attach to the tracee\n"); |
932 | PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); | | 933 | PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); |
933 | printf("Resume the tracee and let it exit\n"); | | 934 | printf("Resume the tracee and let it exit\n"); |
934 | PARENT_TO_CHILD("tracee exit", parent_tracee, msg); | | 935 | PARENT_TO_CHILD("tracee exit", parent_tracee, msg); |
935 | | | 936 | |
936 | printf("Detect that tracee is zombie\n"); | | 937 | printf("Detect that tracee is zombie\n"); |
937 | await_zombie(tracee); | | 938 | await_zombie(tracee); |
938 | | | 939 | |
939 | printf("Assert that there is no status about tracee - " | | 940 | printf("Assert that there is no status about tracee - " |
940 | "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); | | 941 | "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); |
941 | TWAIT_REQUIRE_SUCCESS( | | 942 | TWAIT_REQUIRE_SUCCESS( |
942 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); | | 943 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); |
943 | | | 944 | |
944 | printf("Resume the tracer and let it detect exited tracee\n"); | | 945 | printf("Resume the tracer and let it detect exited tracee\n"); |
945 | PARENT_TO_CHILD("Message 2", parent_tracer, msg); | | 946 | PARENT_TO_CHILD("Message 2", parent_tracer, msg); |
946 | | | 947 | |
947 | printf("Wait for tracer to finish its job and exit - calling %s()\n", | | 948 | printf("Wait for tracer to finish its job and exit - calling %s()\n", |
948 | TWAIT_FNAME); | | 949 | TWAIT_FNAME); |
949 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), | | 950 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), |
950 | tracer); | | 951 | tracer); |
951 | | | 952 | |
952 | validate_status_exited(status, exitval_tracer); | | 953 | validate_status_exited(status, exitval_tracer); |
953 | | | 954 | |
954 | printf("Wait for tracee to finish its job and exit - calling %s()\n", | | 955 | printf("Wait for tracee to finish its job and exit - calling %s()\n", |
955 | TWAIT_FNAME); | | 956 | TWAIT_FNAME); |
956 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), | | 957 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), |
957 | tracee); | | 958 | tracee); |
958 | | | 959 | |
959 | validate_status_exited(status, exitval_tracee); | | 960 | validate_status_exited(status, exitval_tracee); |
960 | | | 961 | |
961 | msg_close(&parent_tracee); | | 962 | msg_close(&parent_tracee); |
962 | msg_close(&parent_tracer); | | 963 | msg_close(&parent_tracer); |
963 | } | | 964 | } |
964 | #endif | | 965 | #endif |
965 | | | 966 | |
966 | ATF_TC(eventmask1); | | 967 | ATF_TC(eventmask1); |
967 | ATF_TC_HEAD(eventmask1, tc) | | 968 | ATF_TC_HEAD(eventmask1, tc) |
968 | { | | 969 | { |
969 | atf_tc_set_md_var(tc, "descr", | | 970 | atf_tc_set_md_var(tc, "descr", |
970 | "Verify that empty EVENT_MASK is preserved"); | | 971 | "Verify that empty EVENT_MASK is preserved"); |
971 | } | | 972 | } |
972 | | | 973 | |
973 | ATF_TC_BODY(eventmask1, tc) | | 974 | ATF_TC_BODY(eventmask1, tc) |
974 | { | | 975 | { |
975 | const int exitval = 5; | | 976 | const int exitval = 5; |
976 | const int sigval = SIGSTOP; | | 977 | const int sigval = SIGSTOP; |
977 | pid_t child, wpid; | | 978 | pid_t child, wpid; |
978 | #if defined(TWAIT_HAVE_STATUS) | | 979 | #if defined(TWAIT_HAVE_STATUS) |
979 | int status; | | 980 | int status; |
980 | #endif | | 981 | #endif |
981 | ptrace_event_t set_event, get_event; | | 982 | ptrace_event_t set_event, get_event; |
982 | const int len = sizeof(ptrace_event_t); | | 983 | const int len = sizeof(ptrace_event_t); |
983 | | | 984 | |
984 | printf("Before forking process PID=%d\n", getpid()); | | 985 | printf("Before forking process PID=%d\n", getpid()); |
985 | ATF_REQUIRE((child = fork()) != -1); | | 986 | ATF_REQUIRE((child = fork()) != -1); |
986 | if (child == 0) { | | 987 | if (child == 0) { |
987 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 988 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
988 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 989 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
989 | | | 990 | |
990 | printf("Before raising %s from child\n", strsignal(sigval)); | | 991 | printf("Before raising %s from child\n", strsignal(sigval)); |
991 | FORKEE_ASSERT(raise(sigval) == 0); | | 992 | FORKEE_ASSERT(raise(sigval) == 0); |
992 | | | 993 | |
993 | printf("Before exiting of the child process\n"); | | 994 | printf("Before exiting of the child process\n"); |
994 | _exit(exitval); | | 995 | _exit(exitval); |
995 | } | | 996 | } |
996 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 997 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
997 | | | 998 | |
998 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 999 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
999 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1000 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1000 | | | 1001 | |
1001 | validate_status_stopped(status, sigval); | | 1002 | validate_status_stopped(status, sigval); |
1002 | | | 1003 | |
1003 | set_event.pe_set_event = 0; | | 1004 | set_event.pe_set_event = 0; |
1004 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); | | 1005 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &set_event, len) != -1); |
1005 | ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); | | 1006 | ATF_REQUIRE(ptrace(PT_GET_EVENT_MASK, child, &get_event, len) != -1); |
1006 | ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); | | 1007 | ATF_REQUIRE(memcmp(&set_event, &get_event, len) == 0); |
1007 | | | 1008 | |
1008 | printf("Before resuming the child process where it left off and " | | 1009 | printf("Before resuming the child process where it left off and " |
1009 | "without signal to be sent\n"); | | 1010 | "without signal to be sent\n"); |
1010 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1011 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1011 | | | 1012 | |
1012 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 1013 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
1013 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1014 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1014 | | | 1015 | |
1015 | validate_status_exited(status, exitval); | | 1016 | validate_status_exited(status, exitval); |
1016 | | | 1017 | |
1017 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 1018 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
1018 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 1019 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
1019 | } | | 1020 | } |
1020 | | | 1021 | |
1021 | ATF_TC(eventmask2); | | 1022 | ATF_TC(eventmask2); |
1022 | ATF_TC_HEAD(eventmask2, tc) | | 1023 | ATF_TC_HEAD(eventmask2, tc) |
1023 | { | | 1024 | { |
1024 | atf_tc_set_md_var(tc, "descr", | | 1025 | atf_tc_set_md_var(tc, "descr", |
1025 | "Verify that PTRACE_FORK in EVENT_MASK is preserved"); | | 1026 | "Verify that PTRACE_FORK in EVENT_MASK is preserved"); |
1026 | } | | 1027 | } |
1027 | | | 1028 | |
1028 | ATF_TC_BODY(eventmask2, tc) | | 1029 | ATF_TC_BODY(eventmask2, tc) |
1029 | { | | 1030 | { |
1030 | const int exitval = 5; | | 1031 | const int exitval = 5; |
1031 | const int sigval = SIGSTOP; | | 1032 | const int sigval = SIGSTOP; |
1032 | pid_t child, wpid; | | 1033 | pid_t child, wpid; |
1033 | #if defined(TWAIT_HAVE_STATUS) | | 1034 | #if defined(TWAIT_HAVE_STATUS) |
1034 | int status; | | 1035 | int status; |
1035 | #endif | | 1036 | #endif |
1036 | ptrace_event_t set_event, get_event; | | 1037 | ptrace_event_t set_event, get_event; |
1037 | const int len = sizeof(ptrace_event_t); | | 1038 | const int len = sizeof(ptrace_event_t); |
1038 | | | 1039 | |
| @@ -1411,1998 +1412,2064 @@ ATF_TC_BODY(fork1, tc) | | | @@ -1411,1998 +1412,2064 @@ ATF_TC_BODY(fork1, tc) |
1411 | TWAIT_FNAME); | | 1412 | TWAIT_FNAME); |
1412 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1413 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1413 | | | 1414 | |
1414 | validate_status_exited(status, exitval); | | 1415 | validate_status_exited(status, exitval); |
1415 | | | 1416 | |
1416 | printf("Before calling %s() for the child - expected no process\n", | | 1417 | printf("Before calling %s() for the child - expected no process\n", |
1417 | TWAIT_FNAME); | | 1418 | TWAIT_FNAME); |
1418 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 1419 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
1419 | } | | 1420 | } |
1420 | #endif | | 1421 | #endif |
1421 | | | 1422 | |
1422 | ATF_TC(fork2); | | 1423 | ATF_TC(fork2); |
1423 | ATF_TC_HEAD(fork2, tc) | | 1424 | ATF_TC_HEAD(fork2, tc) |
1424 | { | | 1425 | { |
1425 | atf_tc_set_md_var(tc, "descr", | | 1426 | atf_tc_set_md_var(tc, "descr", |
1426 | "Verify that fork(2) is not intercepted by ptrace(2) with empty " | | 1427 | "Verify that fork(2) is not intercepted by ptrace(2) with empty " |
1427 | "EVENT_MASK"); | | 1428 | "EVENT_MASK"); |
1428 | } | | 1429 | } |
1429 | | | 1430 | |
1430 | ATF_TC_BODY(fork2, tc) | | 1431 | ATF_TC_BODY(fork2, tc) |
1431 | { | | 1432 | { |
1432 | const int exitval = 5; | | 1433 | const int exitval = 5; |
1433 | const int exitval2 = 15; | | 1434 | const int exitval2 = 15; |
1434 | const int sigval = SIGSTOP; | | 1435 | const int sigval = SIGSTOP; |
1435 | pid_t child, child2, wpid; | | 1436 | pid_t child, child2, wpid; |
1436 | #if defined(TWAIT_HAVE_STATUS) | | 1437 | #if defined(TWAIT_HAVE_STATUS) |
1437 | int status; | | 1438 | int status; |
1438 | #endif | | 1439 | #endif |
1439 | ptrace_event_t event; | | 1440 | ptrace_event_t event; |
1440 | const int elen = sizeof(event); | | 1441 | const int elen = sizeof(event); |
1441 | | | 1442 | |
1442 | printf("Before forking process PID=%d\n", getpid()); | | 1443 | printf("Before forking process PID=%d\n", getpid()); |
1443 | ATF_REQUIRE((child = fork()) != -1); | | 1444 | ATF_REQUIRE((child = fork()) != -1); |
1444 | if (child == 0) { | | 1445 | if (child == 0) { |
1445 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 1446 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
1446 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 1447 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
1447 | | | 1448 | |
1448 | printf("Before raising %s from child\n", strsignal(sigval)); | | 1449 | printf("Before raising %s from child\n", strsignal(sigval)); |
1449 | FORKEE_ASSERT(raise(sigval) == 0); | | 1450 | FORKEE_ASSERT(raise(sigval) == 0); |
1450 | | | 1451 | |
1451 | FORKEE_ASSERT((child2 = fork()) != 1); | | 1452 | FORKEE_ASSERT((child2 = fork()) != 1); |
1452 | | | 1453 | |
1453 | if (child2 == 0) | | 1454 | if (child2 == 0) |
1454 | _exit(exitval2); | | 1455 | _exit(exitval2); |
1455 | | | 1456 | |
1456 | FORKEE_REQUIRE_SUCCESS | | 1457 | FORKEE_REQUIRE_SUCCESS |
1457 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); | | 1458 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); |
1458 | | | 1459 | |
1459 | forkee_status_exited(status, exitval2); | | 1460 | forkee_status_exited(status, exitval2); |
1460 | | | 1461 | |
1461 | printf("Before exiting of the child process\n"); | | 1462 | printf("Before exiting of the child process\n"); |
1462 | _exit(exitval); | | 1463 | _exit(exitval); |
1463 | } | | 1464 | } |
1464 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 1465 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
1465 | | | 1466 | |
1466 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 1467 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
1467 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1468 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1468 | | | 1469 | |
1469 | validate_status_stopped(status, sigval); | | 1470 | validate_status_stopped(status, sigval); |
1470 | | | 1471 | |
1471 | printf("Set empty EVENT_MASK for the child %d\n", child); | | 1472 | printf("Set empty EVENT_MASK for the child %d\n", child); |
1472 | event.pe_set_event = 0; | | 1473 | event.pe_set_event = 0; |
1473 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); | | 1474 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); |
1474 | | | 1475 | |
1475 | printf("Before resuming the child process where it left off and " | | 1476 | printf("Before resuming the child process where it left off and " |
1476 | "without signal to be sent\n"); | | 1477 | "without signal to be sent\n"); |
1477 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1478 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1478 | | | 1479 | |
1479 | printf("Before calling %s() for the child - expected stopped " | | 1480 | printf("Before calling %s() for the child - expected stopped " |
1480 | "SIGCHLD\n", TWAIT_FNAME); | | 1481 | "SIGCHLD\n", TWAIT_FNAME); |
1481 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1482 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1482 | | | 1483 | |
1483 | validate_status_stopped(status, SIGCHLD); | | 1484 | validate_status_stopped(status, SIGCHLD); |
1484 | | | 1485 | |
1485 | printf("Before resuming the child process where it left off and " | | 1486 | printf("Before resuming the child process where it left off and " |
1486 | "without signal to be sent\n"); | | 1487 | "without signal to be sent\n"); |
1487 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1488 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1488 | | | 1489 | |
1489 | printf("Before calling %s() for the child - expected exited\n", | | 1490 | printf("Before calling %s() for the child - expected exited\n", |
1490 | TWAIT_FNAME); | | 1491 | TWAIT_FNAME); |
1491 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1492 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1492 | | | 1493 | |
1493 | validate_status_exited(status, exitval); | | 1494 | validate_status_exited(status, exitval); |
1494 | | | 1495 | |
1495 | printf("Before calling %s() for the child - expected no process\n", | | 1496 | printf("Before calling %s() for the child - expected no process\n", |
1496 | TWAIT_FNAME); | | 1497 | TWAIT_FNAME); |
1497 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 1498 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
1498 | } | | 1499 | } |
1499 | | | 1500 | |
1500 | #if defined(TWAIT_HAVE_PID) | | 1501 | #if defined(TWAIT_HAVE_PID) |
1501 | ATF_TC(vfork1); | | 1502 | ATF_TC(vfork1); |
1502 | ATF_TC_HEAD(vfork1, tc) | | 1503 | ATF_TC_HEAD(vfork1, tc) |
1503 | { | | 1504 | { |
1504 | atf_tc_set_md_var(tc, "descr", | | 1505 | atf_tc_set_md_var(tc, "descr", |
1505 | "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK " | | 1506 | "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK " |
1506 | "set to PTRACE_VFORK"); | | 1507 | "set to PTRACE_VFORK"); |
1507 | } | | 1508 | } |
1508 | | | 1509 | |
1509 | ATF_TC_BODY(vfork1, tc) | | 1510 | ATF_TC_BODY(vfork1, tc) |
1510 | { | | 1511 | { |
1511 | const int exitval = 5; | | 1512 | const int exitval = 5; |
1512 | const int exitval2 = 15; | | 1513 | const int exitval2 = 15; |
1513 | const int sigval = SIGSTOP; | | 1514 | const int sigval = SIGSTOP; |
1514 | pid_t child, child2, wpid; | | 1515 | pid_t child, child2, wpid; |
1515 | #if defined(TWAIT_HAVE_STATUS) | | 1516 | #if defined(TWAIT_HAVE_STATUS) |
1516 | int status; | | 1517 | int status; |
1517 | #endif | | 1518 | #endif |
1518 | ptrace_state_t state; | | 1519 | ptrace_state_t state; |
1519 | const int slen = sizeof(state); | | 1520 | const int slen = sizeof(state); |
1520 | ptrace_event_t event; | | 1521 | ptrace_event_t event; |
1521 | const int elen = sizeof(event); | | 1522 | const int elen = sizeof(event); |
1522 | | | 1523 | |
1523 | atf_tc_expect_fail("PR kern/51630"); | | 1524 | atf_tc_expect_fail("PR kern/51630"); |
1524 | | | 1525 | |
1525 | printf("Before forking process PID=%d\n", getpid()); | | 1526 | printf("Before forking process PID=%d\n", getpid()); |
1526 | ATF_REQUIRE((child = fork()) != -1); | | 1527 | ATF_REQUIRE((child = fork()) != -1); |
1527 | if (child == 0) { | | 1528 | if (child == 0) { |
1528 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 1529 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
1529 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 1530 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
1530 | | | 1531 | |
1531 | printf("Before raising %s from child\n", strsignal(sigval)); | | 1532 | printf("Before raising %s from child\n", strsignal(sigval)); |
1532 | FORKEE_ASSERT(raise(sigval) == 0); | | 1533 | FORKEE_ASSERT(raise(sigval) == 0); |
1533 | | | 1534 | |
1534 | FORKEE_ASSERT((child2 = vfork()) != 1); | | 1535 | FORKEE_ASSERT((child2 = vfork()) != 1); |
1535 | | | 1536 | |
1536 | if (child2 == 0) | | 1537 | if (child2 == 0) |
1537 | _exit(exitval2); | | 1538 | _exit(exitval2); |
1538 | | | 1539 | |
1539 | FORKEE_REQUIRE_SUCCESS | | 1540 | FORKEE_REQUIRE_SUCCESS |
1540 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); | | 1541 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); |
1541 | | | 1542 | |
1542 | forkee_status_exited(status, exitval2); | | 1543 | forkee_status_exited(status, exitval2); |
1543 | | | 1544 | |
1544 | printf("Before exiting of the child process\n"); | | 1545 | printf("Before exiting of the child process\n"); |
1545 | _exit(exitval); | | 1546 | _exit(exitval); |
1546 | } | | 1547 | } |
1547 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 1548 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
1548 | | | 1549 | |
1549 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 1550 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
1550 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1551 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1551 | | | 1552 | |
1552 | validate_status_stopped(status, sigval); | | 1553 | validate_status_stopped(status, sigval); |
1553 | | | 1554 | |
1554 | printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); | | 1555 | printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); |
1555 | event.pe_set_event = PTRACE_VFORK; | | 1556 | event.pe_set_event = PTRACE_VFORK; |
1556 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); | | 1557 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); |
1557 | | | 1558 | |
1558 | printf("Before resuming the child process where it left off and " | | 1559 | printf("Before resuming the child process where it left off and " |
1559 | "without signal to be sent\n"); | | 1560 | "without signal to be sent\n"); |
1560 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1561 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1561 | | | 1562 | |
1562 | printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); | | 1563 | printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); |
1563 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1564 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1564 | | | 1565 | |
1565 | validate_status_stopped(status, SIGTRAP); | | 1566 | validate_status_stopped(status, SIGTRAP); |
1566 | | | 1567 | |
1567 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); | | 1568 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); |
1568 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); | | 1569 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); |
1569 | | | 1570 | |
1570 | child2 = state.pe_other_pid; | | 1571 | child2 = state.pe_other_pid; |
1571 | printf("Reported PTRACE_VFORK event with forkee %d\n", child2); | | 1572 | printf("Reported PTRACE_VFORK event with forkee %d\n", child2); |
1572 | | | 1573 | |
1573 | printf("Before calling %s() for the forkee %d of the child %d\n", | | 1574 | printf("Before calling %s() for the forkee %d of the child %d\n", |
1574 | TWAIT_FNAME, child2, child); | | 1575 | TWAIT_FNAME, child2, child); |
1575 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), | | 1576 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), |
1576 | child2); | | 1577 | child2); |
1577 | | | 1578 | |
1578 | validate_status_stopped(status, SIGTRAP); | | 1579 | validate_status_stopped(status, SIGTRAP); |
1579 | | | 1580 | |
1580 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); | | 1581 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); |
1581 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); | | 1582 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK); |
1582 | ATF_REQUIRE_EQ(state.pe_other_pid, child); | | 1583 | ATF_REQUIRE_EQ(state.pe_other_pid, child); |
1583 | | | 1584 | |
1584 | printf("Before resuming the forkee process where it left off and " | | 1585 | printf("Before resuming the forkee process where it left off and " |
1585 | "without signal to be sent\n"); | | 1586 | "without signal to be sent\n"); |
1586 | ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); | | 1587 | ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); |
1587 | | | 1588 | |
1588 | printf("Before resuming the child process where it left off and " | | 1589 | printf("Before resuming the child process where it left off and " |
1589 | "without signal to be sent\n"); | | 1590 | "without signal to be sent\n"); |
1590 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1591 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1591 | | | 1592 | |
1592 | printf("Before calling %s() for the forkee - expected exited\n", | | 1593 | printf("Before calling %s() for the forkee - expected exited\n", |
1593 | TWAIT_FNAME); | | 1594 | TWAIT_FNAME); |
1594 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), | | 1595 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), |
1595 | child2); | | 1596 | child2); |
1596 | | | 1597 | |
1597 | validate_status_exited(status, exitval2); | | 1598 | validate_status_exited(status, exitval2); |
1598 | | | 1599 | |
1599 | printf("Before calling %s() for the forkee - expected no process\n", | | 1600 | printf("Before calling %s() for the forkee - expected no process\n", |
1600 | TWAIT_FNAME); | | 1601 | TWAIT_FNAME); |
1601 | TWAIT_REQUIRE_FAILURE(ECHILD, | | 1602 | TWAIT_REQUIRE_FAILURE(ECHILD, |
1602 | wpid = TWAIT_GENERIC(child2, &status, 0)); | | 1603 | wpid = TWAIT_GENERIC(child2, &status, 0)); |
1603 | | | 1604 | |
1604 | printf("Before calling %s() for the child - expected stopped " | | 1605 | printf("Before calling %s() for the child - expected stopped " |
1605 | "SIGCHLD\n", TWAIT_FNAME); | | 1606 | "SIGCHLD\n", TWAIT_FNAME); |
1606 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1607 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1607 | | | 1608 | |
1608 | validate_status_stopped(status, SIGCHLD); | | 1609 | validate_status_stopped(status, SIGCHLD); |
1609 | | | 1610 | |
1610 | printf("Before resuming the child process where it left off and " | | 1611 | printf("Before resuming the child process where it left off and " |
1611 | "without signal to be sent\n"); | | 1612 | "without signal to be sent\n"); |
1612 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1613 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1613 | | | 1614 | |
1614 | printf("Before calling %s() for the child - expected exited\n", | | 1615 | printf("Before calling %s() for the child - expected exited\n", |
1615 | TWAIT_FNAME); | | 1616 | TWAIT_FNAME); |
1616 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1617 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1617 | | | 1618 | |
1618 | validate_status_exited(status, exitval); | | 1619 | validate_status_exited(status, exitval); |
1619 | | | 1620 | |
1620 | printf("Before calling %s() for the child - expected no process\n", | | 1621 | printf("Before calling %s() for the child - expected no process\n", |
1621 | TWAIT_FNAME); | | 1622 | TWAIT_FNAME); |
1622 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 1623 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
1623 | } | | 1624 | } |
1624 | #endif | | 1625 | #endif |
1625 | | | 1626 | |
1626 | ATF_TC(vfork2); | | 1627 | ATF_TC(vfork2); |
1627 | ATF_TC_HEAD(vfork2, tc) | | 1628 | ATF_TC_HEAD(vfork2, tc) |
1628 | { | | 1629 | { |
1629 | atf_tc_set_md_var(tc, "descr", | | 1630 | atf_tc_set_md_var(tc, "descr", |
1630 | "Verify that vfork(2) is not intercepted by ptrace(2) with empty " | | 1631 | "Verify that vfork(2) is not intercepted by ptrace(2) with empty " |
1631 | "EVENT_MASK"); | | 1632 | "EVENT_MASK"); |
1632 | } | | 1633 | } |
1633 | | | 1634 | |
1634 | ATF_TC_BODY(vfork2, tc) | | 1635 | ATF_TC_BODY(vfork2, tc) |
1635 | { | | 1636 | { |
1636 | const int exitval = 5; | | 1637 | const int exitval = 5; |
1637 | const int exitval2 = 15; | | 1638 | const int exitval2 = 15; |
1638 | const int sigval = SIGSTOP; | | 1639 | const int sigval = SIGSTOP; |
1639 | pid_t child, child2, wpid; | | 1640 | pid_t child, child2, wpid; |
1640 | #if defined(TWAIT_HAVE_STATUS) | | 1641 | #if defined(TWAIT_HAVE_STATUS) |
1641 | int status; | | 1642 | int status; |
1642 | #endif | | 1643 | #endif |
1643 | ptrace_event_t event; | | 1644 | ptrace_event_t event; |
1644 | const int elen = sizeof(event); | | 1645 | const int elen = sizeof(event); |
1645 | | | 1646 | |
1646 | printf("Before forking process PID=%d\n", getpid()); | | 1647 | printf("Before forking process PID=%d\n", getpid()); |
1647 | ATF_REQUIRE((child = fork()) != -1); | | 1648 | ATF_REQUIRE((child = fork()) != -1); |
1648 | if (child == 0) { | | 1649 | if (child == 0) { |
1649 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 1650 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
1650 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 1651 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
1651 | | | 1652 | |
1652 | printf("Before raising %s from child\n", strsignal(sigval)); | | 1653 | printf("Before raising %s from child\n", strsignal(sigval)); |
1653 | FORKEE_ASSERT(raise(sigval) == 0); | | 1654 | FORKEE_ASSERT(raise(sigval) == 0); |
1654 | | | 1655 | |
1655 | FORKEE_ASSERT((child2 = vfork()) != 1); | | 1656 | FORKEE_ASSERT((child2 = vfork()) != 1); |
1656 | | | 1657 | |
1657 | if (child2 == 0) | | 1658 | if (child2 == 0) |
1658 | _exit(exitval2); | | 1659 | _exit(exitval2); |
1659 | | | 1660 | |
1660 | FORKEE_REQUIRE_SUCCESS | | 1661 | FORKEE_REQUIRE_SUCCESS |
1661 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); | | 1662 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); |
1662 | | | 1663 | |
1663 | forkee_status_exited(status, exitval2); | | 1664 | forkee_status_exited(status, exitval2); |
1664 | | | 1665 | |
1665 | printf("Before exiting of the child process\n"); | | 1666 | printf("Before exiting of the child process\n"); |
1666 | _exit(exitval); | | 1667 | _exit(exitval); |
1667 | } | | 1668 | } |
1668 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 1669 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
1669 | | | 1670 | |
1670 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 1671 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
1671 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1672 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1672 | | | 1673 | |
1673 | validate_status_stopped(status, sigval); | | 1674 | validate_status_stopped(status, sigval); |
1674 | | | 1675 | |
1675 | printf("Set empty EVENT_MASK for the child %d\n", child); | | 1676 | printf("Set empty EVENT_MASK for the child %d\n", child); |
1676 | event.pe_set_event = 0; | | 1677 | event.pe_set_event = 0; |
1677 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); | | 1678 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); |
1678 | | | 1679 | |
1679 | printf("Before resuming the child process where it left off and " | | 1680 | printf("Before resuming the child process where it left off and " |
1680 | "without signal to be sent\n"); | | 1681 | "without signal to be sent\n"); |
1681 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1682 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1682 | | | 1683 | |
1683 | printf("Before calling %s() for the child - expected stopped " | | 1684 | printf("Before calling %s() for the child - expected stopped " |
1684 | "SIGCHLD\n", TWAIT_FNAME); | | 1685 | "SIGCHLD\n", TWAIT_FNAME); |
1685 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1686 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1686 | | | 1687 | |
1687 | validate_status_stopped(status, SIGCHLD); | | 1688 | validate_status_stopped(status, SIGCHLD); |
1688 | | | 1689 | |
1689 | printf("Before resuming the child process where it left off and " | | 1690 | printf("Before resuming the child process where it left off and " |
1690 | "without signal to be sent\n"); | | 1691 | "without signal to be sent\n"); |
1691 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1692 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1692 | | | 1693 | |
1693 | printf("Before calling %s() for the child - expected exited\n", | | 1694 | printf("Before calling %s() for the child - expected exited\n", |
1694 | TWAIT_FNAME); | | 1695 | TWAIT_FNAME); |
1695 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1696 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1696 | | | 1697 | |
1697 | validate_status_exited(status, exitval); | | 1698 | validate_status_exited(status, exitval); |
1698 | | | 1699 | |
1699 | printf("Before calling %s() for the child - expected no process\n", | | 1700 | printf("Before calling %s() for the child - expected no process\n", |
1700 | TWAIT_FNAME); | | 1701 | TWAIT_FNAME); |
1701 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 1702 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
1702 | } | | 1703 | } |
1703 | | | 1704 | |
1704 | ATF_TC(vforkdone1); | | 1705 | ATF_TC(vforkdone1); |
1705 | ATF_TC_HEAD(vforkdone1, tc) | | 1706 | ATF_TC_HEAD(vforkdone1, tc) |
1706 | { | | 1707 | { |
1707 | atf_tc_set_md_var(tc, "descr", | | 1708 | atf_tc_set_md_var(tc, "descr", |
1708 | "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK " | | 1709 | "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK " |
1709 | "set to PTRACE_VFORK_DONE"); | | 1710 | "set to PTRACE_VFORK_DONE"); |
1710 | } | | 1711 | } |
1711 | | | 1712 | |
1712 | ATF_TC_BODY(vforkdone1, tc) | | 1713 | ATF_TC_BODY(vforkdone1, tc) |
1713 | { | | 1714 | { |
1714 | const int exitval = 5; | | 1715 | const int exitval = 5; |
1715 | const int exitval2 = 15; | | 1716 | const int exitval2 = 15; |
1716 | const int sigval = SIGSTOP; | | 1717 | const int sigval = SIGSTOP; |
1717 | pid_t child, child2, wpid; | | 1718 | pid_t child, child2, wpid; |
1718 | #if defined(TWAIT_HAVE_STATUS) | | 1719 | #if defined(TWAIT_HAVE_STATUS) |
1719 | int status; | | 1720 | int status; |
1720 | #endif | | 1721 | #endif |
1721 | ptrace_state_t state; | | 1722 | ptrace_state_t state; |
1722 | const int slen = sizeof(state); | | 1723 | const int slen = sizeof(state); |
1723 | ptrace_event_t event; | | 1724 | ptrace_event_t event; |
1724 | const int elen = sizeof(event); | | 1725 | const int elen = sizeof(event); |
1725 | | | 1726 | |
1726 | printf("Before forking process PID=%d\n", getpid()); | | 1727 | printf("Before forking process PID=%d\n", getpid()); |
1727 | ATF_REQUIRE((child = fork()) != -1); | | 1728 | ATF_REQUIRE((child = fork()) != -1); |
1728 | if (child == 0) { | | 1729 | if (child == 0) { |
1729 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 1730 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
1730 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 1731 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
1731 | | | 1732 | |
1732 | printf("Before raising %s from child\n", strsignal(sigval)); | | 1733 | printf("Before raising %s from child\n", strsignal(sigval)); |
1733 | FORKEE_ASSERT(raise(sigval) == 0); | | 1734 | FORKEE_ASSERT(raise(sigval) == 0); |
1734 | | | 1735 | |
1735 | FORKEE_ASSERT((child2 = vfork()) != 1); | | 1736 | FORKEE_ASSERT((child2 = vfork()) != 1); |
1736 | | | 1737 | |
1737 | if (child2 == 0) | | 1738 | if (child2 == 0) |
1738 | _exit(exitval2); | | 1739 | _exit(exitval2); |
1739 | | | 1740 | |
1740 | FORKEE_REQUIRE_SUCCESS | | 1741 | FORKEE_REQUIRE_SUCCESS |
1741 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); | | 1742 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); |
1742 | | | 1743 | |
1743 | forkee_status_exited(status, exitval2); | | 1744 | forkee_status_exited(status, exitval2); |
1744 | | | 1745 | |
1745 | printf("Before exiting of the child process\n"); | | 1746 | printf("Before exiting of the child process\n"); |
1746 | _exit(exitval); | | 1747 | _exit(exitval); |
1747 | } | | 1748 | } |
1748 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 1749 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
1749 | | | 1750 | |
1750 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 1751 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
1751 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1752 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1752 | | | 1753 | |
1753 | validate_status_stopped(status, sigval); | | 1754 | validate_status_stopped(status, sigval); |
1754 | | | 1755 | |
1755 | printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); | | 1756 | printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); |
1756 | event.pe_set_event = PTRACE_VFORK_DONE; | | 1757 | event.pe_set_event = PTRACE_VFORK_DONE; |
1757 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); | | 1758 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); |
1758 | | | 1759 | |
1759 | printf("Before resuming the child process where it left off and " | | 1760 | printf("Before resuming the child process where it left off and " |
1760 | "without signal to be sent\n"); | | 1761 | "without signal to be sent\n"); |
1761 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1762 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1762 | | | 1763 | |
1763 | printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); | | 1764 | printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); |
1764 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1765 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1765 | | | 1766 | |
1766 | validate_status_stopped(status, SIGTRAP); | | 1767 | validate_status_stopped(status, SIGTRAP); |
1767 | | | 1768 | |
1768 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); | | 1769 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); |
1769 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); | | 1770 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); |
1770 | | | 1771 | |
1771 | child2 = state.pe_other_pid; | | 1772 | child2 = state.pe_other_pid; |
1772 | printf("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); | | 1773 | printf("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); |
1773 | | | 1774 | |
1774 | printf("Before resuming the child process where it left off and " | | 1775 | printf("Before resuming the child process where it left off and " |
1775 | "without signal to be sent\n"); | | 1776 | "without signal to be sent\n"); |
1776 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1777 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1777 | | | 1778 | |
1778 | printf("Before calling %s() for the child - expected stopped " | | 1779 | printf("Before calling %s() for the child - expected stopped " |
1779 | "SIGCHLD\n", TWAIT_FNAME); | | 1780 | "SIGCHLD\n", TWAIT_FNAME); |
1780 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1781 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1781 | | | 1782 | |
1782 | validate_status_stopped(status, SIGCHLD); | | 1783 | validate_status_stopped(status, SIGCHLD); |
1783 | | | 1784 | |
1784 | printf("Before resuming the child process where it left off and " | | 1785 | printf("Before resuming the child process where it left off and " |
1785 | "without signal to be sent\n"); | | 1786 | "without signal to be sent\n"); |
1786 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1787 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1787 | | | 1788 | |
1788 | printf("Before calling %s() for the child - expected exited\n", | | 1789 | printf("Before calling %s() for the child - expected exited\n", |
1789 | TWAIT_FNAME); | | 1790 | TWAIT_FNAME); |
1790 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1791 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1791 | | | 1792 | |
1792 | validate_status_exited(status, exitval); | | 1793 | validate_status_exited(status, exitval); |
1793 | | | 1794 | |
1794 | printf("Before calling %s() for the child - expected no process\n", | | 1795 | printf("Before calling %s() for the child - expected no process\n", |
1795 | TWAIT_FNAME); | | 1796 | TWAIT_FNAME); |
1796 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 1797 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
1797 | } | | 1798 | } |
1798 | | | 1799 | |
1799 | ATF_TC(vforkdone2); | | 1800 | ATF_TC(vforkdone2); |
1800 | ATF_TC_HEAD(vforkdone2, tc) | | 1801 | ATF_TC_HEAD(vforkdone2, tc) |
1801 | { | | 1802 | { |
1802 | atf_tc_set_md_var(tc, "descr", | | 1803 | atf_tc_set_md_var(tc, "descr", |
1803 | "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK " | | 1804 | "Verify that vfork(2) is intercepted by ptrace(2) with EVENT_MASK " |
1804 | "set to PTRACE_FORK | PTRACE_VFORK_DONE"); | | 1805 | "set to PTRACE_FORK | PTRACE_VFORK_DONE"); |
1805 | } | | 1806 | } |
1806 | | | 1807 | |
1807 | ATF_TC_BODY(vforkdone2, tc) | | 1808 | ATF_TC_BODY(vforkdone2, tc) |
1808 | { | | 1809 | { |
1809 | const int exitval = 5; | | 1810 | const int exitval = 5; |
1810 | const int exitval2 = 15; | | 1811 | const int exitval2 = 15; |
1811 | const int sigval = SIGSTOP; | | 1812 | const int sigval = SIGSTOP; |
1812 | pid_t child, child2, wpid; | | 1813 | pid_t child, child2, wpid; |
1813 | #if defined(TWAIT_HAVE_STATUS) | | 1814 | #if defined(TWAIT_HAVE_STATUS) |
1814 | int status; | | 1815 | int status; |
1815 | #endif | | 1816 | #endif |
1816 | ptrace_state_t state; | | 1817 | ptrace_state_t state; |
1817 | const int slen = sizeof(state); | | 1818 | const int slen = sizeof(state); |
1818 | ptrace_event_t event; | | 1819 | ptrace_event_t event; |
1819 | const int elen = sizeof(event); | | 1820 | const int elen = sizeof(event); |
1820 | | | 1821 | |
1821 | printf("Before forking process PID=%d\n", getpid()); | | 1822 | printf("Before forking process PID=%d\n", getpid()); |
1822 | ATF_REQUIRE((child = fork()) != -1); | | 1823 | ATF_REQUIRE((child = fork()) != -1); |
1823 | if (child == 0) { | | 1824 | if (child == 0) { |
1824 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 1825 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
1825 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 1826 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
1826 | | | 1827 | |
1827 | printf("Before raising %s from child\n", strsignal(sigval)); | | 1828 | printf("Before raising %s from child\n", strsignal(sigval)); |
1828 | FORKEE_ASSERT(raise(sigval) == 0); | | 1829 | FORKEE_ASSERT(raise(sigval) == 0); |
1829 | | | 1830 | |
1830 | FORKEE_ASSERT((child2 = vfork()) != 1); | | 1831 | FORKEE_ASSERT((child2 = vfork()) != 1); |
1831 | | | 1832 | |
1832 | if (child2 == 0) | | 1833 | if (child2 == 0) |
1833 | _exit(exitval2); | | 1834 | _exit(exitval2); |
1834 | | | 1835 | |
1835 | FORKEE_REQUIRE_SUCCESS | | 1836 | FORKEE_REQUIRE_SUCCESS |
1836 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); | | 1837 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); |
1837 | | | 1838 | |
1838 | forkee_status_exited(status, exitval2); | | 1839 | forkee_status_exited(status, exitval2); |
1839 | | | 1840 | |
1840 | printf("Before exiting of the child process\n"); | | 1841 | printf("Before exiting of the child process\n"); |
1841 | _exit(exitval); | | 1842 | _exit(exitval); |
1842 | } | | 1843 | } |
1843 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 1844 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
1844 | | | 1845 | |
1845 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 1846 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
1846 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1847 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1847 | | | 1848 | |
1848 | validate_status_stopped(status, sigval); | | 1849 | validate_status_stopped(status, sigval); |
1849 | | | 1850 | |
1850 | printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); | | 1851 | printf("Enable PTRACE_VFORK in EVENT_MASK for the child %d\n", child); |
1851 | event.pe_set_event = PTRACE_FORK | PTRACE_VFORK_DONE; | | 1852 | event.pe_set_event = PTRACE_FORK | PTRACE_VFORK_DONE; |
1852 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); | | 1853 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); |
1853 | | | 1854 | |
1854 | printf("Before resuming the child process where it left off and " | | 1855 | printf("Before resuming the child process where it left off and " |
1855 | "without signal to be sent\n"); | | 1856 | "without signal to be sent\n"); |
1856 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1857 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1857 | | | 1858 | |
1858 | printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); | | 1859 | printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); |
1859 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1860 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1860 | | | 1861 | |
1861 | validate_status_stopped(status, SIGTRAP); | | 1862 | validate_status_stopped(status, SIGTRAP); |
1862 | | | 1863 | |
1863 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); | | 1864 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); |
1864 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); | | 1865 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_VFORK_DONE); |
1865 | | | 1866 | |
1866 | child2 = state.pe_other_pid; | | 1867 | child2 = state.pe_other_pid; |
1867 | printf("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); | | 1868 | printf("Reported PTRACE_VFORK_DONE event with forkee %d\n", child2); |
1868 | | | 1869 | |
1869 | printf("Before resuming the child process where it left off and " | | 1870 | printf("Before resuming the child process where it left off and " |
1870 | "without signal to be sent\n"); | | 1871 | "without signal to be sent\n"); |
1871 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1872 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1872 | | | 1873 | |
1873 | printf("Before calling %s() for the child - expected stopped " | | 1874 | printf("Before calling %s() for the child - expected stopped " |
1874 | "SIGCHLD\n", TWAIT_FNAME); | | 1875 | "SIGCHLD\n", TWAIT_FNAME); |
1875 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1876 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1876 | | | 1877 | |
1877 | validate_status_stopped(status, SIGCHLD); | | 1878 | validate_status_stopped(status, SIGCHLD); |
1878 | | | 1879 | |
1879 | printf("Before resuming the child process where it left off and " | | 1880 | printf("Before resuming the child process where it left off and " |
1880 | "without signal to be sent\n"); | | 1881 | "without signal to be sent\n"); |
1881 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1882 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1882 | | | 1883 | |
1883 | printf("Before calling %s() for the child - expected exited\n", | | 1884 | printf("Before calling %s() for the child - expected exited\n", |
1884 | TWAIT_FNAME); | | 1885 | TWAIT_FNAME); |
1885 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1886 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1886 | | | 1887 | |
1887 | validate_status_exited(status, exitval); | | 1888 | validate_status_exited(status, exitval); |
1888 | | | 1889 | |
1889 | printf("Before calling %s() for the child - expected no process\n", | | 1890 | printf("Before calling %s() for the child - expected no process\n", |
1890 | TWAIT_FNAME); | | 1891 | TWAIT_FNAME); |
1891 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 1892 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
1892 | } | | 1893 | } |
1893 | | | 1894 | |
1894 | ATF_TC(io_read_d1); | | 1895 | ATF_TC(io_read_d1); |
1895 | ATF_TC_HEAD(io_read_d1, tc) | | 1896 | ATF_TC_HEAD(io_read_d1, tc) |
1896 | { | | 1897 | { |
1897 | atf_tc_set_md_var(tc, "descr", | | 1898 | atf_tc_set_md_var(tc, "descr", |
1898 | "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)"); | | 1899 | "Verify PT_IO with PIOD_READ_D and len = sizeof(uint8_t)"); |
1899 | } | | 1900 | } |
1900 | | | 1901 | |
1901 | ATF_TC_BODY(io_read_d1, tc) | | 1902 | ATF_TC_BODY(io_read_d1, tc) |
1902 | { | | 1903 | { |
1903 | const int exitval = 5; | | 1904 | const int exitval = 5; |
1904 | const int sigval = SIGSTOP; | | 1905 | const int sigval = SIGSTOP; |
1905 | pid_t child, wpid; | | 1906 | pid_t child, wpid; |
1906 | uint8_t lookup_me = 0; | | 1907 | uint8_t lookup_me = 0; |
1907 | const uint8_t magic = 0xab; | | 1908 | const uint8_t magic = 0xab; |
1908 | struct ptrace_io_desc io = { | | 1909 | struct ptrace_io_desc io = { |
1909 | .piod_op = PIOD_READ_D, | | 1910 | .piod_op = PIOD_READ_D, |
1910 | .piod_offs = &lookup_me, | | 1911 | .piod_offs = &lookup_me, |
1911 | .piod_addr = &lookup_me, | | 1912 | .piod_addr = &lookup_me, |
1912 | .piod_len = sizeof(lookup_me) | | 1913 | .piod_len = sizeof(lookup_me) |
1913 | }; | | 1914 | }; |
1914 | #if defined(TWAIT_HAVE_STATUS) | | 1915 | #if defined(TWAIT_HAVE_STATUS) |
1915 | int status; | | 1916 | int status; |
1916 | #endif | | 1917 | #endif |
1917 | | | 1918 | |
1918 | printf("Before forking process PID=%d\n", getpid()); | | 1919 | printf("Before forking process PID=%d\n", getpid()); |
1919 | ATF_REQUIRE((child = fork()) != -1); | | 1920 | ATF_REQUIRE((child = fork()) != -1); |
1920 | if (child == 0) { | | 1921 | if (child == 0) { |
1921 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 1922 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
1922 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 1923 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
1923 | | | 1924 | |
1924 | lookup_me = magic; | | 1925 | lookup_me = magic; |
1925 | | | 1926 | |
1926 | printf("Before raising %s from child\n", strsignal(sigval)); | | 1927 | printf("Before raising %s from child\n", strsignal(sigval)); |
1927 | FORKEE_ASSERT(raise(sigval) == 0); | | 1928 | FORKEE_ASSERT(raise(sigval) == 0); |
1928 | | | 1929 | |
1929 | printf("Before exiting of the child process\n"); | | 1930 | printf("Before exiting of the child process\n"); |
1930 | _exit(exitval); | | 1931 | _exit(exitval); |
1931 | } | | 1932 | } |
1932 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 1933 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
1933 | | | 1934 | |
1934 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 1935 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
1935 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1936 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1936 | | | 1937 | |
1937 | validate_status_stopped(status, sigval); | | 1938 | validate_status_stopped(status, sigval); |
1938 | | | 1939 | |
1939 | printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", | | 1940 | printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", |
1940 | child, getpid()); | | 1941 | child, getpid()); |
1941 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); | | 1942 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); |
1942 | | | 1943 | |
1943 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, | | 1944 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, |
1944 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic); | | 1945 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic); |
1945 | | | 1946 | |
1946 | printf("Before resuming the child process where it left off and " | | 1947 | printf("Before resuming the child process where it left off and " |
1947 | "without signal to be sent\n"); | | 1948 | "without signal to be sent\n"); |
1948 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 1949 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
1949 | | | 1950 | |
1950 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 1951 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
1951 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 1952 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
1952 | | | 1953 | |
1953 | validate_status_exited(status, exitval); | | 1954 | validate_status_exited(status, exitval); |
1954 | | | 1955 | |
1955 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 1956 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
1956 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 1957 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
1957 | } | | 1958 | } |
1958 | | | 1959 | |
1959 | ATF_TC(io_read_d2); | | 1960 | ATF_TC(io_read_d2); |
1960 | ATF_TC_HEAD(io_read_d2, tc) | | 1961 | ATF_TC_HEAD(io_read_d2, tc) |
1961 | { | | 1962 | { |
1962 | atf_tc_set_md_var(tc, "descr", | | 1963 | atf_tc_set_md_var(tc, "descr", |
1963 | "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)"); | | 1964 | "Verify PT_IO with PIOD_READ_D and len = sizeof(uint16_t)"); |
1964 | } | | 1965 | } |
1965 | | | 1966 | |
1966 | ATF_TC_BODY(io_read_d2, tc) | | 1967 | ATF_TC_BODY(io_read_d2, tc) |
1967 | { | | 1968 | { |
1968 | const int exitval = 5; | | 1969 | const int exitval = 5; |
1969 | const int sigval = SIGSTOP; | | 1970 | const int sigval = SIGSTOP; |
1970 | pid_t child, wpid; | | 1971 | pid_t child, wpid; |
1971 | uint16_t lookup_me = 0; | | 1972 | uint16_t lookup_me = 0; |
1972 | const uint16_t magic = 0x1234; | | 1973 | const uint16_t magic = 0x1234; |
1973 | struct ptrace_io_desc io = { | | 1974 | struct ptrace_io_desc io = { |
1974 | .piod_op = PIOD_READ_D, | | 1975 | .piod_op = PIOD_READ_D, |
1975 | .piod_offs = &lookup_me, | | 1976 | .piod_offs = &lookup_me, |
1976 | .piod_addr = &lookup_me, | | 1977 | .piod_addr = &lookup_me, |
1977 | .piod_len = sizeof(lookup_me) | | 1978 | .piod_len = sizeof(lookup_me) |
1978 | }; | | 1979 | }; |
1979 | #if defined(TWAIT_HAVE_STATUS) | | 1980 | #if defined(TWAIT_HAVE_STATUS) |
1980 | int status; | | 1981 | int status; |
1981 | #endif | | 1982 | #endif |
1982 | | | 1983 | |
1983 | printf("Before forking process PID=%d\n", getpid()); | | 1984 | printf("Before forking process PID=%d\n", getpid()); |
1984 | ATF_REQUIRE((child = fork()) != -1); | | 1985 | ATF_REQUIRE((child = fork()) != -1); |
1985 | if (child == 0) { | | 1986 | if (child == 0) { |
1986 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 1987 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
1987 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 1988 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
1988 | | | 1989 | |
1989 | lookup_me = magic; | | 1990 | lookup_me = magic; |
1990 | | | 1991 | |
1991 | printf("Before raising %s from child\n", strsignal(sigval)); | | 1992 | printf("Before raising %s from child\n", strsignal(sigval)); |
1992 | FORKEE_ASSERT(raise(sigval) == 0); | | 1993 | FORKEE_ASSERT(raise(sigval) == 0); |
1993 | | | 1994 | |
1994 | printf("Before exiting of the child process\n"); | | 1995 | printf("Before exiting of the child process\n"); |
1995 | _exit(exitval); | | 1996 | _exit(exitval); |
1996 | } | | 1997 | } |
1997 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 1998 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
1998 | | | 1999 | |
1999 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2000 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2000 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2001 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2001 | | | 2002 | |
2002 | validate_status_stopped(status, sigval); | | 2003 | validate_status_stopped(status, sigval); |
2003 | | | 2004 | |
2004 | printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", | | 2005 | printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", |
2005 | child, getpid()); | | 2006 | child, getpid()); |
2006 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); | | 2007 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); |
2007 | | | 2008 | |
2008 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, | | 2009 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, |
2009 | "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic); | | 2010 | "got value %" PRIx16 " != expected %" PRIx16, lookup_me, magic); |
2010 | | | 2011 | |
2011 | printf("Before resuming the child process where it left off and " | | 2012 | printf("Before resuming the child process where it left off and " |
2012 | "without signal to be sent\n"); | | 2013 | "without signal to be sent\n"); |
2013 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2014 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2014 | | | 2015 | |
2015 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2016 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2016 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2017 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2017 | | | 2018 | |
2018 | validate_status_exited(status, exitval); | | 2019 | validate_status_exited(status, exitval); |
2019 | | | 2020 | |
2020 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2021 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2021 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2022 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2022 | } | | 2023 | } |
2023 | | | 2024 | |
2024 | ATF_TC(io_read_d3); | | 2025 | ATF_TC(io_read_d3); |
2025 | ATF_TC_HEAD(io_read_d3, tc) | | 2026 | ATF_TC_HEAD(io_read_d3, tc) |
2026 | { | | 2027 | { |
2027 | atf_tc_set_md_var(tc, "descr", | | 2028 | atf_tc_set_md_var(tc, "descr", |
2028 | "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)"); | | 2029 | "Verify PT_IO with PIOD_READ_D and len = sizeof(uint32_t)"); |
2029 | } | | 2030 | } |
2030 | | | 2031 | |
2031 | ATF_TC_BODY(io_read_d3, tc) | | 2032 | ATF_TC_BODY(io_read_d3, tc) |
2032 | { | | 2033 | { |
2033 | const int exitval = 5; | | 2034 | const int exitval = 5; |
2034 | const int sigval = SIGSTOP; | | 2035 | const int sigval = SIGSTOP; |
2035 | pid_t child, wpid; | | 2036 | pid_t child, wpid; |
2036 | uint32_t lookup_me = 0; | | 2037 | uint32_t lookup_me = 0; |
2037 | const uint32_t magic = 0x1234abcd; | | 2038 | const uint32_t magic = 0x1234abcd; |
2038 | struct ptrace_io_desc io = { | | 2039 | struct ptrace_io_desc io = { |
2039 | .piod_op = PIOD_READ_D, | | 2040 | .piod_op = PIOD_READ_D, |
2040 | .piod_offs = &lookup_me, | | 2041 | .piod_offs = &lookup_me, |
2041 | .piod_addr = &lookup_me, | | 2042 | .piod_addr = &lookup_me, |
2042 | .piod_len = sizeof(lookup_me) | | 2043 | .piod_len = sizeof(lookup_me) |
2043 | }; | | 2044 | }; |
2044 | #if defined(TWAIT_HAVE_STATUS) | | 2045 | #if defined(TWAIT_HAVE_STATUS) |
2045 | int status; | | 2046 | int status; |
2046 | #endif | | 2047 | #endif |
2047 | | | 2048 | |
2048 | printf("Before forking process PID=%d\n", getpid()); | | 2049 | printf("Before forking process PID=%d\n", getpid()); |
2049 | ATF_REQUIRE((child = fork()) != -1); | | 2050 | ATF_REQUIRE((child = fork()) != -1); |
2050 | if (child == 0) { | | 2051 | if (child == 0) { |
2051 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2052 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2052 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2053 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2053 | | | 2054 | |
2054 | lookup_me = magic; | | 2055 | lookup_me = magic; |
2055 | | | 2056 | |
2056 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2057 | printf("Before raising %s from child\n", strsignal(sigval)); |
2057 | FORKEE_ASSERT(raise(sigval) == 0); | | 2058 | FORKEE_ASSERT(raise(sigval) == 0); |
2058 | | | 2059 | |
2059 | printf("Before exiting of the child process\n"); | | 2060 | printf("Before exiting of the child process\n"); |
2060 | _exit(exitval); | | 2061 | _exit(exitval); |
2061 | } | | 2062 | } |
2062 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2063 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2063 | | | 2064 | |
2064 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2065 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2065 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2066 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2066 | | | 2067 | |
2067 | validate_status_stopped(status, sigval); | | 2068 | validate_status_stopped(status, sigval); |
2068 | | | 2069 | |
2069 | printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", | | 2070 | printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", |
2070 | child, getpid()); | | 2071 | child, getpid()); |
2071 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); | | 2072 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); |
2072 | | | 2073 | |
2073 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, | | 2074 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, |
2074 | "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic); | | 2075 | "got value %" PRIx32 " != expected %" PRIx32, lookup_me, magic); |
2075 | | | 2076 | |
2076 | printf("Before resuming the child process where it left off and " | | 2077 | printf("Before resuming the child process where it left off and " |
2077 | "without signal to be sent\n"); | | 2078 | "without signal to be sent\n"); |
2078 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2079 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2079 | | | 2080 | |
2080 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2081 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2081 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2082 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2082 | | | 2083 | |
2083 | validate_status_exited(status, exitval); | | 2084 | validate_status_exited(status, exitval); |
2084 | | | 2085 | |
2085 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2086 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2086 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2087 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2087 | } | | 2088 | } |
2088 | | | 2089 | |
2089 | ATF_TC(io_read_d4); | | 2090 | ATF_TC(io_read_d4); |
2090 | ATF_TC_HEAD(io_read_d4, tc) | | 2091 | ATF_TC_HEAD(io_read_d4, tc) |
2091 | { | | 2092 | { |
2092 | atf_tc_set_md_var(tc, "descr", | | 2093 | atf_tc_set_md_var(tc, "descr", |
2093 | "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)"); | | 2094 | "Verify PT_IO with PIOD_READ_D and len = sizeof(uint64_t)"); |
2094 | } | | 2095 | } |
2095 | | | 2096 | |
2096 | ATF_TC_BODY(io_read_d4, tc) | | 2097 | ATF_TC_BODY(io_read_d4, tc) |
2097 | { | | 2098 | { |
2098 | const int exitval = 5; | | 2099 | const int exitval = 5; |
2099 | const int sigval = SIGSTOP; | | 2100 | const int sigval = SIGSTOP; |
2100 | pid_t child, wpid; | | 2101 | pid_t child, wpid; |
2101 | uint64_t lookup_me = 0; | | 2102 | uint64_t lookup_me = 0; |
2102 | const uint64_t magic = 0x1234abcd9876dcfa; | | 2103 | const uint64_t magic = 0x1234abcd9876dcfa; |
2103 | struct ptrace_io_desc io = { | | 2104 | struct ptrace_io_desc io = { |
2104 | .piod_op = PIOD_READ_D, | | 2105 | .piod_op = PIOD_READ_D, |
2105 | .piod_offs = &lookup_me, | | 2106 | .piod_offs = &lookup_me, |
2106 | .piod_addr = &lookup_me, | | 2107 | .piod_addr = &lookup_me, |
2107 | .piod_len = sizeof(lookup_me) | | 2108 | .piod_len = sizeof(lookup_me) |
2108 | }; | | 2109 | }; |
2109 | #if defined(TWAIT_HAVE_STATUS) | | 2110 | #if defined(TWAIT_HAVE_STATUS) |
2110 | int status; | | 2111 | int status; |
2111 | #endif | | 2112 | #endif |
2112 | | | 2113 | |
2113 | printf("Before forking process PID=%d\n", getpid()); | | 2114 | printf("Before forking process PID=%d\n", getpid()); |
2114 | ATF_REQUIRE((child = fork()) != -1); | | 2115 | ATF_REQUIRE((child = fork()) != -1); |
2115 | if (child == 0) { | | 2116 | if (child == 0) { |
2116 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2117 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2117 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2118 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2118 | | | 2119 | |
2119 | lookup_me = magic; | | 2120 | lookup_me = magic; |
2120 | | | 2121 | |
2121 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2122 | printf("Before raising %s from child\n", strsignal(sigval)); |
2122 | FORKEE_ASSERT(raise(sigval) == 0); | | 2123 | FORKEE_ASSERT(raise(sigval) == 0); |
2123 | | | 2124 | |
2124 | printf("Before exiting of the child process\n"); | | 2125 | printf("Before exiting of the child process\n"); |
2125 | _exit(exitval); | | 2126 | _exit(exitval); |
2126 | } | | 2127 | } |
2127 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2128 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2128 | | | 2129 | |
2129 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2130 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2130 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2131 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2131 | | | 2132 | |
2132 | validate_status_stopped(status, sigval); | | 2133 | validate_status_stopped(status, sigval); |
2133 | | | 2134 | |
2134 | printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", | | 2135 | printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", |
2135 | child, getpid()); | | 2136 | child, getpid()); |
2136 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); | | 2137 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); |
2137 | | | 2138 | |
2138 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, | | 2139 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, |
2139 | "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic); | | 2140 | "got value %" PRIx64 " != expected %" PRIx64, lookup_me, magic); |
2140 | | | 2141 | |
2141 | printf("Before resuming the child process where it left off and " | | 2142 | printf("Before resuming the child process where it left off and " |
2142 | "without signal to be sent\n"); | | 2143 | "without signal to be sent\n"); |
2143 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2144 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2144 | | | 2145 | |
2145 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2146 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2146 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2147 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2147 | | | 2148 | |
2148 | validate_status_exited(status, exitval); | | 2149 | validate_status_exited(status, exitval); |
2149 | | | 2150 | |
2150 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2151 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2151 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2152 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2152 | } | | 2153 | } |
2153 | | | 2154 | |
2154 | ATF_TC(io_write_d1); | | 2155 | ATF_TC(io_write_d1); |
2155 | ATF_TC_HEAD(io_write_d1, tc) | | 2156 | ATF_TC_HEAD(io_write_d1, tc) |
2156 | { | | 2157 | { |
2157 | atf_tc_set_md_var(tc, "descr", | | 2158 | atf_tc_set_md_var(tc, "descr", |
2158 | "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)"); | | 2159 | "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint8_t)"); |
2159 | } | | 2160 | } |
2160 | | | 2161 | |
2161 | ATF_TC_BODY(io_write_d1, tc) | | 2162 | ATF_TC_BODY(io_write_d1, tc) |
2162 | { | | 2163 | { |
2163 | const int exitval = 5; | | 2164 | const int exitval = 5; |
2164 | const int sigval = SIGSTOP; | | 2165 | const int sigval = SIGSTOP; |
2165 | pid_t child, wpid; | | 2166 | pid_t child, wpid; |
2166 | uint8_t lookup_me = 0; | | 2167 | uint8_t lookup_me = 0; |
2167 | const uint8_t magic = 0xab; | | 2168 | const uint8_t magic = 0xab; |
2168 | struct ptrace_io_desc io = { | | 2169 | struct ptrace_io_desc io = { |
2169 | .piod_op = PIOD_WRITE_D, | | 2170 | .piod_op = PIOD_WRITE_D, |
2170 | .piod_offs = &lookup_me, | | 2171 | .piod_offs = &lookup_me, |
2171 | .piod_addr = &lookup_me, | | 2172 | .piod_addr = &lookup_me, |
2172 | .piod_len = sizeof(lookup_me) | | 2173 | .piod_len = sizeof(lookup_me) |
2173 | }; | | 2174 | }; |
2174 | #if defined(TWAIT_HAVE_STATUS) | | 2175 | #if defined(TWAIT_HAVE_STATUS) |
2175 | int status; | | 2176 | int status; |
2176 | #endif | | 2177 | #endif |
2177 | | | 2178 | |
2178 | printf("Before forking process PID=%d\n", getpid()); | | 2179 | printf("Before forking process PID=%d\n", getpid()); |
2179 | ATF_REQUIRE((child = fork()) != -1); | | 2180 | ATF_REQUIRE((child = fork()) != -1); |
2180 | if (child == 0) { | | 2181 | if (child == 0) { |
2181 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2182 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2182 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2183 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2183 | | | 2184 | |
2184 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2185 | printf("Before raising %s from child\n", strsignal(sigval)); |
2185 | FORKEE_ASSERT(raise(sigval) == 0); | | 2186 | FORKEE_ASSERT(raise(sigval) == 0); |
2186 | | | 2187 | |
2187 | FORKEE_ASSERT_EQ(lookup_me, magic); | | 2188 | FORKEE_ASSERT_EQ(lookup_me, magic); |
2188 | | | 2189 | |
2189 | printf("Before exiting of the child process\n"); | | 2190 | printf("Before exiting of the child process\n"); |
2190 | _exit(exitval); | | 2191 | _exit(exitval); |
2191 | } | | 2192 | } |
2192 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2193 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2193 | | | 2194 | |
2194 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2195 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2195 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2196 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2196 | | | 2197 | |
2197 | validate_status_stopped(status, sigval); | | 2198 | validate_status_stopped(status, sigval); |
2198 | | | 2199 | |
2199 | lookup_me = magic; | | 2200 | lookup_me = magic; |
2200 | | | 2201 | |
2201 | printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", | | 2202 | printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", |
2202 | child, getpid()); | | 2203 | child, getpid()); |
2203 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); | | 2204 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); |
2204 | | | 2205 | |
2205 | printf("Before resuming the child process where it left off and " | | 2206 | printf("Before resuming the child process where it left off and " |
2206 | "without signal to be sent\n"); | | 2207 | "without signal to be sent\n"); |
2207 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2208 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2208 | | | 2209 | |
2209 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2210 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2210 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2211 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2211 | | | 2212 | |
2212 | validate_status_exited(status, exitval); | | 2213 | validate_status_exited(status, exitval); |
2213 | | | 2214 | |
2214 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2215 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2215 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2216 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2216 | } | | 2217 | } |
2217 | | | 2218 | |
2218 | ATF_TC(io_write_d2); | | 2219 | ATF_TC(io_write_d2); |
2219 | ATF_TC_HEAD(io_write_d2, tc) | | 2220 | ATF_TC_HEAD(io_write_d2, tc) |
2220 | { | | 2221 | { |
2221 | atf_tc_set_md_var(tc, "descr", | | 2222 | atf_tc_set_md_var(tc, "descr", |
2222 | "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)"); | | 2223 | "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint16_t)"); |
2223 | } | | 2224 | } |
2224 | | | 2225 | |
2225 | ATF_TC_BODY(io_write_d2, tc) | | 2226 | ATF_TC_BODY(io_write_d2, tc) |
2226 | { | | 2227 | { |
2227 | const int exitval = 5; | | 2228 | const int exitval = 5; |
2228 | const int sigval = SIGSTOP; | | 2229 | const int sigval = SIGSTOP; |
2229 | pid_t child, wpid; | | 2230 | pid_t child, wpid; |
2230 | uint16_t lookup_me = 0; | | 2231 | uint16_t lookup_me = 0; |
2231 | const uint16_t magic = 0xab12; | | 2232 | const uint16_t magic = 0xab12; |
2232 | struct ptrace_io_desc io = { | | 2233 | struct ptrace_io_desc io = { |
2233 | .piod_op = PIOD_WRITE_D, | | 2234 | .piod_op = PIOD_WRITE_D, |
2234 | .piod_offs = &lookup_me, | | 2235 | .piod_offs = &lookup_me, |
2235 | .piod_addr = &lookup_me, | | 2236 | .piod_addr = &lookup_me, |
2236 | .piod_len = sizeof(lookup_me) | | 2237 | .piod_len = sizeof(lookup_me) |
2237 | }; | | 2238 | }; |
2238 | #if defined(TWAIT_HAVE_STATUS) | | 2239 | #if defined(TWAIT_HAVE_STATUS) |
2239 | int status; | | 2240 | int status; |
2240 | #endif | | 2241 | #endif |
2241 | | | 2242 | |
2242 | printf("Before forking process PID=%d\n", getpid()); | | 2243 | printf("Before forking process PID=%d\n", getpid()); |
2243 | ATF_REQUIRE((child = fork()) != -1); | | 2244 | ATF_REQUIRE((child = fork()) != -1); |
2244 | if (child == 0) { | | 2245 | if (child == 0) { |
2245 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2246 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2246 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2247 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2247 | | | 2248 | |
2248 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2249 | printf("Before raising %s from child\n", strsignal(sigval)); |
2249 | FORKEE_ASSERT(raise(sigval) == 0); | | 2250 | FORKEE_ASSERT(raise(sigval) == 0); |
2250 | | | 2251 | |
2251 | FORKEE_ASSERT_EQ(lookup_me, magic); | | 2252 | FORKEE_ASSERT_EQ(lookup_me, magic); |
2252 | | | 2253 | |
2253 | printf("Before exiting of the child process\n"); | | 2254 | printf("Before exiting of the child process\n"); |
2254 | _exit(exitval); | | 2255 | _exit(exitval); |
2255 | } | | 2256 | } |
2256 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2257 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2257 | | | 2258 | |
2258 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2259 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2259 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2260 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2260 | | | 2261 | |
2261 | validate_status_stopped(status, sigval); | | 2262 | validate_status_stopped(status, sigval); |
2262 | | | 2263 | |
2263 | lookup_me = magic; | | 2264 | lookup_me = magic; |
2264 | | | 2265 | |
2265 | printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", | | 2266 | printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", |
2266 | child, getpid()); | | 2267 | child, getpid()); |
2267 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); | | 2268 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); |
2268 | | | 2269 | |
2269 | printf("Before resuming the child process where it left off and " | | 2270 | printf("Before resuming the child process where it left off and " |
2270 | "without signal to be sent\n"); | | 2271 | "without signal to be sent\n"); |
2271 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2272 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2272 | | | 2273 | |
2273 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2274 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2274 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2275 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2275 | | | 2276 | |
2276 | validate_status_exited(status, exitval); | | 2277 | validate_status_exited(status, exitval); |
2277 | | | 2278 | |
2278 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2279 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2279 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2280 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2280 | } | | 2281 | } |
2281 | | | 2282 | |
2282 | ATF_TC(io_write_d3); | | 2283 | ATF_TC(io_write_d3); |
2283 | ATF_TC_HEAD(io_write_d3, tc) | | 2284 | ATF_TC_HEAD(io_write_d3, tc) |
2284 | { | | 2285 | { |
2285 | atf_tc_set_md_var(tc, "descr", | | 2286 | atf_tc_set_md_var(tc, "descr", |
2286 | "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)"); | | 2287 | "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint32_t)"); |
2287 | } | | 2288 | } |
2288 | | | 2289 | |
2289 | ATF_TC_BODY(io_write_d3, tc) | | 2290 | ATF_TC_BODY(io_write_d3, tc) |
2290 | { | | 2291 | { |
2291 | const int exitval = 5; | | 2292 | const int exitval = 5; |
2292 | const int sigval = SIGSTOP; | | 2293 | const int sigval = SIGSTOP; |
2293 | pid_t child, wpid; | | 2294 | pid_t child, wpid; |
2294 | uint32_t lookup_me = 0; | | 2295 | uint32_t lookup_me = 0; |
2295 | const uint32_t magic = 0xab127643; | | 2296 | const uint32_t magic = 0xab127643; |
2296 | struct ptrace_io_desc io = { | | 2297 | struct ptrace_io_desc io = { |
2297 | .piod_op = PIOD_WRITE_D, | | 2298 | .piod_op = PIOD_WRITE_D, |
2298 | .piod_offs = &lookup_me, | | 2299 | .piod_offs = &lookup_me, |
2299 | .piod_addr = &lookup_me, | | 2300 | .piod_addr = &lookup_me, |
2300 | .piod_len = sizeof(lookup_me) | | 2301 | .piod_len = sizeof(lookup_me) |
2301 | }; | | 2302 | }; |
2302 | #if defined(TWAIT_HAVE_STATUS) | | 2303 | #if defined(TWAIT_HAVE_STATUS) |
2303 | int status; | | 2304 | int status; |
2304 | #endif | | 2305 | #endif |
2305 | | | 2306 | |
2306 | printf("Before forking process PID=%d\n", getpid()); | | 2307 | printf("Before forking process PID=%d\n", getpid()); |
2307 | ATF_REQUIRE((child = fork()) != -1); | | 2308 | ATF_REQUIRE((child = fork()) != -1); |
2308 | if (child == 0) { | | 2309 | if (child == 0) { |
2309 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2310 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2310 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2311 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2311 | | | 2312 | |
2312 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2313 | printf("Before raising %s from child\n", strsignal(sigval)); |
2313 | FORKEE_ASSERT(raise(sigval) == 0); | | 2314 | FORKEE_ASSERT(raise(sigval) == 0); |
2314 | | | 2315 | |
2315 | FORKEE_ASSERT_EQ(lookup_me, magic); | | 2316 | FORKEE_ASSERT_EQ(lookup_me, magic); |
2316 | | | 2317 | |
2317 | printf("Before exiting of the child process\n"); | | 2318 | printf("Before exiting of the child process\n"); |
2318 | _exit(exitval); | | 2319 | _exit(exitval); |
2319 | } | | 2320 | } |
2320 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2321 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2321 | | | 2322 | |
2322 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2323 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2323 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2324 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2324 | | | 2325 | |
2325 | validate_status_stopped(status, sigval); | | 2326 | validate_status_stopped(status, sigval); |
2326 | | | 2327 | |
2327 | lookup_me = magic; | | 2328 | lookup_me = magic; |
2328 | | | 2329 | |
2329 | printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", | | 2330 | printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", |
2330 | child, getpid()); | | 2331 | child, getpid()); |
2331 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); | | 2332 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); |
2332 | | | 2333 | |
2333 | printf("Before resuming the child process where it left off and " | | 2334 | printf("Before resuming the child process where it left off and " |
2334 | "without signal to be sent\n"); | | 2335 | "without signal to be sent\n"); |
2335 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2336 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2336 | | | 2337 | |
2337 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2338 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2338 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2339 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2339 | | | 2340 | |
2340 | validate_status_exited(status, exitval); | | 2341 | validate_status_exited(status, exitval); |
2341 | | | 2342 | |
2342 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2343 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2343 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2344 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2344 | } | | 2345 | } |
2345 | | | 2346 | |
2346 | ATF_TC(io_write_d4); | | 2347 | ATF_TC(io_write_d4); |
2347 | ATF_TC_HEAD(io_write_d4, tc) | | 2348 | ATF_TC_HEAD(io_write_d4, tc) |
2348 | { | | 2349 | { |
2349 | atf_tc_set_md_var(tc, "descr", | | 2350 | atf_tc_set_md_var(tc, "descr", |
2350 | "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)"); | | 2351 | "Verify PT_IO with PIOD_WRITE_D and len = sizeof(uint64_t)"); |
2351 | } | | 2352 | } |
2352 | | | 2353 | |
2353 | ATF_TC_BODY(io_write_d4, tc) | | 2354 | ATF_TC_BODY(io_write_d4, tc) |
2354 | { | | 2355 | { |
2355 | const int exitval = 5; | | 2356 | const int exitval = 5; |
2356 | const int sigval = SIGSTOP; | | 2357 | const int sigval = SIGSTOP; |
2357 | pid_t child, wpid; | | 2358 | pid_t child, wpid; |
2358 | uint64_t lookup_me = 0; | | 2359 | uint64_t lookup_me = 0; |
2359 | const uint64_t magic = 0xab12764376490123; | | 2360 | const uint64_t magic = 0xab12764376490123; |
2360 | struct ptrace_io_desc io = { | | 2361 | struct ptrace_io_desc io = { |
2361 | .piod_op = PIOD_WRITE_D, | | 2362 | .piod_op = PIOD_WRITE_D, |
2362 | .piod_offs = &lookup_me, | | 2363 | .piod_offs = &lookup_me, |
2363 | .piod_addr = &lookup_me, | | 2364 | .piod_addr = &lookup_me, |
2364 | .piod_len = sizeof(lookup_me) | | 2365 | .piod_len = sizeof(lookup_me) |
2365 | }; | | 2366 | }; |
2366 | #if defined(TWAIT_HAVE_STATUS) | | 2367 | #if defined(TWAIT_HAVE_STATUS) |
2367 | int status; | | 2368 | int status; |
2368 | #endif | | 2369 | #endif |
2369 | | | 2370 | |
2370 | printf("Before forking process PID=%d\n", getpid()); | | 2371 | printf("Before forking process PID=%d\n", getpid()); |
2371 | ATF_REQUIRE((child = fork()) != -1); | | 2372 | ATF_REQUIRE((child = fork()) != -1); |
2372 | if (child == 0) { | | 2373 | if (child == 0) { |
2373 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2374 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2374 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2375 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2375 | | | 2376 | |
2376 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2377 | printf("Before raising %s from child\n", strsignal(sigval)); |
2377 | FORKEE_ASSERT(raise(sigval) == 0); | | 2378 | FORKEE_ASSERT(raise(sigval) == 0); |
2378 | | | 2379 | |
2379 | FORKEE_ASSERT_EQ(lookup_me, magic); | | 2380 | FORKEE_ASSERT_EQ(lookup_me, magic); |
2380 | | | 2381 | |
2381 | printf("Before exiting of the child process\n"); | | 2382 | printf("Before exiting of the child process\n"); |
2382 | _exit(exitval); | | 2383 | _exit(exitval); |
2383 | } | | 2384 | } |
2384 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2385 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2385 | | | 2386 | |
2386 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2387 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2387 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2388 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2388 | | | 2389 | |
2389 | validate_status_stopped(status, sigval); | | 2390 | validate_status_stopped(status, sigval); |
2390 | | | 2391 | |
2391 | lookup_me = magic; | | 2392 | lookup_me = magic; |
2392 | | | 2393 | |
2393 | printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", | | 2394 | printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", |
2394 | child, getpid()); | | 2395 | child, getpid()); |
2395 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); | | 2396 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); |
2396 | | | 2397 | |
2397 | printf("Before resuming the child process where it left off and " | | 2398 | printf("Before resuming the child process where it left off and " |
2398 | "without signal to be sent\n"); | | 2399 | "without signal to be sent\n"); |
2399 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2400 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2400 | | | 2401 | |
2401 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2402 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2402 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2403 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2403 | | | 2404 | |
2404 | validate_status_exited(status, exitval); | | 2405 | validate_status_exited(status, exitval); |
2405 | | | 2406 | |
2406 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2407 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2407 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2408 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2408 | } | | 2409 | } |
2409 | | | 2410 | |
| | | 2411 | ATF_TC(io_read_auxv1); |
| | | 2412 | ATF_TC_HEAD(io_read_auxv1, tc) |
| | | 2413 | { |
| | | 2414 | atf_tc_set_md_var(tc, "descr", |
| | | 2415 | "Verify PT_READ_AUXV called for tracee"); |
| | | 2416 | } |
| | | 2417 | |
| | | 2418 | ATF_TC_BODY(io_read_auxv1, tc) |
| | | 2419 | { |
| | | 2420 | const int exitval = 5; |
| | | 2421 | const int sigval = SIGSTOP; |
| | | 2422 | pid_t child, wpid; |
| | | 2423 | #if defined(TWAIT_HAVE_STATUS) |
| | | 2424 | int status; |
| | | 2425 | #endif |
| | | 2426 | AuxInfo ai[100], *aip; |
| | | 2427 | struct ptrace_io_desc io = { |
| | | 2428 | .piod_op = PIOD_READ_AUXV, |
| | | 2429 | .piod_offs = 0, |
| | | 2430 | .piod_addr = ai, |
| | | 2431 | .piod_len = sizeof(ai) |
| | | 2432 | }; |
| | | 2433 | |
| | | 2434 | printf("Before forking process PID=%d\n", getpid()); |
| | | 2435 | ATF_REQUIRE((child = fork()) != -1); |
| | | 2436 | if (child == 0) { |
| | | 2437 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
| | | 2438 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
| | | 2439 | |
| | | 2440 | printf("Before raising %s from child\n", strsignal(sigval)); |
| | | 2441 | FORKEE_ASSERT(raise(sigval) == 0); |
| | | 2442 | |
| | | 2443 | printf("Before exiting of the child process\n"); |
| | | 2444 | _exit(exitval); |
| | | 2445 | } |
| | | 2446 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
| | | 2447 | |
| | | 2448 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
| | | 2449 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
| | | 2450 | |
| | | 2451 | validate_status_stopped(status, sigval); |
| | | 2452 | |
| | | 2453 | printf("Read new AUXV from tracee (PID=%d) by tracer (PID=%d)\n", |
| | | 2454 | child, getpid()); |
| | | 2455 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); |
| | | 2456 | |
| | | 2457 | printf("Asserting that AUXV length (%zu) is > 0\n", io.piod_len); |
| | | 2458 | ATF_REQUIRE(io.piod_len > 0); |
| | | 2459 | |
| | | 2460 | for (aip = ai; aip->a_type != AT_NULL; aip++) |
| | | 2461 | printf("a_type=%#llx a_v=%#llx\n", |
| | | 2462 | (long long int)aip->a_type, (long long int)aip->a_v); |
| | | 2463 | |
| | | 2464 | printf("Before resuming the child process where it left off and " |
| | | 2465 | "without signal to be sent\n"); |
| | | 2466 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
| | | 2467 | |
| | | 2468 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
| | | 2469 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
| | | 2470 | |
| | | 2471 | validate_status_exited(status, exitval); |
| | | 2472 | |
| | | 2473 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
| | | 2474 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
| | | 2475 | } |
| | | 2476 | |
2410 | ATF_TC(read_d1); | | 2477 | ATF_TC(read_d1); |
2411 | ATF_TC_HEAD(read_d1, tc) | | 2478 | ATF_TC_HEAD(read_d1, tc) |
2412 | { | | 2479 | { |
2413 | atf_tc_set_md_var(tc, "descr", | | 2480 | atf_tc_set_md_var(tc, "descr", |
2414 | "Verify PT_READ_D called once"); | | 2481 | "Verify PT_READ_D called once"); |
2415 | } | | 2482 | } |
2416 | | | 2483 | |
2417 | ATF_TC_BODY(read_d1, tc) | | 2484 | ATF_TC_BODY(read_d1, tc) |
2418 | { | | 2485 | { |
2419 | const int exitval = 5; | | 2486 | const int exitval = 5; |
2420 | const int sigval = SIGSTOP; | | 2487 | const int sigval = SIGSTOP; |
2421 | pid_t child, wpid; | | 2488 | pid_t child, wpid; |
2422 | int lookup_me = 0; | | 2489 | int lookup_me = 0; |
2423 | const int magic = (int)random(); | | 2490 | const int magic = (int)random(); |
2424 | #if defined(TWAIT_HAVE_STATUS) | | 2491 | #if defined(TWAIT_HAVE_STATUS) |
2425 | int status; | | 2492 | int status; |
2426 | #endif | | 2493 | #endif |
2427 | | | 2494 | |
2428 | printf("Before forking process PID=%d\n", getpid()); | | 2495 | printf("Before forking process PID=%d\n", getpid()); |
2429 | ATF_REQUIRE((child = fork()) != -1); | | 2496 | ATF_REQUIRE((child = fork()) != -1); |
2430 | if (child == 0) { | | 2497 | if (child == 0) { |
2431 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2498 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2432 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2499 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2433 | | | 2500 | |
2434 | lookup_me = magic; | | 2501 | lookup_me = magic; |
2435 | | | 2502 | |
2436 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2503 | printf("Before raising %s from child\n", strsignal(sigval)); |
2437 | FORKEE_ASSERT(raise(sigval) == 0); | | 2504 | FORKEE_ASSERT(raise(sigval) == 0); |
2438 | | | 2505 | |
2439 | printf("Before exiting of the child process\n"); | | 2506 | printf("Before exiting of the child process\n"); |
2440 | _exit(exitval); | | 2507 | _exit(exitval); |
2441 | } | | 2508 | } |
2442 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2509 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2443 | | | 2510 | |
2444 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2511 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2445 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2512 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2446 | | | 2513 | |
2447 | validate_status_stopped(status, sigval); | | 2514 | validate_status_stopped(status, sigval); |
2448 | | | 2515 | |
2449 | printf("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", | | 2516 | printf("Read new lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", |
2450 | child, getpid()); | | 2517 | child, getpid()); |
2451 | errno = 0; | | 2518 | errno = 0; |
2452 | lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0); | | 2519 | lookup_me = ptrace(PT_READ_D, child, &lookup_me, 0); |
2453 | ATF_REQUIRE_EQ(errno, 0); | | 2520 | ATF_REQUIRE_EQ(errno, 0); |
2454 | | | 2521 | |
2455 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, | | 2522 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, |
2456 | "got value %#x != expected %#x", lookup_me, magic); | | 2523 | "got value %#x != expected %#x", lookup_me, magic); |
2457 | | | 2524 | |
2458 | printf("Before resuming the child process where it left off and " | | 2525 | printf("Before resuming the child process where it left off and " |
2459 | "without signal to be sent\n"); | | 2526 | "without signal to be sent\n"); |
2460 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2527 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2461 | | | 2528 | |
2462 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2529 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2463 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2530 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2464 | | | 2531 | |
2465 | validate_status_exited(status, exitval); | | 2532 | validate_status_exited(status, exitval); |
2466 | | | 2533 | |
2467 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2534 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2468 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2535 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2469 | } | | 2536 | } |
2470 | | | 2537 | |
2471 | ATF_TC(read_d2); | | 2538 | ATF_TC(read_d2); |
2472 | ATF_TC_HEAD(read_d2, tc) | | 2539 | ATF_TC_HEAD(read_d2, tc) |
2473 | { | | 2540 | { |
2474 | atf_tc_set_md_var(tc, "descr", | | 2541 | atf_tc_set_md_var(tc, "descr", |
2475 | "Verify PT_READ_D called twice"); | | 2542 | "Verify PT_READ_D called twice"); |
2476 | } | | 2543 | } |
2477 | | | 2544 | |
2478 | ATF_TC_BODY(read_d2, tc) | | 2545 | ATF_TC_BODY(read_d2, tc) |
2479 | { | | 2546 | { |
2480 | const int exitval = 5; | | 2547 | const int exitval = 5; |
2481 | const int sigval = SIGSTOP; | | 2548 | const int sigval = SIGSTOP; |
2482 | pid_t child, wpid; | | 2549 | pid_t child, wpid; |
2483 | int lookup_me1 = 0; | | 2550 | int lookup_me1 = 0; |
2484 | int lookup_me2 = 0; | | 2551 | int lookup_me2 = 0; |
2485 | const int magic1 = (int)random(); | | 2552 | const int magic1 = (int)random(); |
2486 | const int magic2 = (int)random(); | | 2553 | const int magic2 = (int)random(); |
2487 | #if defined(TWAIT_HAVE_STATUS) | | 2554 | #if defined(TWAIT_HAVE_STATUS) |
2488 | int status; | | 2555 | int status; |
2489 | #endif | | 2556 | #endif |
2490 | | | 2557 | |
2491 | printf("Before forking process PID=%d\n", getpid()); | | 2558 | printf("Before forking process PID=%d\n", getpid()); |
2492 | ATF_REQUIRE((child = fork()) != -1); | | 2559 | ATF_REQUIRE((child = fork()) != -1); |
2493 | if (child == 0) { | | 2560 | if (child == 0) { |
2494 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2561 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2495 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2562 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2496 | | | 2563 | |
2497 | lookup_me1 = magic1; | | 2564 | lookup_me1 = magic1; |
2498 | lookup_me2 = magic2; | | 2565 | lookup_me2 = magic2; |
2499 | | | 2566 | |
2500 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2567 | printf("Before raising %s from child\n", strsignal(sigval)); |
2501 | FORKEE_ASSERT(raise(sigval) == 0); | | 2568 | FORKEE_ASSERT(raise(sigval) == 0); |
2502 | | | 2569 | |
2503 | printf("Before exiting of the child process\n"); | | 2570 | printf("Before exiting of the child process\n"); |
2504 | _exit(exitval); | | 2571 | _exit(exitval); |
2505 | } | | 2572 | } |
2506 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2573 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2507 | | | 2574 | |
2508 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2575 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2509 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2576 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2510 | | | 2577 | |
2511 | validate_status_stopped(status, sigval); | | 2578 | validate_status_stopped(status, sigval); |
2512 | | | 2579 | |
2513 | printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", | | 2580 | printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", |
2514 | child, getpid()); | | 2581 | child, getpid()); |
2515 | errno = 0; | | 2582 | errno = 0; |
2516 | lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); | | 2583 | lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); |
2517 | ATF_REQUIRE_EQ(errno, 0); | | 2584 | ATF_REQUIRE_EQ(errno, 0); |
2518 | | | 2585 | |
2519 | ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, | | 2586 | ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, |
2520 | "got value %#x != expected %#x", lookup_me1, magic1); | | 2587 | "got value %#x != expected %#x", lookup_me1, magic1); |
2521 | | | 2588 | |
2522 | printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", | | 2589 | printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", |
2523 | child, getpid()); | | 2590 | child, getpid()); |
2524 | errno = 0; | | 2591 | errno = 0; |
2525 | lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); | | 2592 | lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); |
2526 | ATF_REQUIRE_EQ(errno, 0); | | 2593 | ATF_REQUIRE_EQ(errno, 0); |
2527 | | | 2594 | |
2528 | ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, | | 2595 | ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, |
2529 | "got value %#x != expected %#x", lookup_me2, magic2); | | 2596 | "got value %#x != expected %#x", lookup_me2, magic2); |
2530 | | | 2597 | |
2531 | printf("Before resuming the child process where it left off and " | | 2598 | printf("Before resuming the child process where it left off and " |
2532 | "without signal to be sent\n"); | | 2599 | "without signal to be sent\n"); |
2533 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2600 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2534 | | | 2601 | |
2535 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2602 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2536 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2603 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2537 | | | 2604 | |
2538 | validate_status_exited(status, exitval); | | 2605 | validate_status_exited(status, exitval); |
2539 | | | 2606 | |
2540 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2607 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2541 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2608 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2542 | } | | 2609 | } |
2543 | | | 2610 | |
2544 | ATF_TC(read_d3); | | 2611 | ATF_TC(read_d3); |
2545 | ATF_TC_HEAD(read_d3, tc) | | 2612 | ATF_TC_HEAD(read_d3, tc) |
2546 | { | | 2613 | { |
2547 | atf_tc_set_md_var(tc, "descr", | | 2614 | atf_tc_set_md_var(tc, "descr", |
2548 | "Verify PT_READ_D called three times"); | | 2615 | "Verify PT_READ_D called three times"); |
2549 | } | | 2616 | } |
2550 | | | 2617 | |
2551 | ATF_TC_BODY(read_d3, tc) | | 2618 | ATF_TC_BODY(read_d3, tc) |
2552 | { | | 2619 | { |
2553 | const int exitval = 5; | | 2620 | const int exitval = 5; |
2554 | const int sigval = SIGSTOP; | | 2621 | const int sigval = SIGSTOP; |
2555 | pid_t child, wpid; | | 2622 | pid_t child, wpid; |
2556 | int lookup_me1 = 0; | | 2623 | int lookup_me1 = 0; |
2557 | int lookup_me2 = 0; | | 2624 | int lookup_me2 = 0; |
2558 | int lookup_me3 = 0; | | 2625 | int lookup_me3 = 0; |
2559 | const int magic1 = (int)random(); | | 2626 | const int magic1 = (int)random(); |
2560 | const int magic2 = (int)random(); | | 2627 | const int magic2 = (int)random(); |
2561 | const int magic3 = (int)random(); | | 2628 | const int magic3 = (int)random(); |
2562 | #if defined(TWAIT_HAVE_STATUS) | | 2629 | #if defined(TWAIT_HAVE_STATUS) |
2563 | int status; | | 2630 | int status; |
2564 | #endif | | 2631 | #endif |
2565 | | | 2632 | |
2566 | printf("Before forking process PID=%d\n", getpid()); | | 2633 | printf("Before forking process PID=%d\n", getpid()); |
2567 | ATF_REQUIRE((child = fork()) != -1); | | 2634 | ATF_REQUIRE((child = fork()) != -1); |
2568 | if (child == 0) { | | 2635 | if (child == 0) { |
2569 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2636 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2570 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2637 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2571 | | | 2638 | |
2572 | lookup_me1 = magic1; | | 2639 | lookup_me1 = magic1; |
2573 | lookup_me2 = magic2; | | 2640 | lookup_me2 = magic2; |
2574 | lookup_me3 = magic3; | | 2641 | lookup_me3 = magic3; |
2575 | | | 2642 | |
2576 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2643 | printf("Before raising %s from child\n", strsignal(sigval)); |
2577 | FORKEE_ASSERT(raise(sigval) == 0); | | 2644 | FORKEE_ASSERT(raise(sigval) == 0); |
2578 | | | 2645 | |
2579 | printf("Before exiting of the child process\n"); | | 2646 | printf("Before exiting of the child process\n"); |
2580 | _exit(exitval); | | 2647 | _exit(exitval); |
2581 | } | | 2648 | } |
2582 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2649 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2583 | | | 2650 | |
2584 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2651 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2585 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2652 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2586 | | | 2653 | |
2587 | validate_status_stopped(status, sigval); | | 2654 | validate_status_stopped(status, sigval); |
2588 | | | 2655 | |
2589 | printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", | | 2656 | printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", |
2590 | child, getpid()); | | 2657 | child, getpid()); |
2591 | errno = 0; | | 2658 | errno = 0; |
2592 | lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); | | 2659 | lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); |
2593 | ATF_REQUIRE_EQ(errno, 0); | | 2660 | ATF_REQUIRE_EQ(errno, 0); |
2594 | | | 2661 | |
2595 | ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, | | 2662 | ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, |
2596 | "got value %#x != expected %#x", lookup_me1, magic1); | | 2663 | "got value %#x != expected %#x", lookup_me1, magic1); |
2597 | | | 2664 | |
2598 | printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", | | 2665 | printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", |
2599 | child, getpid()); | | 2666 | child, getpid()); |
2600 | errno = 0; | | 2667 | errno = 0; |
2601 | lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); | | 2668 | lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); |
2602 | ATF_REQUIRE_EQ(errno, 0); | | 2669 | ATF_REQUIRE_EQ(errno, 0); |
2603 | | | 2670 | |
2604 | ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, | | 2671 | ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, |
2605 | "got value %#x != expected %#x", lookup_me2, magic2); | | 2672 | "got value %#x != expected %#x", lookup_me2, magic2); |
2606 | | | 2673 | |
2607 | printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", | | 2674 | printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", |
2608 | child, getpid()); | | 2675 | child, getpid()); |
2609 | errno = 0; | | 2676 | errno = 0; |
2610 | lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0); | | 2677 | lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0); |
2611 | ATF_REQUIRE_EQ(errno, 0); | | 2678 | ATF_REQUIRE_EQ(errno, 0); |
2612 | | | 2679 | |
2613 | ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, | | 2680 | ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, |
2614 | "got value %#x != expected %#x", lookup_me3, magic3); | | 2681 | "got value %#x != expected %#x", lookup_me3, magic3); |
2615 | | | 2682 | |
2616 | printf("Before resuming the child process where it left off and " | | 2683 | printf("Before resuming the child process where it left off and " |
2617 | "without signal to be sent\n"); | | 2684 | "without signal to be sent\n"); |
2618 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2685 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2619 | | | 2686 | |
2620 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2687 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2621 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2688 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2622 | | | 2689 | |
2623 | validate_status_exited(status, exitval); | | 2690 | validate_status_exited(status, exitval); |
2624 | | | 2691 | |
2625 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2692 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2626 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2693 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2627 | } | | 2694 | } |
2628 | | | 2695 | |
2629 | ATF_TC(read_d4); | | 2696 | ATF_TC(read_d4); |
2630 | ATF_TC_HEAD(read_d4, tc) | | 2697 | ATF_TC_HEAD(read_d4, tc) |
2631 | { | | 2698 | { |
2632 | atf_tc_set_md_var(tc, "descr", | | 2699 | atf_tc_set_md_var(tc, "descr", |
2633 | "Verify PT_READ_D called four times"); | | 2700 | "Verify PT_READ_D called four times"); |
2634 | } | | 2701 | } |
2635 | | | 2702 | |
2636 | ATF_TC_BODY(read_d4, tc) | | 2703 | ATF_TC_BODY(read_d4, tc) |
2637 | { | | 2704 | { |
2638 | const int exitval = 5; | | 2705 | const int exitval = 5; |
2639 | const int sigval = SIGSTOP; | | 2706 | const int sigval = SIGSTOP; |
2640 | pid_t child, wpid; | | 2707 | pid_t child, wpid; |
2641 | int lookup_me1 = 0; | | 2708 | int lookup_me1 = 0; |
2642 | int lookup_me2 = 0; | | 2709 | int lookup_me2 = 0; |
2643 | int lookup_me3 = 0; | | 2710 | int lookup_me3 = 0; |
2644 | int lookup_me4 = 0; | | 2711 | int lookup_me4 = 0; |
2645 | const int magic1 = (int)random(); | | 2712 | const int magic1 = (int)random(); |
2646 | const int magic2 = (int)random(); | | 2713 | const int magic2 = (int)random(); |
2647 | const int magic3 = (int)random(); | | 2714 | const int magic3 = (int)random(); |
2648 | const int magic4 = (int)random(); | | 2715 | const int magic4 = (int)random(); |
2649 | #if defined(TWAIT_HAVE_STATUS) | | 2716 | #if defined(TWAIT_HAVE_STATUS) |
2650 | int status; | | 2717 | int status; |
2651 | #endif | | 2718 | #endif |
2652 | | | 2719 | |
2653 | printf("Before forking process PID=%d\n", getpid()); | | 2720 | printf("Before forking process PID=%d\n", getpid()); |
2654 | ATF_REQUIRE((child = fork()) != -1); | | 2721 | ATF_REQUIRE((child = fork()) != -1); |
2655 | if (child == 0) { | | 2722 | if (child == 0) { |
2656 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2723 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2657 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2724 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2658 | | | 2725 | |
2659 | lookup_me1 = magic1; | | 2726 | lookup_me1 = magic1; |
2660 | lookup_me2 = magic2; | | 2727 | lookup_me2 = magic2; |
2661 | lookup_me3 = magic3; | | 2728 | lookup_me3 = magic3; |
2662 | lookup_me4 = magic4; | | 2729 | lookup_me4 = magic4; |
2663 | | | 2730 | |
2664 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2731 | printf("Before raising %s from child\n", strsignal(sigval)); |
2665 | FORKEE_ASSERT(raise(sigval) == 0); | | 2732 | FORKEE_ASSERT(raise(sigval) == 0); |
2666 | | | 2733 | |
2667 | printf("Before exiting of the child process\n"); | | 2734 | printf("Before exiting of the child process\n"); |
2668 | _exit(exitval); | | 2735 | _exit(exitval); |
2669 | } | | 2736 | } |
2670 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2737 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2671 | | | 2738 | |
2672 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2739 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2673 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2740 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2674 | | | 2741 | |
2675 | validate_status_stopped(status, sigval); | | 2742 | validate_status_stopped(status, sigval); |
2676 | | | 2743 | |
2677 | printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", | | 2744 | printf("Read new lookup_me1 from tracee (PID=%d) by tracer (PID=%d)\n", |
2678 | child, getpid()); | | 2745 | child, getpid()); |
2679 | errno = 0; | | 2746 | errno = 0; |
2680 | lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); | | 2747 | lookup_me1 = ptrace(PT_READ_D, child, &lookup_me1, 0); |
2681 | ATF_REQUIRE_EQ(errno, 0); | | 2748 | ATF_REQUIRE_EQ(errno, 0); |
2682 | | | 2749 | |
2683 | ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, | | 2750 | ATF_REQUIRE_EQ_MSG(lookup_me1, magic1, |
2684 | "got value %#x != expected %#x", lookup_me1, magic1); | | 2751 | "got value %#x != expected %#x", lookup_me1, magic1); |
2685 | | | 2752 | |
2686 | printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", | | 2753 | printf("Read new lookup_me2 from tracee (PID=%d) by tracer (PID=%d)\n", |
2687 | child, getpid()); | | 2754 | child, getpid()); |
2688 | errno = 0; | | 2755 | errno = 0; |
2689 | lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); | | 2756 | lookup_me2 = ptrace(PT_READ_D, child, &lookup_me2, 0); |
2690 | ATF_REQUIRE_EQ(errno, 0); | | 2757 | ATF_REQUIRE_EQ(errno, 0); |
2691 | | | 2758 | |
2692 | ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, | | 2759 | ATF_REQUIRE_EQ_MSG(lookup_me2, magic2, |
2693 | "got value %#x != expected %#x", lookup_me2, magic2); | | 2760 | "got value %#x != expected %#x", lookup_me2, magic2); |
2694 | | | 2761 | |
2695 | printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", | | 2762 | printf("Read new lookup_me3 from tracee (PID=%d) by tracer (PID=%d)\n", |
2696 | child, getpid()); | | 2763 | child, getpid()); |
2697 | errno = 0; | | 2764 | errno = 0; |
2698 | lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0); | | 2765 | lookup_me3 = ptrace(PT_READ_D, child, &lookup_me3, 0); |
2699 | ATF_REQUIRE_EQ(errno, 0); | | 2766 | ATF_REQUIRE_EQ(errno, 0); |
2700 | | | 2767 | |
2701 | ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, | | 2768 | ATF_REQUIRE_EQ_MSG(lookup_me3, magic3, |
2702 | "got value %#x != expected %#x", lookup_me3, magic3); | | 2769 | "got value %#x != expected %#x", lookup_me3, magic3); |
2703 | | | 2770 | |
2704 | printf("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n", | | 2771 | printf("Read new lookup_me4 from tracee (PID=%d) by tracer (PID=%d)\n", |
2705 | child, getpid()); | | 2772 | child, getpid()); |
2706 | errno = 0; | | 2773 | errno = 0; |
2707 | lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0); | | 2774 | lookup_me4 = ptrace(PT_READ_D, child, &lookup_me4, 0); |
2708 | ATF_REQUIRE_EQ(errno, 0); | | 2775 | ATF_REQUIRE_EQ(errno, 0); |
2709 | | | 2776 | |
2710 | ATF_REQUIRE_EQ_MSG(lookup_me4, magic4, | | 2777 | ATF_REQUIRE_EQ_MSG(lookup_me4, magic4, |
2711 | "got value %#x != expected %#x", lookup_me4, magic4); | | 2778 | "got value %#x != expected %#x", lookup_me4, magic4); |
2712 | | | 2779 | |
2713 | printf("Before resuming the child process where it left off and " | | 2780 | printf("Before resuming the child process where it left off and " |
2714 | "without signal to be sent\n"); | | 2781 | "without signal to be sent\n"); |
2715 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2782 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2716 | | | 2783 | |
2717 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2784 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2718 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2785 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2719 | | | 2786 | |
2720 | validate_status_exited(status, exitval); | | 2787 | validate_status_exited(status, exitval); |
2721 | | | 2788 | |
2722 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2789 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2723 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2790 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2724 | } | | 2791 | } |
2725 | | | 2792 | |
2726 | ATF_TC(write_d1); | | 2793 | ATF_TC(write_d1); |
2727 | ATF_TC_HEAD(write_d1, tc) | | 2794 | ATF_TC_HEAD(write_d1, tc) |
2728 | { | | 2795 | { |
2729 | atf_tc_set_md_var(tc, "descr", | | 2796 | atf_tc_set_md_var(tc, "descr", |
2730 | "Verify PT_WRITE_D called once"); | | 2797 | "Verify PT_WRITE_D called once"); |
2731 | } | | 2798 | } |
2732 | | | 2799 | |
2733 | ATF_TC_BODY(write_d1, tc) | | 2800 | ATF_TC_BODY(write_d1, tc) |
2734 | { | | 2801 | { |
2735 | const int exitval = 5; | | 2802 | const int exitval = 5; |
2736 | const int sigval = SIGSTOP; | | 2803 | const int sigval = SIGSTOP; |
2737 | pid_t child, wpid; | | 2804 | pid_t child, wpid; |
2738 | int lookup_me = 0; | | 2805 | int lookup_me = 0; |
2739 | const int magic = (int)random(); | | 2806 | const int magic = (int)random(); |
2740 | #if defined(TWAIT_HAVE_STATUS) | | 2807 | #if defined(TWAIT_HAVE_STATUS) |
2741 | int status; | | 2808 | int status; |
2742 | #endif | | 2809 | #endif |
2743 | | | 2810 | |
2744 | printf("Before forking process PID=%d\n", getpid()); | | 2811 | printf("Before forking process PID=%d\n", getpid()); |
2745 | ATF_REQUIRE((child = fork()) != -1); | | 2812 | ATF_REQUIRE((child = fork()) != -1); |
2746 | if (child == 0) { | | 2813 | if (child == 0) { |
2747 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2814 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2748 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2815 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2749 | | | 2816 | |
2750 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2817 | printf("Before raising %s from child\n", strsignal(sigval)); |
2751 | FORKEE_ASSERT(raise(sigval) == 0); | | 2818 | FORKEE_ASSERT(raise(sigval) == 0); |
2752 | | | 2819 | |
2753 | FORKEE_ASSERT_EQ(lookup_me, magic); | | 2820 | FORKEE_ASSERT_EQ(lookup_me, magic); |
2754 | | | 2821 | |
2755 | printf("Before exiting of the child process\n"); | | 2822 | printf("Before exiting of the child process\n"); |
2756 | _exit(exitval); | | 2823 | _exit(exitval); |
2757 | } | | 2824 | } |
2758 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2825 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2759 | | | 2826 | |
2760 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2827 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2761 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2828 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2762 | | | 2829 | |
2763 | validate_status_stopped(status, sigval); | | 2830 | validate_status_stopped(status, sigval); |
2764 | | | 2831 | |
2765 | printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", | | 2832 | printf("Write new lookup_me to tracee (PID=%d) from tracer (PID=%d)\n", |
2766 | child, getpid()); | | 2833 | child, getpid()); |
2767 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1); | | 2834 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me, magic) != -1); |
2768 | | | 2835 | |
2769 | printf("Before resuming the child process where it left off and " | | 2836 | printf("Before resuming the child process where it left off and " |
2770 | "without signal to be sent\n"); | | 2837 | "without signal to be sent\n"); |
2771 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2838 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2772 | | | 2839 | |
2773 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2840 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2774 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2841 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2775 | | | 2842 | |
2776 | validate_status_exited(status, exitval); | | 2843 | validate_status_exited(status, exitval); |
2777 | | | 2844 | |
2778 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2845 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2779 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2846 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2780 | } | | 2847 | } |
2781 | | | 2848 | |
2782 | ATF_TC(write_d2); | | 2849 | ATF_TC(write_d2); |
2783 | ATF_TC_HEAD(write_d2, tc) | | 2850 | ATF_TC_HEAD(write_d2, tc) |
2784 | { | | 2851 | { |
2785 | atf_tc_set_md_var(tc, "descr", | | 2852 | atf_tc_set_md_var(tc, "descr", |
2786 | "Verify PT_WRITE_D called twice"); | | 2853 | "Verify PT_WRITE_D called twice"); |
2787 | } | | 2854 | } |
2788 | | | 2855 | |
2789 | ATF_TC_BODY(write_d2, tc) | | 2856 | ATF_TC_BODY(write_d2, tc) |
2790 | { | | 2857 | { |
2791 | const int exitval = 5; | | 2858 | const int exitval = 5; |
2792 | const int sigval = SIGSTOP; | | 2859 | const int sigval = SIGSTOP; |
2793 | pid_t child, wpid; | | 2860 | pid_t child, wpid; |
2794 | int lookup_me1 = 0; | | 2861 | int lookup_me1 = 0; |
2795 | int lookup_me2 = 0; | | 2862 | int lookup_me2 = 0; |
2796 | const int magic1 = (int)random(); | | 2863 | const int magic1 = (int)random(); |
2797 | const int magic2 = (int)random(); | | 2864 | const int magic2 = (int)random(); |
2798 | #if defined(TWAIT_HAVE_STATUS) | | 2865 | #if defined(TWAIT_HAVE_STATUS) |
2799 | int status; | | 2866 | int status; |
2800 | #endif | | 2867 | #endif |
2801 | | | 2868 | |
2802 | printf("Before forking process PID=%d\n", getpid()); | | 2869 | printf("Before forking process PID=%d\n", getpid()); |
2803 | ATF_REQUIRE((child = fork()) != -1); | | 2870 | ATF_REQUIRE((child = fork()) != -1); |
2804 | if (child == 0) { | | 2871 | if (child == 0) { |
2805 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2872 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2806 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2873 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2807 | | | 2874 | |
2808 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2875 | printf("Before raising %s from child\n", strsignal(sigval)); |
2809 | FORKEE_ASSERT(raise(sigval) == 0); | | 2876 | FORKEE_ASSERT(raise(sigval) == 0); |
2810 | | | 2877 | |
2811 | FORKEE_ASSERT_EQ(lookup_me1, magic1); | | 2878 | FORKEE_ASSERT_EQ(lookup_me1, magic1); |
2812 | FORKEE_ASSERT_EQ(lookup_me2, magic2); | | 2879 | FORKEE_ASSERT_EQ(lookup_me2, magic2); |
2813 | | | 2880 | |
2814 | printf("Before exiting of the child process\n"); | | 2881 | printf("Before exiting of the child process\n"); |
2815 | _exit(exitval); | | 2882 | _exit(exitval); |
2816 | } | | 2883 | } |
2817 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2884 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2818 | | | 2885 | |
2819 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2886 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2820 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2887 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2821 | | | 2888 | |
2822 | validate_status_stopped(status, sigval); | | 2889 | validate_status_stopped(status, sigval); |
2823 | | | 2890 | |
2824 | printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", | | 2891 | printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", |
2825 | child, getpid()); | | 2892 | child, getpid()); |
2826 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); | | 2893 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); |
2827 | | | 2894 | |
2828 | printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", | | 2895 | printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", |
2829 | child, getpid()); | | 2896 | child, getpid()); |
2830 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); | | 2897 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); |
2831 | | | 2898 | |
2832 | printf("Before resuming the child process where it left off and " | | 2899 | printf("Before resuming the child process where it left off and " |
2833 | "without signal to be sent\n"); | | 2900 | "without signal to be sent\n"); |
2834 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2901 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2835 | | | 2902 | |
2836 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2903 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2837 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2904 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2838 | | | 2905 | |
2839 | validate_status_exited(status, exitval); | | 2906 | validate_status_exited(status, exitval); |
2840 | | | 2907 | |
2841 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2908 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2842 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2909 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2843 | } | | 2910 | } |
2844 | | | 2911 | |
2845 | ATF_TC(write_d3); | | 2912 | ATF_TC(write_d3); |
2846 | ATF_TC_HEAD(write_d3, tc) | | 2913 | ATF_TC_HEAD(write_d3, tc) |
2847 | { | | 2914 | { |
2848 | atf_tc_set_md_var(tc, "descr", | | 2915 | atf_tc_set_md_var(tc, "descr", |
2849 | "Verify PT_WRITE_D called three times"); | | 2916 | "Verify PT_WRITE_D called three times"); |
2850 | } | | 2917 | } |
2851 | | | 2918 | |
2852 | ATF_TC_BODY(write_d3, tc) | | 2919 | ATF_TC_BODY(write_d3, tc) |
2853 | { | | 2920 | { |
2854 | const int exitval = 5; | | 2921 | const int exitval = 5; |
2855 | const int sigval = SIGSTOP; | | 2922 | const int sigval = SIGSTOP; |
2856 | pid_t child, wpid; | | 2923 | pid_t child, wpid; |
2857 | int lookup_me1 = 0; | | 2924 | int lookup_me1 = 0; |
2858 | int lookup_me2 = 0; | | 2925 | int lookup_me2 = 0; |
2859 | int lookup_me3 = 0; | | 2926 | int lookup_me3 = 0; |
2860 | const int magic1 = (int)random(); | | 2927 | const int magic1 = (int)random(); |
2861 | const int magic2 = (int)random(); | | 2928 | const int magic2 = (int)random(); |
2862 | const int magic3 = (int)random(); | | 2929 | const int magic3 = (int)random(); |
2863 | #if defined(TWAIT_HAVE_STATUS) | | 2930 | #if defined(TWAIT_HAVE_STATUS) |
2864 | int status; | | 2931 | int status; |
2865 | #endif | | 2932 | #endif |
2866 | | | 2933 | |
2867 | printf("Before forking process PID=%d\n", getpid()); | | 2934 | printf("Before forking process PID=%d\n", getpid()); |
2868 | ATF_REQUIRE((child = fork()) != -1); | | 2935 | ATF_REQUIRE((child = fork()) != -1); |
2869 | if (child == 0) { | | 2936 | if (child == 0) { |
2870 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 2937 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2871 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 2938 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2872 | | | 2939 | |
2873 | printf("Before raising %s from child\n", strsignal(sigval)); | | 2940 | printf("Before raising %s from child\n", strsignal(sigval)); |
2874 | FORKEE_ASSERT(raise(sigval) == 0); | | 2941 | FORKEE_ASSERT(raise(sigval) == 0); |
2875 | | | 2942 | |
2876 | FORKEE_ASSERT_EQ(lookup_me1, magic1); | | 2943 | FORKEE_ASSERT_EQ(lookup_me1, magic1); |
2877 | FORKEE_ASSERT_EQ(lookup_me2, magic2); | | 2944 | FORKEE_ASSERT_EQ(lookup_me2, magic2); |
2878 | FORKEE_ASSERT_EQ(lookup_me3, magic3); | | 2945 | FORKEE_ASSERT_EQ(lookup_me3, magic3); |
2879 | | | 2946 | |
2880 | printf("Before exiting of the child process\n"); | | 2947 | printf("Before exiting of the child process\n"); |
2881 | _exit(exitval); | | 2948 | _exit(exitval); |
2882 | } | | 2949 | } |
2883 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 2950 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2884 | | | 2951 | |
2885 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2952 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2886 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2953 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2887 | | | 2954 | |
2888 | validate_status_stopped(status, sigval); | | 2955 | validate_status_stopped(status, sigval); |
2889 | | | 2956 | |
2890 | printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", | | 2957 | printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", |
2891 | child, getpid()); | | 2958 | child, getpid()); |
2892 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); | | 2959 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); |
2893 | | | 2960 | |
2894 | printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", | | 2961 | printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", |
2895 | child, getpid()); | | 2962 | child, getpid()); |
2896 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); | | 2963 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); |
2897 | | | 2964 | |
2898 | printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n", | | 2965 | printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n", |
2899 | child, getpid()); | | 2966 | child, getpid()); |
2900 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1); | | 2967 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1); |
2901 | | | 2968 | |
2902 | printf("Before resuming the child process where it left off and " | | 2969 | printf("Before resuming the child process where it left off and " |
2903 | "without signal to be sent\n"); | | 2970 | "without signal to be sent\n"); |
2904 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 2971 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2905 | | | 2972 | |
2906 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2973 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2907 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 2974 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2908 | | | 2975 | |
2909 | validate_status_exited(status, exitval); | | 2976 | validate_status_exited(status, exitval); |
2910 | | | 2977 | |
2911 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 2978 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2912 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 2979 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2913 | } | | 2980 | } |
2914 | | | 2981 | |
2915 | ATF_TC(write_d4); | | 2982 | ATF_TC(write_d4); |
2916 | ATF_TC_HEAD(write_d4, tc) | | 2983 | ATF_TC_HEAD(write_d4, tc) |
2917 | { | | 2984 | { |
2918 | atf_tc_set_md_var(tc, "descr", | | 2985 | atf_tc_set_md_var(tc, "descr", |
2919 | "Verify PT_WRITE_D called four times"); | | 2986 | "Verify PT_WRITE_D called four times"); |
2920 | } | | 2987 | } |
2921 | | | 2988 | |
2922 | ATF_TC_BODY(write_d4, tc) | | 2989 | ATF_TC_BODY(write_d4, tc) |
2923 | { | | 2990 | { |
2924 | const int exitval = 5; | | 2991 | const int exitval = 5; |
2925 | const int sigval = SIGSTOP; | | 2992 | const int sigval = SIGSTOP; |
2926 | pid_t child, wpid; | | 2993 | pid_t child, wpid; |
2927 | int lookup_me1 = 0; | | 2994 | int lookup_me1 = 0; |
2928 | int lookup_me2 = 0; | | 2995 | int lookup_me2 = 0; |
2929 | int lookup_me3 = 0; | | 2996 | int lookup_me3 = 0; |
2930 | int lookup_me4 = 0; | | 2997 | int lookup_me4 = 0; |
2931 | const int magic1 = (int)random(); | | 2998 | const int magic1 = (int)random(); |
2932 | const int magic2 = (int)random(); | | 2999 | const int magic2 = (int)random(); |
2933 | const int magic3 = (int)random(); | | 3000 | const int magic3 = (int)random(); |
2934 | const int magic4 = (int)random(); | | 3001 | const int magic4 = (int)random(); |
2935 | #if defined(TWAIT_HAVE_STATUS) | | 3002 | #if defined(TWAIT_HAVE_STATUS) |
2936 | int status; | | 3003 | int status; |
2937 | #endif | | 3004 | #endif |
2938 | | | 3005 | |
2939 | printf("Before forking process PID=%d\n", getpid()); | | 3006 | printf("Before forking process PID=%d\n", getpid()); |
2940 | ATF_REQUIRE((child = fork()) != -1); | | 3007 | ATF_REQUIRE((child = fork()) != -1); |
2941 | if (child == 0) { | | 3008 | if (child == 0) { |
2942 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 3009 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
2943 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 3010 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
2944 | | | 3011 | |
2945 | printf("Before raising %s from child\n", strsignal(sigval)); | | 3012 | printf("Before raising %s from child\n", strsignal(sigval)); |
2946 | FORKEE_ASSERT(raise(sigval) == 0); | | 3013 | FORKEE_ASSERT(raise(sigval) == 0); |
2947 | | | 3014 | |
2948 | FORKEE_ASSERT_EQ(lookup_me1, magic1); | | 3015 | FORKEE_ASSERT_EQ(lookup_me1, magic1); |
2949 | FORKEE_ASSERT_EQ(lookup_me2, magic2); | | 3016 | FORKEE_ASSERT_EQ(lookup_me2, magic2); |
2950 | FORKEE_ASSERT_EQ(lookup_me3, magic3); | | 3017 | FORKEE_ASSERT_EQ(lookup_me3, magic3); |
2951 | FORKEE_ASSERT_EQ(lookup_me4, magic4); | | 3018 | FORKEE_ASSERT_EQ(lookup_me4, magic4); |
2952 | | | 3019 | |
2953 | printf("Before exiting of the child process\n"); | | 3020 | printf("Before exiting of the child process\n"); |
2954 | _exit(exitval); | | 3021 | _exit(exitval); |
2955 | } | | 3022 | } |
2956 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 3023 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
2957 | | | 3024 | |
2958 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3025 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2959 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3026 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2960 | | | 3027 | |
2961 | validate_status_stopped(status, sigval); | | 3028 | validate_status_stopped(status, sigval); |
2962 | | | 3029 | |
2963 | printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", | | 3030 | printf("Write new lookup_me1 to tracee (PID=%d) from tracer (PID=%d)\n", |
2964 | child, getpid()); | | 3031 | child, getpid()); |
2965 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); | | 3032 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me1, magic1) != -1); |
2966 | | | 3033 | |
2967 | printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", | | 3034 | printf("Write new lookup_me2 to tracee (PID=%d) from tracer (PID=%d)\n", |
2968 | child, getpid()); | | 3035 | child, getpid()); |
2969 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); | | 3036 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me2, magic2) != -1); |
2970 | | | 3037 | |
2971 | printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n", | | 3038 | printf("Write new lookup_me3 to tracee (PID=%d) from tracer (PID=%d)\n", |
2972 | child, getpid()); | | 3039 | child, getpid()); |
2973 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1); | | 3040 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me3, magic3) != -1); |
2974 | | | 3041 | |
2975 | printf("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n", | | 3042 | printf("Write new lookup_me4 to tracee (PID=%d) from tracer (PID=%d)\n", |
2976 | child, getpid()); | | 3043 | child, getpid()); |
2977 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1); | | 3044 | ATF_REQUIRE(ptrace(PT_WRITE_D, child, &lookup_me4, magic4) != -1); |
2978 | | | 3045 | |
2979 | printf("Before resuming the child process where it left off and " | | 3046 | printf("Before resuming the child process where it left off and " |
2980 | "without signal to be sent\n"); | | 3047 | "without signal to be sent\n"); |
2981 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 3048 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
2982 | | | 3049 | |
2983 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3050 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2984 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3051 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
2985 | | | 3052 | |
2986 | validate_status_exited(status, exitval); | | 3053 | validate_status_exited(status, exitval); |
2987 | | | 3054 | |
2988 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3055 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
2989 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 3056 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
2990 | } | | 3057 | } |
2991 | | | 3058 | |
2992 | ATF_TC(io_read_d_write_d_handshake1); | | 3059 | ATF_TC(io_read_d_write_d_handshake1); |
2993 | ATF_TC_HEAD(io_read_d_write_d_handshake1, tc) | | 3060 | ATF_TC_HEAD(io_read_d_write_d_handshake1, tc) |
2994 | { | | 3061 | { |
2995 | atf_tc_set_md_var(tc, "descr", | | 3062 | atf_tc_set_md_var(tc, "descr", |
2996 | "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake"); | | 3063 | "Verify PT_IO with PIOD_READ_D and PIOD_WRITE_D handshake"); |
2997 | } | | 3064 | } |
2998 | | | 3065 | |
2999 | ATF_TC_BODY(io_read_d_write_d_handshake1, tc) | | 3066 | ATF_TC_BODY(io_read_d_write_d_handshake1, tc) |
3000 | { | | 3067 | { |
3001 | const int exitval = 5; | | 3068 | const int exitval = 5; |
3002 | const int sigval = SIGSTOP; | | 3069 | const int sigval = SIGSTOP; |
3003 | pid_t child, wpid; | | 3070 | pid_t child, wpid; |
3004 | uint8_t lookup_me_fromtracee = 0; | | 3071 | uint8_t lookup_me_fromtracee = 0; |
3005 | const uint8_t magic_fromtracee = (uint8_t)random(); | | 3072 | const uint8_t magic_fromtracee = (uint8_t)random(); |
3006 | uint8_t lookup_me_totracee = 0; | | 3073 | uint8_t lookup_me_totracee = 0; |
3007 | const uint8_t magic_totracee = (uint8_t)random(); | | 3074 | const uint8_t magic_totracee = (uint8_t)random(); |
3008 | struct ptrace_io_desc io_fromtracee = { | | 3075 | struct ptrace_io_desc io_fromtracee = { |
3009 | .piod_op = PIOD_READ_D, | | 3076 | .piod_op = PIOD_READ_D, |
3010 | .piod_offs = &lookup_me_fromtracee, | | 3077 | .piod_offs = &lookup_me_fromtracee, |
3011 | .piod_addr = &lookup_me_fromtracee, | | 3078 | .piod_addr = &lookup_me_fromtracee, |
3012 | .piod_len = sizeof(lookup_me_fromtracee) | | 3079 | .piod_len = sizeof(lookup_me_fromtracee) |
3013 | }; | | 3080 | }; |
3014 | struct ptrace_io_desc io_totracee = { | | 3081 | struct ptrace_io_desc io_totracee = { |
3015 | .piod_op = PIOD_WRITE_D, | | 3082 | .piod_op = PIOD_WRITE_D, |
3016 | .piod_offs = &lookup_me_totracee, | | 3083 | .piod_offs = &lookup_me_totracee, |
3017 | .piod_addr = &lookup_me_totracee, | | 3084 | .piod_addr = &lookup_me_totracee, |
3018 | .piod_len = sizeof(lookup_me_totracee) | | 3085 | .piod_len = sizeof(lookup_me_totracee) |
3019 | }; | | 3086 | }; |
3020 | #if defined(TWAIT_HAVE_STATUS) | | 3087 | #if defined(TWAIT_HAVE_STATUS) |
3021 | int status; | | 3088 | int status; |
3022 | #endif | | 3089 | #endif |
3023 | | | 3090 | |
3024 | printf("Before forking process PID=%d\n", getpid()); | | 3091 | printf("Before forking process PID=%d\n", getpid()); |
3025 | ATF_REQUIRE((child = fork()) != -1); | | 3092 | ATF_REQUIRE((child = fork()) != -1); |
3026 | if (child == 0) { | | 3093 | if (child == 0) { |
3027 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 3094 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
3028 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 3095 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
3029 | | | 3096 | |
3030 | lookup_me_fromtracee = magic_fromtracee; | | 3097 | lookup_me_fromtracee = magic_fromtracee; |
3031 | | | 3098 | |
3032 | printf("Before raising %s from child\n", strsignal(sigval)); | | 3099 | printf("Before raising %s from child\n", strsignal(sigval)); |
3033 | FORKEE_ASSERT(raise(sigval) == 0); | | 3100 | FORKEE_ASSERT(raise(sigval) == 0); |
3034 | | | 3101 | |
3035 | FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); | | 3102 | FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); |
3036 | | | 3103 | |
3037 | printf("Before exiting of the child process\n"); | | 3104 | printf("Before exiting of the child process\n"); |
3038 | _exit(exitval); | | 3105 | _exit(exitval); |
3039 | } | | 3106 | } |
3040 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 3107 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
3041 | | | 3108 | |
3042 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3109 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3043 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3110 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
3044 | | | 3111 | |
3045 | validate_status_stopped(status, sigval); | | 3112 | validate_status_stopped(status, sigval); |
3046 | | | 3113 | |
3047 | printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", | | 3114 | printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", |
3048 | child, getpid()); | | 3115 | child, getpid()); |
3049 | ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1); | | 3116 | ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1); |
3050 | | | 3117 | |
3051 | ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, | | 3118 | ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, |
3052 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee, | | 3119 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee, |
3053 | magic_fromtracee); | | 3120 | magic_fromtracee); |
3054 | | | 3121 | |
3055 | lookup_me_totracee = magic_totracee; | | 3122 | lookup_me_totracee = magic_totracee; |
3056 | | | 3123 | |
3057 | printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n", | | 3124 | printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n", |
3058 | child, getpid()); | | 3125 | child, getpid()); |
3059 | ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1); | | 3126 | ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1); |
3060 | | | 3127 | |
3061 | ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee, | | 3128 | ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee, |
3062 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee, | | 3129 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee, |
3063 | magic_totracee); | | 3130 | magic_totracee); |
3064 | | | 3131 | |
3065 | printf("Before resuming the child process where it left off and " | | 3132 | printf("Before resuming the child process where it left off and " |
3066 | "without signal to be sent\n"); | | 3133 | "without signal to be sent\n"); |
3067 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 3134 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
3068 | | | 3135 | |
3069 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3136 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3070 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3137 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
3071 | | | 3138 | |
3072 | validate_status_exited(status, exitval); | | 3139 | validate_status_exited(status, exitval); |
3073 | | | 3140 | |
3074 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3141 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3075 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 3142 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
3076 | } | | 3143 | } |
3077 | | | 3144 | |
3078 | ATF_TC(io_read_d_write_d_handshake2); | | 3145 | ATF_TC(io_read_d_write_d_handshake2); |
3079 | ATF_TC_HEAD(io_read_d_write_d_handshake2, tc) | | 3146 | ATF_TC_HEAD(io_read_d_write_d_handshake2, tc) |
3080 | { | | 3147 | { |
3081 | atf_tc_set_md_var(tc, "descr", | | 3148 | atf_tc_set_md_var(tc, "descr", |
3082 | "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake"); | | 3149 | "Verify PT_IO with PIOD_WRITE_D and PIOD_READ_D handshake"); |
3083 | } | | 3150 | } |
3084 | | | 3151 | |
3085 | ATF_TC_BODY(io_read_d_write_d_handshake2, tc) | | 3152 | ATF_TC_BODY(io_read_d_write_d_handshake2, tc) |
3086 | { | | 3153 | { |
3087 | const int exitval = 5; | | 3154 | const int exitval = 5; |
3088 | const int sigval = SIGSTOP; | | 3155 | const int sigval = SIGSTOP; |
3089 | pid_t child, wpid; | | 3156 | pid_t child, wpid; |
3090 | uint8_t lookup_me_fromtracee = 0; | | 3157 | uint8_t lookup_me_fromtracee = 0; |
3091 | const uint8_t magic_fromtracee = (uint8_t)random(); | | 3158 | const uint8_t magic_fromtracee = (uint8_t)random(); |
3092 | uint8_t lookup_me_totracee = 0; | | 3159 | uint8_t lookup_me_totracee = 0; |
3093 | const uint8_t magic_totracee = (uint8_t)random(); | | 3160 | const uint8_t magic_totracee = (uint8_t)random(); |
3094 | struct ptrace_io_desc io_fromtracee = { | | 3161 | struct ptrace_io_desc io_fromtracee = { |
3095 | .piod_op = PIOD_READ_D, | | 3162 | .piod_op = PIOD_READ_D, |
3096 | .piod_offs = &lookup_me_fromtracee, | | 3163 | .piod_offs = &lookup_me_fromtracee, |
3097 | .piod_addr = &lookup_me_fromtracee, | | 3164 | .piod_addr = &lookup_me_fromtracee, |
3098 | .piod_len = sizeof(lookup_me_fromtracee) | | 3165 | .piod_len = sizeof(lookup_me_fromtracee) |
3099 | }; | | 3166 | }; |
3100 | struct ptrace_io_desc io_totracee = { | | 3167 | struct ptrace_io_desc io_totracee = { |
3101 | .piod_op = PIOD_WRITE_D, | | 3168 | .piod_op = PIOD_WRITE_D, |
3102 | .piod_offs = &lookup_me_totracee, | | 3169 | .piod_offs = &lookup_me_totracee, |
3103 | .piod_addr = &lookup_me_totracee, | | 3170 | .piod_addr = &lookup_me_totracee, |
3104 | .piod_len = sizeof(lookup_me_totracee) | | 3171 | .piod_len = sizeof(lookup_me_totracee) |
3105 | }; | | 3172 | }; |
3106 | #if defined(TWAIT_HAVE_STATUS) | | 3173 | #if defined(TWAIT_HAVE_STATUS) |
3107 | int status; | | 3174 | int status; |
3108 | #endif | | 3175 | #endif |
3109 | | | 3176 | |
3110 | printf("Before forking process PID=%d\n", getpid()); | | 3177 | printf("Before forking process PID=%d\n", getpid()); |
3111 | ATF_REQUIRE((child = fork()) != -1); | | 3178 | ATF_REQUIRE((child = fork()) != -1); |
3112 | if (child == 0) { | | 3179 | if (child == 0) { |
3113 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 3180 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
3114 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 3181 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
3115 | | | 3182 | |
3116 | lookup_me_fromtracee = magic_fromtracee; | | 3183 | lookup_me_fromtracee = magic_fromtracee; |
3117 | | | 3184 | |
3118 | printf("Before raising %s from child\n", strsignal(sigval)); | | 3185 | printf("Before raising %s from child\n", strsignal(sigval)); |
3119 | FORKEE_ASSERT(raise(sigval) == 0); | | 3186 | FORKEE_ASSERT(raise(sigval) == 0); |
3120 | | | 3187 | |
3121 | FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); | | 3188 | FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); |
3122 | | | 3189 | |
3123 | printf("Before exiting of the child process\n"); | | 3190 | printf("Before exiting of the child process\n"); |
3124 | _exit(exitval); | | 3191 | _exit(exitval); |
3125 | } | | 3192 | } |
3126 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 3193 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
3127 | | | 3194 | |
3128 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3195 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3129 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3196 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
3130 | | | 3197 | |
3131 | validate_status_stopped(status, sigval); | | 3198 | validate_status_stopped(status, sigval); |
3132 | | | 3199 | |
3133 | lookup_me_totracee = magic_totracee; | | 3200 | lookup_me_totracee = magic_totracee; |
3134 | | | 3201 | |
3135 | printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n", | | 3202 | printf("Write lookup_me_totracee to PID=%d by tracer (PID=%d)\n", |
3136 | child, getpid()); | | 3203 | child, getpid()); |
3137 | ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1); | | 3204 | ATF_REQUIRE(ptrace(PT_IO, child, &io_totracee, 0) != -1); |
3138 | | | 3205 | |
3139 | ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee, | | 3206 | ATF_REQUIRE_EQ_MSG(lookup_me_totracee, magic_totracee, |
3140 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee, | | 3207 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me_totracee, |
3141 | magic_totracee); | | 3208 | magic_totracee); |
3142 | | | 3209 | |
3143 | printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", | | 3210 | printf("Read lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", |
3144 | child, getpid()); | | 3211 | child, getpid()); |
3145 | ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1); | | 3212 | ATF_REQUIRE(ptrace(PT_IO, child, &io_fromtracee, 0) != -1); |
3146 | | | 3213 | |
3147 | ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, | | 3214 | ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, |
3148 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee, | | 3215 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me_fromtracee, |
3149 | magic_fromtracee); | | 3216 | magic_fromtracee); |
3150 | | | 3217 | |
3151 | printf("Before resuming the child process where it left off and " | | 3218 | printf("Before resuming the child process where it left off and " |
3152 | "without signal to be sent\n"); | | 3219 | "without signal to be sent\n"); |
3153 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 3220 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
3154 | | | 3221 | |
3155 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3222 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3156 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3223 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
3157 | | | 3224 | |
3158 | validate_status_exited(status, exitval); | | 3225 | validate_status_exited(status, exitval); |
3159 | | | 3226 | |
3160 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3227 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3161 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 3228 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
3162 | } | | 3229 | } |
3163 | | | 3230 | |
3164 | ATF_TC(read_d_write_d_handshake1); | | 3231 | ATF_TC(read_d_write_d_handshake1); |
3165 | ATF_TC_HEAD(read_d_write_d_handshake1, tc) | | 3232 | ATF_TC_HEAD(read_d_write_d_handshake1, tc) |
3166 | { | | 3233 | { |
3167 | atf_tc_set_md_var(tc, "descr", | | 3234 | atf_tc_set_md_var(tc, "descr", |
3168 | "Verify PT_READ_D with PT_WRITE_D handshake"); | | 3235 | "Verify PT_READ_D with PT_WRITE_D handshake"); |
3169 | } | | 3236 | } |
3170 | | | 3237 | |
3171 | ATF_TC_BODY(read_d_write_d_handshake1, tc) | | 3238 | ATF_TC_BODY(read_d_write_d_handshake1, tc) |
3172 | { | | 3239 | { |
3173 | const int exitval = 5; | | 3240 | const int exitval = 5; |
3174 | const int sigval = SIGSTOP; | | 3241 | const int sigval = SIGSTOP; |
3175 | pid_t child, wpid; | | 3242 | pid_t child, wpid; |
3176 | int lookup_me_fromtracee = 0; | | 3243 | int lookup_me_fromtracee = 0; |
3177 | const int magic_fromtracee = (int)random(); | | 3244 | const int magic_fromtracee = (int)random(); |
3178 | int lookup_me_totracee = 0; | | 3245 | int lookup_me_totracee = 0; |
3179 | const int magic_totracee = (int)random(); | | 3246 | const int magic_totracee = (int)random(); |
3180 | #if defined(TWAIT_HAVE_STATUS) | | 3247 | #if defined(TWAIT_HAVE_STATUS) |
3181 | int status; | | 3248 | int status; |
3182 | #endif | | 3249 | #endif |
3183 | | | 3250 | |
3184 | printf("Before forking process PID=%d\n", getpid()); | | 3251 | printf("Before forking process PID=%d\n", getpid()); |
3185 | ATF_REQUIRE((child = fork()) != -1); | | 3252 | ATF_REQUIRE((child = fork()) != -1); |
3186 | if (child == 0) { | | 3253 | if (child == 0) { |
3187 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 3254 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
3188 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 3255 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
3189 | | | 3256 | |
3190 | lookup_me_fromtracee = magic_fromtracee; | | 3257 | lookup_me_fromtracee = magic_fromtracee; |
3191 | | | 3258 | |
3192 | printf("Before raising %s from child\n", strsignal(sigval)); | | 3259 | printf("Before raising %s from child\n", strsignal(sigval)); |
3193 | FORKEE_ASSERT(raise(sigval) == 0); | | 3260 | FORKEE_ASSERT(raise(sigval) == 0); |
3194 | | | 3261 | |
3195 | FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); | | 3262 | FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); |
3196 | | | 3263 | |
3197 | printf("Before exiting of the child process\n"); | | 3264 | printf("Before exiting of the child process\n"); |
3198 | _exit(exitval); | | 3265 | _exit(exitval); |
3199 | } | | 3266 | } |
3200 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 3267 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
3201 | | | 3268 | |
3202 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3269 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3203 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3270 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
3204 | | | 3271 | |
3205 | validate_status_stopped(status, sigval); | | 3272 | validate_status_stopped(status, sigval); |
3206 | | | 3273 | |
3207 | printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", | | 3274 | printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", |
3208 | child, getpid()); | | 3275 | child, getpid()); |
3209 | errno = 0; | | 3276 | errno = 0; |
3210 | lookup_me_fromtracee = | | 3277 | lookup_me_fromtracee = |
3211 | ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0); | | 3278 | ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0); |
3212 | ATF_REQUIRE_EQ(errno, 0); | | 3279 | ATF_REQUIRE_EQ(errno, 0); |
3213 | | | 3280 | |
3214 | ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, | | 3281 | ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, |
3215 | "got value %#x != expected %#x", lookup_me_fromtracee, | | 3282 | "got value %#x != expected %#x", lookup_me_fromtracee, |
3216 | magic_fromtracee); | | 3283 | magic_fromtracee); |
3217 | | | 3284 | |
3218 | printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n", | | 3285 | printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n", |
3219 | child, getpid()); | | 3286 | child, getpid()); |
3220 | ATF_REQUIRE | | 3287 | ATF_REQUIRE |
3221 | (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee) | | 3288 | (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee) |
3222 | != -1); | | 3289 | != -1); |
3223 | | | 3290 | |
3224 | printf("Before resuming the child process where it left off and " | | 3291 | printf("Before resuming the child process where it left off and " |
3225 | "without signal to be sent\n"); | | 3292 | "without signal to be sent\n"); |
3226 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 3293 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
3227 | | | 3294 | |
3228 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3295 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3229 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3296 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
3230 | | | 3297 | |
3231 | validate_status_exited(status, exitval); | | 3298 | validate_status_exited(status, exitval); |
3232 | | | 3299 | |
3233 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3300 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3234 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 3301 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
3235 | } | | 3302 | } |
3236 | | | 3303 | |
3237 | ATF_TC(read_d_write_d_handshake2); | | 3304 | ATF_TC(read_d_write_d_handshake2); |
3238 | ATF_TC_HEAD(read_d_write_d_handshake2, tc) | | 3305 | ATF_TC_HEAD(read_d_write_d_handshake2, tc) |
3239 | { | | 3306 | { |
3240 | atf_tc_set_md_var(tc, "descr", | | 3307 | atf_tc_set_md_var(tc, "descr", |
3241 | "Verify PT_WRITE_D with PT_READ_D handshake"); | | 3308 | "Verify PT_WRITE_D with PT_READ_D handshake"); |
3242 | } | | 3309 | } |
3243 | | | 3310 | |
3244 | ATF_TC_BODY(read_d_write_d_handshake2, tc) | | 3311 | ATF_TC_BODY(read_d_write_d_handshake2, tc) |
3245 | { | | 3312 | { |
3246 | const int exitval = 5; | | 3313 | const int exitval = 5; |
3247 | const int sigval = SIGSTOP; | | 3314 | const int sigval = SIGSTOP; |
3248 | pid_t child, wpid; | | 3315 | pid_t child, wpid; |
3249 | int lookup_me_fromtracee = 0; | | 3316 | int lookup_me_fromtracee = 0; |
3250 | const int magic_fromtracee = (int)random(); | | 3317 | const int magic_fromtracee = (int)random(); |
3251 | int lookup_me_totracee = 0; | | 3318 | int lookup_me_totracee = 0; |
3252 | const int magic_totracee = (int)random(); | | 3319 | const int magic_totracee = (int)random(); |
3253 | #if defined(TWAIT_HAVE_STATUS) | | 3320 | #if defined(TWAIT_HAVE_STATUS) |
3254 | int status; | | 3321 | int status; |
3255 | #endif | | 3322 | #endif |
3256 | | | 3323 | |
3257 | printf("Before forking process PID=%d\n", getpid()); | | 3324 | printf("Before forking process PID=%d\n", getpid()); |
3258 | ATF_REQUIRE((child = fork()) != -1); | | 3325 | ATF_REQUIRE((child = fork()) != -1); |
3259 | if (child == 0) { | | 3326 | if (child == 0) { |
3260 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 3327 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
3261 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 3328 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
3262 | | | 3329 | |
3263 | lookup_me_fromtracee = magic_fromtracee; | | 3330 | lookup_me_fromtracee = magic_fromtracee; |
3264 | | | 3331 | |
3265 | printf("Before raising %s from child\n", strsignal(sigval)); | | 3332 | printf("Before raising %s from child\n", strsignal(sigval)); |
3266 | FORKEE_ASSERT(raise(sigval) == 0); | | 3333 | FORKEE_ASSERT(raise(sigval) == 0); |
3267 | | | 3334 | |
3268 | FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); | | 3335 | FORKEE_ASSERT_EQ(lookup_me_totracee, magic_totracee); |
3269 | | | 3336 | |
3270 | printf("Before exiting of the child process\n"); | | 3337 | printf("Before exiting of the child process\n"); |
3271 | _exit(exitval); | | 3338 | _exit(exitval); |
3272 | } | | 3339 | } |
3273 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 3340 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
3274 | | | 3341 | |
3275 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3342 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3276 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3343 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
3277 | | | 3344 | |
3278 | validate_status_stopped(status, sigval); | | 3345 | validate_status_stopped(status, sigval); |
3279 | | | 3346 | |
3280 | printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n", | | 3347 | printf("Write new lookup_me_totracee to PID=%d from tracer (PID=%d)\n", |
3281 | child, getpid()); | | 3348 | child, getpid()); |
3282 | ATF_REQUIRE | | 3349 | ATF_REQUIRE |
3283 | (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee) | | 3350 | (ptrace(PT_WRITE_D, child, &lookup_me_totracee, magic_totracee) |
3284 | != -1); | | 3351 | != -1); |
3285 | | | 3352 | |
3286 | printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", | | 3353 | printf("Read new lookup_me_fromtracee PID=%d by tracer (PID=%d)\n", |
3287 | child, getpid()); | | 3354 | child, getpid()); |
3288 | errno = 0; | | 3355 | errno = 0; |
3289 | lookup_me_fromtracee = | | 3356 | lookup_me_fromtracee = |
3290 | ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0); | | 3357 | ptrace(PT_READ_D, child, &lookup_me_fromtracee, 0); |
3291 | ATF_REQUIRE_EQ(errno, 0); | | 3358 | ATF_REQUIRE_EQ(errno, 0); |
3292 | | | 3359 | |
3293 | ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, | | 3360 | ATF_REQUIRE_EQ_MSG(lookup_me_fromtracee, magic_fromtracee, |
3294 | "got value %#x != expected %#x", lookup_me_fromtracee, | | 3361 | "got value %#x != expected %#x", lookup_me_fromtracee, |
3295 | magic_fromtracee); | | 3362 | magic_fromtracee); |
3296 | | | 3363 | |
3297 | printf("Before resuming the child process where it left off and " | | 3364 | printf("Before resuming the child process where it left off and " |
3298 | "without signal to be sent\n"); | | 3365 | "without signal to be sent\n"); |
3299 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 3366 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
3300 | | | 3367 | |
3301 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3368 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3302 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3369 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
3303 | | | 3370 | |
3304 | validate_status_exited(status, exitval); | | 3371 | validate_status_exited(status, exitval); |
3305 | | | 3372 | |
3306 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3373 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3307 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 3374 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
3308 | } | | 3375 | } |
3309 | | | 3376 | |
3310 | /* These dummy functions are used to be copied with ptrace(2) calls */ | | 3377 | /* These dummy functions are used to be copied with ptrace(2) calls */ |
3311 | static int __used | | 3378 | static int __used |
3312 | dummy_fn1(int a, int b, int c, int d) | | 3379 | dummy_fn1(int a, int b, int c, int d) |
3313 | { | | 3380 | { |
3314 | | | 3381 | |
3315 | a *= 1; | | 3382 | a *= 1; |
3316 | b += 2; | | 3383 | b += 2; |
3317 | c -= 3; | | 3384 | c -= 3; |
3318 | d /= 4; | | 3385 | d /= 4; |
3319 | | | 3386 | |
3320 | return a + b * c - d; | | 3387 | return a + b * c - d; |
3321 | } | | 3388 | } |
3322 | | | 3389 | |
3323 | static int __used | | 3390 | static int __used |
3324 | dummy_fn2(int a, int b, int c, int d) | | 3391 | dummy_fn2(int a, int b, int c, int d) |
3325 | { | | 3392 | { |
3326 | | | 3393 | |
3327 | a *= 4; | | 3394 | a *= 4; |
3328 | b += 3; | | 3395 | b += 3; |
3329 | c -= 2; | | 3396 | c -= 2; |
3330 | d /= 1; | | 3397 | d /= 1; |
3331 | | | 3398 | |
3332 | return a + b * c - d; | | 3399 | return a + b * c - d; |
3333 | } | | 3400 | } |
3334 | | | 3401 | |
3335 | static int __used | | 3402 | static int __used |
3336 | dummy_fn3(int a, int b, int c, int d) | | 3403 | dummy_fn3(int a, int b, int c, int d) |
3337 | { | | 3404 | { |
3338 | | | 3405 | |
3339 | a *= 10; | | 3406 | a *= 10; |
3340 | b += 20; | | 3407 | b += 20; |
3341 | c -= 30; | | 3408 | c -= 30; |
3342 | d /= 40; | | 3409 | d /= 40; |
3343 | | | 3410 | |
3344 | return a + b * c - d; | | 3411 | return a + b * c - d; |
3345 | } | | 3412 | } |
3346 | | | 3413 | |
3347 | static int __used | | 3414 | static int __used |
3348 | dummy_fn4(int a, int b, int c, int d) | | 3415 | dummy_fn4(int a, int b, int c, int d) |
3349 | { | | 3416 | { |
3350 | | | 3417 | |
3351 | a *= 40; | | 3418 | a *= 40; |
3352 | b += 30; | | 3419 | b += 30; |
3353 | c -= 20; | | 3420 | c -= 20; |
3354 | d /= 10; | | 3421 | d /= 10; |
3355 | | | 3422 | |
3356 | return a + b * c - d; | | 3423 | return a + b * c - d; |
3357 | } | | 3424 | } |
3358 | | | 3425 | |
3359 | ATF_TC(io_read_i1); | | 3426 | ATF_TC(io_read_i1); |
3360 | ATF_TC_HEAD(io_read_i1, tc) | | 3427 | ATF_TC_HEAD(io_read_i1, tc) |
3361 | { | | 3428 | { |
3362 | atf_tc_set_md_var(tc, "descr", | | 3429 | atf_tc_set_md_var(tc, "descr", |
3363 | "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)"); | | 3430 | "Verify PT_IO with PIOD_READ_I and len = sizeof(uint8_t)"); |
3364 | } | | 3431 | } |
3365 | | | 3432 | |
3366 | ATF_TC_BODY(io_read_i1, tc) | | 3433 | ATF_TC_BODY(io_read_i1, tc) |
3367 | { | | 3434 | { |
3368 | const int exitval = 5; | | 3435 | const int exitval = 5; |
3369 | const int sigval = SIGSTOP; | | 3436 | const int sigval = SIGSTOP; |
3370 | pid_t child, wpid; | | 3437 | pid_t child, wpid; |
3371 | uint8_t lookup_me = 0; | | 3438 | uint8_t lookup_me = 0; |
3372 | uint8_t magic; | | 3439 | uint8_t magic; |
3373 | memcpy(&magic, dummy_fn1, sizeof(magic)); | | 3440 | memcpy(&magic, dummy_fn1, sizeof(magic)); |
3374 | struct ptrace_io_desc io = { | | 3441 | struct ptrace_io_desc io = { |
3375 | .piod_op = PIOD_READ_I, | | 3442 | .piod_op = PIOD_READ_I, |
3376 | .piod_offs = dummy_fn1, | | 3443 | .piod_offs = dummy_fn1, |
3377 | .piod_addr = &lookup_me, | | 3444 | .piod_addr = &lookup_me, |
3378 | .piod_len = sizeof(lookup_me) | | 3445 | .piod_len = sizeof(lookup_me) |
3379 | }; | | 3446 | }; |
3380 | #if defined(TWAIT_HAVE_STATUS) | | 3447 | #if defined(TWAIT_HAVE_STATUS) |
3381 | int status; | | 3448 | int status; |
3382 | #endif | | 3449 | #endif |
3383 | | | 3450 | |
3384 | printf("Before forking process PID=%d\n", getpid()); | | 3451 | printf("Before forking process PID=%d\n", getpid()); |
3385 | ATF_REQUIRE((child = fork()) != -1); | | 3452 | ATF_REQUIRE((child = fork()) != -1); |
3386 | if (child == 0) { | | 3453 | if (child == 0) { |
3387 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 3454 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
3388 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 3455 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
3389 | | | 3456 | |
3390 | printf("Before raising %s from child\n", strsignal(sigval)); | | 3457 | printf("Before raising %s from child\n", strsignal(sigval)); |
3391 | FORKEE_ASSERT(raise(sigval) == 0); | | 3458 | FORKEE_ASSERT(raise(sigval) == 0); |
3392 | | | 3459 | |
3393 | printf("Before exiting of the child process\n"); | | 3460 | printf("Before exiting of the child process\n"); |
3394 | _exit(exitval); | | 3461 | _exit(exitval); |
3395 | } | | 3462 | } |
3396 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 3463 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
3397 | | | 3464 | |
3398 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 3465 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
3399 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 3466 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
3400 | | | 3467 | |
3401 | validate_status_stopped(status, sigval); | | 3468 | validate_status_stopped(status, sigval); |
3402 | | | 3469 | |
3403 | printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", | | 3470 | printf("Read lookup_me from tracee (PID=%d) by tracer (PID=%d)\n", |
3404 | child, getpid()); | | 3471 | child, getpid()); |
3405 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); | | 3472 | ATF_REQUIRE(ptrace(PT_IO, child, &io, 0) != -1); |
3406 | | | 3473 | |
3407 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, | | 3474 | ATF_REQUIRE_EQ_MSG(lookup_me, magic, |
3408 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic); | | 3475 | "got value %" PRIx8 " != expected %" PRIx8, lookup_me, magic); |
| @@ -4671,1032 +4738,1034 @@ ATF_TC_BODY(kill2, tc) | | | @@ -4671,1032 +4738,1034 @@ ATF_TC_BODY(kill2, tc) |
4671 | ATF_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); | | 4738 | ATF_REQUIRE(ptrace(PT_KILL, child, (void*)1, 0) != -1); |
4672 | | | 4739 | |
4673 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 4740 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
4674 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 4741 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
4675 | | | 4742 | |
4676 | validate_status_signaled(status, SIGKILL, 0); | | 4743 | validate_status_signaled(status, SIGKILL, 0); |
4677 | | | 4744 | |
4678 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 4745 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
4679 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 4746 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
4680 | } | | 4747 | } |
4681 | | | 4748 | |
4682 | ATF_TC(lwpinfo1); | | 4749 | ATF_TC(lwpinfo1); |
4683 | ATF_TC_HEAD(lwpinfo1, tc) | | 4750 | ATF_TC_HEAD(lwpinfo1, tc) |
4684 | { | | 4751 | { |
4685 | atf_tc_set_md_var(tc, "descr", | | 4752 | atf_tc_set_md_var(tc, "descr", |
4686 | "Verify basic LWPINFO call for single thread (PT_TRACE_ME)"); | | 4753 | "Verify basic LWPINFO call for single thread (PT_TRACE_ME)"); |
4687 | } | | 4754 | } |
4688 | | | 4755 | |
4689 | ATF_TC_BODY(lwpinfo1, tc) | | 4756 | ATF_TC_BODY(lwpinfo1, tc) |
4690 | { | | 4757 | { |
4691 | const int exitval = 5; | | 4758 | const int exitval = 5; |
4692 | const int sigval = SIGSTOP; | | 4759 | const int sigval = SIGSTOP; |
4693 | pid_t child, wpid; | | 4760 | pid_t child, wpid; |
4694 | #if defined(TWAIT_HAVE_STATUS) | | 4761 | #if defined(TWAIT_HAVE_STATUS) |
4695 | int status; | | 4762 | int status; |
4696 | #endif | | 4763 | #endif |
4697 | struct ptrace_lwpinfo info = {0, 0}; | | 4764 | struct ptrace_lwpinfo info = {0, 0}; |
4698 | | | 4765 | |
4699 | printf("Before forking process PID=%d\n", getpid()); | | 4766 | printf("Before forking process PID=%d\n", getpid()); |
4700 | ATF_REQUIRE((child = fork()) != -1); | | 4767 | ATF_REQUIRE((child = fork()) != -1); |
4701 | if (child == 0) { | | 4768 | if (child == 0) { |
4702 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 4769 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
4703 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 4770 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
4704 | | | 4771 | |
4705 | printf("Before raising %s from child\n", strsignal(sigval)); | | 4772 | printf("Before raising %s from child\n", strsignal(sigval)); |
4706 | FORKEE_ASSERT(raise(sigval) == 0); | | 4773 | FORKEE_ASSERT(raise(sigval) == 0); |
4707 | | | 4774 | |
4708 | printf("Before exiting of the child process\n"); | | 4775 | printf("Before exiting of the child process\n"); |
4709 | _exit(exitval); | | 4776 | _exit(exitval); |
4710 | } | | 4777 | } |
4711 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 4778 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
4712 | | | 4779 | |
4713 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 4780 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
4714 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 4781 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
4715 | | | 4782 | |
4716 | validate_status_stopped(status, sigval); | | 4783 | validate_status_stopped(status, sigval); |
4717 | | | 4784 | |
4718 | printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); | | 4785 | printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); |
4719 | ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1); | | 4786 | ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1); |
4720 | | | 4787 | |
4721 | printf("Assert that there exists a thread\n"); | | 4788 | printf("Assert that there exists a thread\n"); |
4722 | ATF_REQUIRE(info.pl_lwpid > 0); | | 4789 | ATF_REQUIRE(info.pl_lwpid > 0); |
4723 | | | 4790 | |
4724 | printf("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", | | 4791 | printf("Assert that lwp thread %d received event PL_EVENT_SIGNAL\n", |
4725 | info.pl_lwpid); | | 4792 | info.pl_lwpid); |
4726 | ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL, | | 4793 | ATF_REQUIRE_EQ_MSG(info.pl_event, PL_EVENT_SIGNAL, |
4727 | "Received event %d != expected event %d", | | 4794 | "Received event %d != expected event %d", |
4728 | info.pl_event, PL_EVENT_SIGNAL); | | 4795 | info.pl_event, PL_EVENT_SIGNAL); |
4729 | | | 4796 | |
4730 | printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); | | 4797 | printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); |
4731 | ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1); | | 4798 | ATF_REQUIRE(ptrace(PT_LWPINFO, child, &info, sizeof(info)) != -1); |
4732 | | | 4799 | |
4733 | printf("Assert that there are no more lwp threads in child\n"); | | 4800 | printf("Assert that there are no more lwp threads in child\n"); |
4734 | ATF_REQUIRE_EQ(info.pl_lwpid, 0); | | 4801 | ATF_REQUIRE_EQ(info.pl_lwpid, 0); |
4735 | | | 4802 | |
4736 | printf("Before resuming the child process where it left off and " | | 4803 | printf("Before resuming the child process where it left off and " |
4737 | "without signal to be sent\n"); | | 4804 | "without signal to be sent\n"); |
4738 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 4805 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
4739 | | | 4806 | |
4740 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 4807 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
4741 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 4808 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
4742 | | | 4809 | |
4743 | validate_status_exited(status, exitval); | | 4810 | validate_status_exited(status, exitval); |
4744 | | | 4811 | |
4745 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 4812 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
4746 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 4813 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
4747 | } | | 4814 | } |
4748 | | | 4815 | |
4749 | #if defined(TWAIT_HAVE_PID) | | 4816 | #if defined(TWAIT_HAVE_PID) |
4750 | ATF_TC(lwpinfo2); | | 4817 | ATF_TC(lwpinfo2); |
4751 | ATF_TC_HEAD(lwpinfo2, tc) | | 4818 | ATF_TC_HEAD(lwpinfo2, tc) |
4752 | { | | 4819 | { |
4753 | atf_tc_set_md_var(tc, "descr", | | 4820 | atf_tc_set_md_var(tc, "descr", |
4754 | "Verify basic LWPINFO call for single thread (PT_ATTACH from " | | 4821 | "Verify basic LWPINFO call for single thread (PT_ATTACH from " |
4755 | "tracer)"); | | 4822 | "tracer)"); |
4756 | } | | 4823 | } |
4757 | | | 4824 | |
4758 | ATF_TC_BODY(lwpinfo2, tc) | | 4825 | ATF_TC_BODY(lwpinfo2, tc) |
4759 | { | | 4826 | { |
4760 | struct msg_fds parent_tracee, parent_tracer; | | 4827 | struct msg_fds parent_tracee, parent_tracer; |
4761 | const int exitval_tracee = 5; | | 4828 | const int exitval_tracee = 5; |
4762 | const int exitval_tracer = 10; | | 4829 | const int exitval_tracer = 10; |
4763 | pid_t tracee, tracer, wpid; | | 4830 | pid_t tracee, tracer, wpid; |
4764 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ | | 4831 | uint8_t msg = 0xde; /* dummy message for IPC based on pipe(2) */ |
4765 | #if defined(TWAIT_HAVE_STATUS) | | 4832 | #if defined(TWAIT_HAVE_STATUS) |
4766 | int status; | | 4833 | int status; |
4767 | #endif | | 4834 | #endif |
4768 | struct ptrace_lwpinfo info = {0, 0}; | | 4835 | struct ptrace_lwpinfo info = {0, 0}; |
4769 | | | 4836 | |
4770 | printf("Spawn tracee\n"); | | 4837 | printf("Spawn tracee\n"); |
4771 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); | | 4838 | ATF_REQUIRE(msg_open(&parent_tracee) == 0); |
4772 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); | | 4839 | ATF_REQUIRE(msg_open(&parent_tracer) == 0); |
4773 | tracee = atf_utils_fork(); | | 4840 | tracee = atf_utils_fork(); |
4774 | if (tracee == 0) { | | 4841 | if (tracee == 0) { |
4775 | | | 4842 | |
4776 | /* Wait for message from the parent */ | | 4843 | /* Wait for message from the parent */ |
4777 | CHILD_TO_PARENT("tracee ready", parent_tracee, msg); | | 4844 | CHILD_TO_PARENT("tracee ready", parent_tracee, msg); |
4778 | CHILD_FROM_PARENT("tracee exit", parent_tracee, msg); | | 4845 | CHILD_FROM_PARENT("tracee exit", parent_tracee, msg); |
4779 | | | 4846 | |
4780 | _exit(exitval_tracee); | | 4847 | _exit(exitval_tracee); |
4781 | } | | 4848 | } |
4782 | PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); | | 4849 | PARENT_FROM_CHILD("tracee ready", parent_tracee, msg); |
4783 | | | 4850 | |
4784 | printf("Spawn debugger\n"); | | 4851 | printf("Spawn debugger\n"); |
4785 | tracer = atf_utils_fork(); | | 4852 | tracer = atf_utils_fork(); |
4786 | if (tracer == 0) { | | 4853 | if (tracer == 0) { |
4787 | /* No IPC to communicate with the child */ | | 4854 | /* No IPC to communicate with the child */ |
4788 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); | | 4855 | printf("Before calling PT_ATTACH from tracee %d\n", getpid()); |
4789 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); | | 4856 | FORKEE_ASSERT(ptrace(PT_ATTACH, tracee, NULL, 0) != -1); |
4790 | | | 4857 | |
4791 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ | | 4858 | /* Wait for tracee and assert that it was stopped w/ SIGSTOP */ |
4792 | FORKEE_REQUIRE_SUCCESS( | | 4859 | FORKEE_REQUIRE_SUCCESS( |
4793 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 4860 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
4794 | | | 4861 | |
4795 | forkee_status_stopped(status, SIGSTOP); | | 4862 | forkee_status_stopped(status, SIGSTOP); |
4796 | | | 4863 | |
4797 | printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); | | 4864 | printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); |
4798 | FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info)) | | 4865 | FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info)) |
4799 | != -1); | | 4866 | != -1); |
4800 | | | 4867 | |
4801 | printf("Assert that there exists a thread\n"); | | 4868 | printf("Assert that there exists a thread\n"); |
4802 | FORKEE_ASSERTX(info.pl_lwpid > 0); | | 4869 | FORKEE_ASSERTX(info.pl_lwpid > 0); |
4803 | | | 4870 | |
4804 | printf("Assert that lwp thread %d received event " | | 4871 | printf("Assert that lwp thread %d received event " |
4805 | "PL_EVENT_SIGNAL\n", info.pl_lwpid); | | 4872 | "PL_EVENT_SIGNAL\n", info.pl_lwpid); |
4806 | FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL); | | 4873 | FORKEE_ASSERT_EQ(info.pl_event, PL_EVENT_SIGNAL); |
4807 | | | 4874 | |
4808 | printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); | | 4875 | printf("Before calling ptrace(2) with PT_LWPINFO for child\n"); |
4809 | FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info)) | | 4876 | FORKEE_ASSERT(ptrace(PT_LWPINFO, tracee, &info, sizeof(info)) |
4810 | != -1); | | 4877 | != -1); |
4811 | | | 4878 | |
4812 | printf("Assert that there are no more lwp threads in child\n"); | | 4879 | printf("Assert that there are no more lwp threads in child\n"); |
4813 | FORKEE_ASSERTX(info.pl_lwpid == 0); | | 4880 | FORKEE_ASSERTX(info.pl_lwpid == 0); |
4814 | | | 4881 | |
4815 | /* Resume tracee with PT_CONTINUE */ | | 4882 | /* Resume tracee with PT_CONTINUE */ |
4816 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); | | 4883 | FORKEE_ASSERT(ptrace(PT_CONTINUE, tracee, (void *)1, 0) != -1); |
4817 | | | 4884 | |
4818 | /* Inform parent that tracer has attached to tracee */ | | 4885 | /* Inform parent that tracer has attached to tracee */ |
4819 | CHILD_TO_PARENT("tracer ready", parent_tracer, msg); | | 4886 | CHILD_TO_PARENT("tracer ready", parent_tracer, msg); |
4820 | /* Wait for parent */ | | 4887 | /* Wait for parent */ |
4821 | CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); | | 4888 | CHILD_FROM_PARENT("tracer wait", parent_tracer, msg); |
4822 | | | 4889 | |
4823 | /* Wait for tracee and assert that it exited */ | | 4890 | /* Wait for tracee and assert that it exited */ |
4824 | FORKEE_REQUIRE_SUCCESS( | | 4891 | FORKEE_REQUIRE_SUCCESS( |
4825 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); | | 4892 | wpid = TWAIT_GENERIC(tracee, &status, 0), tracee); |
4826 | | | 4893 | |
4827 | forkee_status_exited(status, exitval_tracee); | | 4894 | forkee_status_exited(status, exitval_tracee); |
4828 | | | 4895 | |
4829 | printf("Before exiting of the tracer process\n"); | | 4896 | printf("Before exiting of the tracer process\n"); |
4830 | _exit(exitval_tracer); | | 4897 | _exit(exitval_tracer); |
4831 | } | | 4898 | } |
4832 | | | 4899 | |
4833 | printf("Wait for the tracer to attach to the tracee\n"); | | 4900 | printf("Wait for the tracer to attach to the tracee\n"); |
4834 | PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); | | 4901 | PARENT_FROM_CHILD("tracer ready", parent_tracer, msg); |
4835 | | | 4902 | |
4836 | printf("Resume the tracee and let it exit\n"); | | 4903 | printf("Resume the tracee and let it exit\n"); |
4837 | PARENT_TO_CHILD("tracee exit", parent_tracee, msg); | | 4904 | PARENT_TO_CHILD("tracee exit", parent_tracee, msg); |
4838 | | | 4905 | |
4839 | printf("Detect that tracee is zombie\n"); | | 4906 | printf("Detect that tracee is zombie\n"); |
4840 | await_zombie(tracee); | | 4907 | await_zombie(tracee); |
4841 | | | 4908 | |
4842 | printf("Assert that there is no status about tracee - " | | 4909 | printf("Assert that there is no status about tracee - " |
4843 | "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); | | 4910 | "Tracer must detect zombie first - calling %s()\n", TWAIT_FNAME); |
4844 | TWAIT_REQUIRE_SUCCESS( | | 4911 | TWAIT_REQUIRE_SUCCESS( |
4845 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); | | 4912 | wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), 0); |
4846 | | | 4913 | |
4847 | printf("Resume the tracer and let it detect exited tracee\n"); | | 4914 | printf("Resume the tracer and let it detect exited tracee\n"); |
4848 | PARENT_TO_CHILD("tracer wait", parent_tracer, msg); | | 4915 | PARENT_TO_CHILD("tracer wait", parent_tracer, msg); |
4849 | | | 4916 | |
4850 | printf("Wait for tracer to finish its job and exit - calling %s()\n", | | 4917 | printf("Wait for tracer to finish its job and exit - calling %s()\n", |
4851 | TWAIT_FNAME); | | 4918 | TWAIT_FNAME); |
4852 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), | | 4919 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracer, &status, 0), |
4853 | tracer); | | 4920 | tracer); |
4854 | | | 4921 | |
4855 | validate_status_exited(status, exitval_tracer); | | 4922 | validate_status_exited(status, exitval_tracer); |
4856 | | | 4923 | |
4857 | printf("Wait for tracee to finish its job and exit - calling %s()\n", | | 4924 | printf("Wait for tracee to finish its job and exit - calling %s()\n", |
4858 | TWAIT_FNAME); | | 4925 | TWAIT_FNAME); |
4859 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), | | 4926 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(tracee, &status, WNOHANG), |
4860 | tracee); | | 4927 | tracee); |
4861 | | | 4928 | |
4862 | validate_status_exited(status, exitval_tracee); | | 4929 | validate_status_exited(status, exitval_tracee); |
4863 | | | 4930 | |
4864 | msg_close(&parent_tracer); | | 4931 | msg_close(&parent_tracer); |
4865 | msg_close(&parent_tracee); | | 4932 | msg_close(&parent_tracee); |
4866 | } | | 4933 | } |
4867 | #endif | | 4934 | #endif |
4868 | | | 4935 | |
4869 | ATF_TC(siginfo1); | | 4936 | ATF_TC(siginfo1); |
4870 | ATF_TC_HEAD(siginfo1, tc) | | 4937 | ATF_TC_HEAD(siginfo1, tc) |
4871 | { | | 4938 | { |
4872 | atf_tc_set_md_var(tc, "descr", | | 4939 | atf_tc_set_md_var(tc, "descr", |
4873 | "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee"); | | 4940 | "Verify basic PT_GET_SIGINFO call for SIGTRAP from tracee"); |
4874 | } | | 4941 | } |
4875 | | | 4942 | |
4876 | ATF_TC_BODY(siginfo1, tc) | | 4943 | ATF_TC_BODY(siginfo1, tc) |
4877 | { | | 4944 | { |
4878 | const int exitval = 5; | | 4945 | const int exitval = 5; |
4879 | const int sigval = SIGTRAP; | | 4946 | const int sigval = SIGTRAP; |
4880 | pid_t child, wpid; | | 4947 | pid_t child, wpid; |
4881 | #if defined(TWAIT_HAVE_STATUS) | | 4948 | #if defined(TWAIT_HAVE_STATUS) |
4882 | int status; | | 4949 | int status; |
4883 | #endif | | 4950 | #endif |
4884 | struct ptrace_siginfo info; | | 4951 | struct ptrace_siginfo info; |
4885 | memset(&info, 0, sizeof(info)); | | 4952 | memset(&info, 0, sizeof(info)); |
4886 | | | 4953 | |
4887 | printf("Before forking process PID=%d\n", getpid()); | | 4954 | printf("Before forking process PID=%d\n", getpid()); |
4888 | ATF_REQUIRE((child = fork()) != -1); | | 4955 | ATF_REQUIRE((child = fork()) != -1); |
4889 | if (child == 0) { | | 4956 | if (child == 0) { |
4890 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 4957 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
4891 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 4958 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
4892 | | | 4959 | |
4893 | printf("Before raising %s from child\n", strsignal(sigval)); | | 4960 | printf("Before raising %s from child\n", strsignal(sigval)); |
4894 | FORKEE_ASSERT(raise(sigval) == 0); | | 4961 | FORKEE_ASSERT(raise(sigval) == 0); |
4895 | | | 4962 | |
4896 | printf("Before exiting of the child process\n"); | | 4963 | printf("Before exiting of the child process\n"); |
4897 | _exit(exitval); | | 4964 | _exit(exitval); |
4898 | } | | 4965 | } |
4899 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 4966 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
4900 | | | 4967 | |
4901 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 4968 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
4902 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 4969 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
4903 | | | 4970 | |
4904 | validate_status_stopped(status, sigval); | | 4971 | validate_status_stopped(status, sigval); |
4905 | | | 4972 | |
4906 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 4973 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
4907 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 4974 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
4908 | | | 4975 | |
4909 | printf("Signal traced to lwpid=%d\n", info.psi_lwpid); | | 4976 | printf("Signal traced to lwpid=%d\n", info.psi_lwpid); |
4910 | printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", | | 4977 | printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", |
4911 | info.psi_siginfo.si_signo, info.psi_siginfo.si_code, | | 4978 | info.psi_siginfo.si_signo, info.psi_siginfo.si_code, |
4912 | info.psi_siginfo.si_errno); | | 4979 | info.psi_siginfo.si_errno); |
4913 | | | 4980 | |
4914 | printf("Before resuming the child process where it left off and " | | 4981 | printf("Before resuming the child process where it left off and " |
4915 | "without signal to be sent\n"); | | 4982 | "without signal to be sent\n"); |
4916 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 4983 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
4917 | | | 4984 | |
4918 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 4985 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
4919 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 4986 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
4920 | | | 4987 | |
4921 | validate_status_exited(status, exitval); | | 4988 | validate_status_exited(status, exitval); |
4922 | | | 4989 | |
4923 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 4990 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
4924 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 4991 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
4925 | } | | 4992 | } |
4926 | | | 4993 | |
4927 | ATF_TC(siginfo2); | | 4994 | ATF_TC(siginfo2); |
4928 | ATF_TC_HEAD(siginfo2, tc) | | 4995 | ATF_TC_HEAD(siginfo2, tc) |
4929 | { | | 4996 | { |
4930 | atf_tc_set_md_var(tc, "descr", | | 4997 | atf_tc_set_md_var(tc, "descr", |
4931 | "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without " | | 4998 | "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls without " |
4932 | "modification of SIGINT from tracee"); | | 4999 | "modification of SIGINT from tracee"); |
4933 | } | | 5000 | } |
4934 | | | 5001 | |
4935 | static int siginfo2_caught = 0; | | 5002 | static int siginfo2_caught = 0; |
4936 | | | 5003 | |
4937 | static void | | 5004 | static void |
4938 | siginfo2_sighandler(int sig) | | 5005 | siginfo2_sighandler(int sig) |
4939 | { | | 5006 | { |
4940 | FORKEE_ASSERT_EQ(sig, SIGINT); | | 5007 | FORKEE_ASSERT_EQ(sig, SIGINT); |
4941 | | | 5008 | |
4942 | ++siginfo2_caught; | | 5009 | ++siginfo2_caught; |
4943 | } | | 5010 | } |
4944 | | | 5011 | |
4945 | ATF_TC_BODY(siginfo2, tc) | | 5012 | ATF_TC_BODY(siginfo2, tc) |
4946 | { | | 5013 | { |
4947 | const int exitval = 5; | | 5014 | const int exitval = 5; |
4948 | const int sigval = SIGINT; | | 5015 | const int sigval = SIGINT; |
4949 | pid_t child, wpid; | | 5016 | pid_t child, wpid; |
4950 | struct sigaction sa; | | 5017 | struct sigaction sa; |
4951 | #if defined(TWAIT_HAVE_STATUS) | | 5018 | #if defined(TWAIT_HAVE_STATUS) |
4952 | int status; | | 5019 | int status; |
4953 | #endif | | 5020 | #endif |
4954 | struct ptrace_siginfo info; | | 5021 | struct ptrace_siginfo info; |
4955 | memset(&info, 0, sizeof(info)); | | 5022 | memset(&info, 0, sizeof(info)); |
4956 | | | 5023 | |
4957 | printf("Before forking process PID=%d\n", getpid()); | | 5024 | printf("Before forking process PID=%d\n", getpid()); |
4958 | ATF_REQUIRE((child = fork()) != -1); | | 5025 | ATF_REQUIRE((child = fork()) != -1); |
4959 | if (child == 0) { | | 5026 | if (child == 0) { |
4960 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 5027 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
4961 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 5028 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
4962 | | | 5029 | |
4963 | sa.sa_handler = siginfo2_sighandler; | | 5030 | sa.sa_handler = siginfo2_sighandler; |
4964 | sa.sa_flags = SA_SIGINFO; | | 5031 | sa.sa_flags = SA_SIGINFO; |
4965 | sigemptyset(&sa.sa_mask); | | 5032 | sigemptyset(&sa.sa_mask); |
4966 | | | 5033 | |
4967 | FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); | | 5034 | FORKEE_ASSERT(sigaction(sigval, &sa, NULL) != -1); |
4968 | | | 5035 | |
4969 | printf("Before raising %s from child\n", strsignal(sigval)); | | 5036 | printf("Before raising %s from child\n", strsignal(sigval)); |
4970 | FORKEE_ASSERT(raise(sigval) == 0); | | 5037 | FORKEE_ASSERT(raise(sigval) == 0); |
4971 | | | 5038 | |
4972 | FORKEE_ASSERT_EQ(siginfo2_caught, 1); | | 5039 | FORKEE_ASSERT_EQ(siginfo2_caught, 1); |
4973 | | | 5040 | |
4974 | printf("Before exiting of the child process\n"); | | 5041 | printf("Before exiting of the child process\n"); |
4975 | _exit(exitval); | | 5042 | _exit(exitval); |
4976 | } | | 5043 | } |
4977 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 5044 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
4978 | | | 5045 | |
4979 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5046 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
4980 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5047 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
4981 | | | 5048 | |
4982 | validate_status_stopped(status, sigval); | | 5049 | validate_status_stopped(status, sigval); |
4983 | | | 5050 | |
4984 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 5051 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
4985 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5052 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
4986 | | | 5053 | |
4987 | printf("Signal traced to lwpid=%d\n", info.psi_lwpid); | | 5054 | printf("Signal traced to lwpid=%d\n", info.psi_lwpid); |
4988 | printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", | | 5055 | printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", |
4989 | info.psi_siginfo.si_signo, info.psi_siginfo.si_code, | | 5056 | info.psi_siginfo.si_signo, info.psi_siginfo.si_code, |
4990 | info.psi_siginfo.si_errno); | | 5057 | info.psi_siginfo.si_errno); |
4991 | | | 5058 | |
4992 | printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); | | 5059 | printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); |
4993 | ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5060 | ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); |
4994 | | | 5061 | |
4995 | printf("Before resuming the child process where it left off and " | | 5062 | printf("Before resuming the child process where it left off and " |
4996 | "without signal to be sent\n"); | | 5063 | "without signal to be sent\n"); |
4997 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1); | | 5064 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigval) != -1); |
4998 | | | 5065 | |
4999 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5066 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5000 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5067 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5001 | | | 5068 | |
5002 | validate_status_exited(status, exitval); | | 5069 | validate_status_exited(status, exitval); |
5003 | | | 5070 | |
5004 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5071 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5005 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 5072 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
5006 | } | | 5073 | } |
5007 | | | 5074 | |
5008 | ATF_TC(siginfo3); | | 5075 | ATF_TC(siginfo3); |
5009 | ATF_TC_HEAD(siginfo3, tc) | | 5076 | ATF_TC_HEAD(siginfo3, tc) |
5010 | { | | 5077 | { |
5011 | atf_tc_set_md_var(tc, "descr", | | 5078 | atf_tc_set_md_var(tc, "descr", |
5012 | "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with " | | 5079 | "Verify basic PT_GET_SIGINFO and PT_SET_SIGINFO calls with " |
5013 | "setting signal to new value"); | | 5080 | "setting signal to new value"); |
5014 | } | | 5081 | } |
5015 | | | 5082 | |
5016 | static int siginfo3_caught = 0; | | 5083 | static int siginfo3_caught = 0; |
5017 | | | 5084 | |
5018 | static void | | 5085 | static void |
5019 | siginfo3_sigaction(int sig, siginfo_t *info, void *ctx) | | 5086 | siginfo3_sigaction(int sig, siginfo_t *info, void *ctx) |
5020 | { | | 5087 | { |
5021 | FORKEE_ASSERT_EQ(sig, SIGTRAP); | | 5088 | FORKEE_ASSERT_EQ(sig, SIGTRAP); |
5022 | | | 5089 | |
5023 | FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); | | 5090 | FORKEE_ASSERT_EQ(info->si_signo, SIGTRAP); |
5024 | FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); | | 5091 | FORKEE_ASSERT_EQ(info->si_code, TRAP_BRKPT); |
5025 | | | 5092 | |
5026 | ++siginfo3_caught; | | 5093 | ++siginfo3_caught; |
5027 | } | | 5094 | } |
5028 | | | 5095 | |
5029 | ATF_TC_BODY(siginfo3, tc) | | 5096 | ATF_TC_BODY(siginfo3, tc) |
5030 | { | | 5097 | { |
5031 | const int exitval = 5; | | 5098 | const int exitval = 5; |
5032 | const int sigval = SIGINT; | | 5099 | const int sigval = SIGINT; |
5033 | const int sigfaked = SIGTRAP; | | 5100 | const int sigfaked = SIGTRAP; |
5034 | const int sicodefaked = TRAP_BRKPT; | | 5101 | const int sicodefaked = TRAP_BRKPT; |
5035 | pid_t child, wpid; | | 5102 | pid_t child, wpid; |
5036 | struct sigaction sa; | | 5103 | struct sigaction sa; |
5037 | #if defined(TWAIT_HAVE_STATUS) | | 5104 | #if defined(TWAIT_HAVE_STATUS) |
5038 | int status; | | 5105 | int status; |
5039 | #endif | | 5106 | #endif |
5040 | struct ptrace_siginfo info; | | 5107 | struct ptrace_siginfo info; |
5041 | memset(&info, 0, sizeof(info)); | | 5108 | memset(&info, 0, sizeof(info)); |
5042 | | | 5109 | |
5043 | printf("Before forking process PID=%d\n", getpid()); | | 5110 | printf("Before forking process PID=%d\n", getpid()); |
5044 | ATF_REQUIRE((child = fork()) != -1); | | 5111 | ATF_REQUIRE((child = fork()) != -1); |
5045 | if (child == 0) { | | 5112 | if (child == 0) { |
5046 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 5113 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
5047 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 5114 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
5048 | | | 5115 | |
5049 | sa.sa_sigaction = siginfo3_sigaction; | | 5116 | sa.sa_sigaction = siginfo3_sigaction; |
5050 | sa.sa_flags = SA_SIGINFO; | | 5117 | sa.sa_flags = SA_SIGINFO; |
5051 | sigemptyset(&sa.sa_mask); | | 5118 | sigemptyset(&sa.sa_mask); |
5052 | | | 5119 | |
5053 | FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1); | | 5120 | FORKEE_ASSERT(sigaction(sigfaked, &sa, NULL) != -1); |
5054 | | | 5121 | |
5055 | printf("Before raising %s from child\n", strsignal(sigval)); | | 5122 | printf("Before raising %s from child\n", strsignal(sigval)); |
5056 | FORKEE_ASSERT(raise(sigval) == 0); | | 5123 | FORKEE_ASSERT(raise(sigval) == 0); |
5057 | | | 5124 | |
5058 | FORKEE_ASSERT_EQ(siginfo3_caught, 1); | | 5125 | FORKEE_ASSERT_EQ(siginfo3_caught, 1); |
5059 | | | 5126 | |
5060 | printf("Before exiting of the child process\n"); | | 5127 | printf("Before exiting of the child process\n"); |
5061 | _exit(exitval); | | 5128 | _exit(exitval); |
5062 | } | | 5129 | } |
5063 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 5130 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
5064 | | | 5131 | |
5065 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5132 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5066 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5133 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5067 | | | 5134 | |
5068 | validate_status_stopped(status, sigval); | | 5135 | validate_status_stopped(status, sigval); |
5069 | | | 5136 | |
5070 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 5137 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
5071 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5138 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
5072 | | | 5139 | |
5073 | printf("Signal traced to lwpid=%d\n", info.psi_lwpid); | | 5140 | printf("Signal traced to lwpid=%d\n", info.psi_lwpid); |
5074 | printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", | | 5141 | printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", |
5075 | info.psi_siginfo.si_signo, info.psi_siginfo.si_code, | | 5142 | info.psi_siginfo.si_signo, info.psi_siginfo.si_code, |
5076 | info.psi_siginfo.si_errno); | | 5143 | info.psi_siginfo.si_errno); |
5077 | | | 5144 | |
5078 | printf("Before setting new faked signal to signo=%d si_code=%d\n", | | 5145 | printf("Before setting new faked signal to signo=%d si_code=%d\n", |
5079 | sigfaked, sicodefaked); | | 5146 | sigfaked, sicodefaked); |
5080 | info.psi_siginfo.si_signo = sigfaked; | | 5147 | info.psi_siginfo.si_signo = sigfaked; |
5081 | info.psi_siginfo.si_code = sicodefaked; | | 5148 | info.psi_siginfo.si_code = sicodefaked; |
5082 | | | 5149 | |
5083 | printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); | | 5150 | printf("Before calling ptrace(2) with PT_SET_SIGINFO for child\n"); |
5084 | ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5151 | ATF_REQUIRE(ptrace(PT_SET_SIGINFO, child, &info, sizeof(info)) != -1); |
5085 | | | 5152 | |
5086 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 5153 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
5087 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5154 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
5088 | | | 5155 | |
5089 | printf("Before checking siginfo_t\n"); | | 5156 | printf("Before checking siginfo_t\n"); |
5090 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); | | 5157 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigfaked); |
5091 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); | | 5158 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, sicodefaked); |
5092 | | | 5159 | |
5093 | printf("Before resuming the child process where it left off and " | | 5160 | printf("Before resuming the child process where it left off and " |
5094 | "without signal to be sent\n"); | | 5161 | "without signal to be sent\n"); |
5095 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1); | | 5162 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, sigfaked) != -1); |
5096 | | | 5163 | |
5097 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5164 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5098 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5165 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5099 | | | 5166 | |
5100 | validate_status_exited(status, exitval); | | 5167 | validate_status_exited(status, exitval); |
5101 | | | 5168 | |
5102 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5169 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5103 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 5170 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
5104 | } | | 5171 | } |
5105 | | | 5172 | |
5106 | ATF_TC(siginfo4); | | 5173 | ATF_TC(siginfo4); |
5107 | ATF_TC_HEAD(siginfo4, tc) | | 5174 | ATF_TC_HEAD(siginfo4, tc) |
5108 | { | | 5175 | { |
5109 | atf_tc_set_md_var(tc, "descr", | | 5176 | atf_tc_set_md_var(tc, "descr", |
5110 | "Detect SIGTRAP TRAP_EXEC from tracee"); | | 5177 | "Detect SIGTRAP TRAP_EXEC from tracee"); |
5111 | } | | 5178 | } |
5112 | | | 5179 | |
5113 | ATF_TC_BODY(siginfo4, tc) | | 5180 | ATF_TC_BODY(siginfo4, tc) |
5114 | { | | 5181 | { |
5115 | const int sigval = SIGTRAP; | | 5182 | const int sigval = SIGTRAP; |
5116 | pid_t child, wpid; | | 5183 | pid_t child, wpid; |
5117 | #if defined(TWAIT_HAVE_STATUS) | | 5184 | #if defined(TWAIT_HAVE_STATUS) |
5118 | int status; | | 5185 | int status; |
5119 | #endif | | 5186 | #endif |
5120 | | | 5187 | |
5121 | struct ptrace_siginfo info; | | 5188 | struct ptrace_siginfo info; |
5122 | memset(&info, 0, sizeof(info)); | | 5189 | memset(&info, 0, sizeof(info)); |
5123 | | | 5190 | |
5124 | printf("Before forking process PID=%d\n", getpid()); | | 5191 | printf("Before forking process PID=%d\n", getpid()); |
5125 | ATF_REQUIRE((child = fork()) != -1); | | 5192 | ATF_REQUIRE((child = fork()) != -1); |
5126 | if (child == 0) { | | 5193 | if (child == 0) { |
5127 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 5194 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
5128 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 5195 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
5129 | | | 5196 | |
5130 | printf("Before calling execve(2) from child\n"); | | 5197 | printf("Before calling execve(2) from child\n"); |
5131 | execlp("/bin/echo", "/bin/echo", NULL); | | 5198 | execlp("/bin/echo", "/bin/echo", NULL); |
5132 | | | 5199 | |
5133 | FORKEE_ASSERT(0 && "Not reached"); | | 5200 | FORKEE_ASSERT(0 && "Not reached"); |
5134 | } | | 5201 | } |
5135 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 5202 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
5136 | | | 5203 | |
5137 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5204 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5138 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5205 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5139 | | | 5206 | |
5140 | validate_status_stopped(status, sigval); | | 5207 | validate_status_stopped(status, sigval); |
5141 | | | 5208 | |
5142 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 5209 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
5143 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5210 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
5144 | | | 5211 | |
5145 | printf("Signal traced to lwpid=%d\n", info.psi_lwpid); | | 5212 | printf("Signal traced to lwpid=%d\n", info.psi_lwpid); |
5146 | printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", | | 5213 | printf("Signal properties: si_signo=%#x si_code=%#x si_errno=%#x\n", |
5147 | info.psi_siginfo.si_signo, info.psi_siginfo.si_code, | | 5214 | info.psi_siginfo.si_signo, info.psi_siginfo.si_code, |
5148 | info.psi_siginfo.si_errno); | | 5215 | info.psi_siginfo.si_errno); |
5149 | | | 5216 | |
5150 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); | | 5217 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); |
5151 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); | | 5218 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_EXEC); |
5152 | | | 5219 | |
5153 | printf("Before resuming the child process where it left off and " | | 5220 | printf("Before resuming the child process where it left off and " |
5154 | "without signal to be sent\n"); | | 5221 | "without signal to be sent\n"); |
5155 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 5222 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
5156 | | | 5223 | |
5157 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5224 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5158 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5225 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5159 | | | 5226 | |
5160 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5227 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5161 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 5228 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
5162 | } | | 5229 | } |
5163 | | | 5230 | |
5164 | #if defined(TWAIT_HAVE_PID) | | 5231 | #if defined(TWAIT_HAVE_PID) |
5165 | ATF_TC(siginfo5); | | 5232 | ATF_TC(siginfo5); |
5166 | ATF_TC_HEAD(siginfo5, tc) | | 5233 | ATF_TC_HEAD(siginfo5, tc) |
5167 | { | | 5234 | { |
5168 | atf_tc_set_md_var(tc, "descr", | | 5235 | atf_tc_set_md_var(tc, "descr", |
5169 | "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK " | | 5236 | "Verify that fork(2) is intercepted by ptrace(2) with EVENT_MASK " |
5170 | "set to PTRACE_FORK and reports correct signal information"); | | 5237 | "set to PTRACE_FORK and reports correct signal information"); |
5171 | } | | 5238 | } |
5172 | | | 5239 | |
5173 | ATF_TC_BODY(siginfo5, tc) | | 5240 | ATF_TC_BODY(siginfo5, tc) |
5174 | { | | 5241 | { |
5175 | const int exitval = 5; | | 5242 | const int exitval = 5; |
5176 | const int exitval2 = 15; | | 5243 | const int exitval2 = 15; |
5177 | const int sigval = SIGSTOP; | | 5244 | const int sigval = SIGSTOP; |
5178 | pid_t child, child2, wpid; | | 5245 | pid_t child, child2, wpid; |
5179 | #if defined(TWAIT_HAVE_STATUS) | | 5246 | #if defined(TWAIT_HAVE_STATUS) |
5180 | int status; | | 5247 | int status; |
5181 | #endif | | 5248 | #endif |
5182 | ptrace_state_t state; | | 5249 | ptrace_state_t state; |
5183 | const int slen = sizeof(state); | | 5250 | const int slen = sizeof(state); |
5184 | ptrace_event_t event; | | 5251 | ptrace_event_t event; |
5185 | const int elen = sizeof(event); | | 5252 | const int elen = sizeof(event); |
5186 | struct ptrace_siginfo info; | | 5253 | struct ptrace_siginfo info; |
5187 | | | 5254 | |
5188 | memset(&info, 0, sizeof(info)); | | 5255 | memset(&info, 0, sizeof(info)); |
5189 | | | 5256 | |
5190 | printf("Before forking process PID=%d\n", getpid()); | | 5257 | printf("Before forking process PID=%d\n", getpid()); |
5191 | ATF_REQUIRE((child = fork()) != -1); | | 5258 | ATF_REQUIRE((child = fork()) != -1); |
5192 | if (child == 0) { | | 5259 | if (child == 0) { |
5193 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 5260 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
5194 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 5261 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
5195 | | | 5262 | |
5196 | printf("Before raising %s from child\n", strsignal(sigval)); | | 5263 | printf("Before raising %s from child\n", strsignal(sigval)); |
5197 | FORKEE_ASSERT(raise(sigval) == 0); | | 5264 | FORKEE_ASSERT(raise(sigval) == 0); |
5198 | | | 5265 | |
5199 | FORKEE_ASSERT((child2 = fork()) != 1); | | 5266 | FORKEE_ASSERT((child2 = fork()) != 1); |
5200 | | | 5267 | |
5201 | if (child2 == 0) | | 5268 | if (child2 == 0) |
5202 | _exit(exitval2); | | 5269 | _exit(exitval2); |
5203 | | | 5270 | |
5204 | FORKEE_REQUIRE_SUCCESS | | 5271 | FORKEE_REQUIRE_SUCCESS |
5205 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); | | 5272 | (wpid = TWAIT_GENERIC(child2, &status, 0), child2); |
5206 | | | 5273 | |
5207 | forkee_status_exited(status, exitval2); | | 5274 | forkee_status_exited(status, exitval2); |
5208 | | | 5275 | |
5209 | printf("Before exiting of the child process\n"); | | 5276 | printf("Before exiting of the child process\n"); |
5210 | _exit(exitval); | | 5277 | _exit(exitval); |
5211 | } | | 5278 | } |
5212 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 5279 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
5213 | | | 5280 | |
5214 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5281 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5215 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5282 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5216 | | | 5283 | |
5217 | validate_status_stopped(status, sigval); | | 5284 | validate_status_stopped(status, sigval); |
5218 | | | 5285 | |
5219 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 5286 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
5220 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5287 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
5221 | | | 5288 | |
5222 | printf("Before checking siginfo_t\n"); | | 5289 | printf("Before checking siginfo_t\n"); |
5223 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); | | 5290 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); |
5224 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); | | 5291 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); |
5225 | | | 5292 | |
5226 | printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); | | 5293 | printf("Enable PTRACE_FORK in EVENT_MASK for the child %d\n", child); |
5227 | event.pe_set_event = PTRACE_FORK; | | 5294 | event.pe_set_event = PTRACE_FORK; |
5228 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); | | 5295 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); |
5229 | | | 5296 | |
5230 | printf("Before resuming the child process where it left off and " | | 5297 | printf("Before resuming the child process where it left off and " |
5231 | "without signal to be sent\n"); | | 5298 | "without signal to be sent\n"); |
5232 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 5299 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
5233 | | | 5300 | |
5234 | printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); | | 5301 | printf("Before calling %s() for the child %d\n", TWAIT_FNAME, child); |
5235 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5302 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5236 | | | 5303 | |
5237 | validate_status_stopped(status, SIGTRAP); | | 5304 | validate_status_stopped(status, SIGTRAP); |
5238 | | | 5305 | |
5239 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 5306 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
5240 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5307 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
5241 | | | 5308 | |
5242 | printf("Before checking siginfo_t\n"); | | 5309 | printf("Before checking siginfo_t\n"); |
5243 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); | | 5310 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); |
5244 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD); | | 5311 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD); |
5245 | | | 5312 | |
5246 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); | | 5313 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); |
5247 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); | | 5314 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); |
5248 | | | 5315 | |
5249 | child2 = state.pe_other_pid; | | 5316 | child2 = state.pe_other_pid; |
5250 | printf("Reported PTRACE_FORK event with forkee %d\n", child2); | | 5317 | printf("Reported PTRACE_FORK event with forkee %d\n", child2); |
5251 | | | 5318 | |
5252 | printf("Before calling %s() for the forkee %d of the child %d\n", | | 5319 | printf("Before calling %s() for the forkee %d of the child %d\n", |
5253 | TWAIT_FNAME, child2, child); | | 5320 | TWAIT_FNAME, child2, child); |
5254 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), | | 5321 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), |
5255 | child2); | | 5322 | child2); |
5256 | | | 5323 | |
5257 | validate_status_stopped(status, SIGTRAP); | | 5324 | validate_status_stopped(status, SIGTRAP); |
5258 | | | 5325 | |
5259 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 5326 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
5260 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5327 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
5261 | | | 5328 | |
5262 | printf("Before checking siginfo_t\n"); | | 5329 | printf("Before checking siginfo_t\n"); |
5263 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); | | 5330 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); |
5264 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD); | | 5331 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_CHLD); |
5265 | | | 5332 | |
5266 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); | | 5333 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child2, &state, slen) != -1); |
5267 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); | | 5334 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_FORK); |
5268 | ATF_REQUIRE_EQ(state.pe_other_pid, child); | | 5335 | ATF_REQUIRE_EQ(state.pe_other_pid, child); |
5269 | | | 5336 | |
5270 | printf("Before resuming the forkee process where it left off and " | | 5337 | printf("Before resuming the forkee process where it left off and " |
5271 | "without signal to be sent\n"); | | 5338 | "without signal to be sent\n"); |
5272 | ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); | | 5339 | ATF_REQUIRE(ptrace(PT_CONTINUE, child2, (void *)1, 0) != -1); |
5273 | | | 5340 | |
5274 | printf("Before resuming the child process where it left off and " | | 5341 | printf("Before resuming the child process where it left off and " |
5275 | "without signal to be sent\n"); | | 5342 | "without signal to be sent\n"); |
5276 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 5343 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
5277 | | | 5344 | |
5278 | printf("Before calling %s() for the forkee - expected exited\n", | | 5345 | printf("Before calling %s() for the forkee - expected exited\n", |
5279 | TWAIT_FNAME); | | 5346 | TWAIT_FNAME); |
5280 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), | | 5347 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child2, &status, 0), |
5281 | child2); | | 5348 | child2); |
5282 | | | 5349 | |
5283 | validate_status_exited(status, exitval2); | | 5350 | validate_status_exited(status, exitval2); |
5284 | | | 5351 | |
5285 | printf("Before calling %s() for the forkee - expected no process\n", | | 5352 | printf("Before calling %s() for the forkee - expected no process\n", |
5286 | TWAIT_FNAME); | | 5353 | TWAIT_FNAME); |
5287 | TWAIT_REQUIRE_FAILURE(ECHILD, | | 5354 | TWAIT_REQUIRE_FAILURE(ECHILD, |
5288 | wpid = TWAIT_GENERIC(child2, &status, 0)); | | 5355 | wpid = TWAIT_GENERIC(child2, &status, 0)); |
5289 | | | 5356 | |
5290 | printf("Before calling %s() for the child - expected stopped " | | 5357 | printf("Before calling %s() for the child - expected stopped " |
5291 | "SIGCHLD\n", TWAIT_FNAME); | | 5358 | "SIGCHLD\n", TWAIT_FNAME); |
5292 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5359 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5293 | | | 5360 | |
5294 | validate_status_stopped(status, SIGCHLD); | | 5361 | validate_status_stopped(status, SIGCHLD); |
5295 | | | 5362 | |
5296 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 5363 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
5297 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5364 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
5298 | | | 5365 | |
5299 | printf("Before checking siginfo_t\n"); | | 5366 | printf("Before checking siginfo_t\n"); |
5300 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD); | | 5367 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGCHLD); |
5301 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED); | | 5368 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, CLD_EXITED); |
5302 | | | 5369 | |
5303 | printf("Before resuming the child process where it left off and " | | 5370 | printf("Before resuming the child process where it left off and " |
5304 | "without signal to be sent\n"); | | 5371 | "without signal to be sent\n"); |
5305 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 5372 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
5306 | | | 5373 | |
5307 | printf("Before calling %s() for the child - expected exited\n", | | 5374 | printf("Before calling %s() for the child - expected exited\n", |
5308 | TWAIT_FNAME); | | 5375 | TWAIT_FNAME); |
5309 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5376 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5310 | | | 5377 | |
5311 | validate_status_exited(status, exitval); | | 5378 | validate_status_exited(status, exitval); |
5312 | | | 5379 | |
5313 | printf("Before calling %s() for the child - expected no process\n", | | 5380 | printf("Before calling %s() for the child - expected no process\n", |
5314 | TWAIT_FNAME); | | 5381 | TWAIT_FNAME); |
5315 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 5382 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
5316 | } | | 5383 | } |
5317 | #endif | | 5384 | #endif |
5318 | | | 5385 | |
5319 | #if defined(PT_STEP) | | 5386 | #if defined(PT_STEP) |
5320 | ATF_TC(siginfo6); | | 5387 | ATF_TC(siginfo6); |
5321 | ATF_TC_HEAD(siginfo6, tc) | | 5388 | ATF_TC_HEAD(siginfo6, tc) |
5322 | { | | 5389 | { |
5323 | atf_tc_set_md_var(tc, "descr", | | 5390 | atf_tc_set_md_var(tc, "descr", |
5324 | "Verify single PT_STEP call with signal information check"); | | 5391 | "Verify single PT_STEP call with signal information check"); |
5325 | } | | 5392 | } |
5326 | | | 5393 | |
5327 | ATF_TC_BODY(siginfo6, tc) | | 5394 | ATF_TC_BODY(siginfo6, tc) |
5328 | { | | 5395 | { |
5329 | const int exitval = 5; | | 5396 | const int exitval = 5; |
5330 | const int sigval = SIGSTOP; | | 5397 | const int sigval = SIGSTOP; |
5331 | pid_t child, wpid; | | 5398 | pid_t child, wpid; |
5332 | #if defined(TWAIT_HAVE_STATUS) | | 5399 | #if defined(TWAIT_HAVE_STATUS) |
5333 | int status; | | 5400 | int status; |
5334 | #endif | | 5401 | #endif |
5335 | int happy; | | 5402 | int happy; |
5336 | struct ptrace_siginfo info; | | 5403 | struct ptrace_siginfo info; |
5337 | | | 5404 | |
5338 | memset(&info, 0, sizeof(info)); | | 5405 | memset(&info, 0, sizeof(info)); |
5339 | | | 5406 | |
5340 | printf("Before forking process PID=%d\n", getpid()); | | 5407 | printf("Before forking process PID=%d\n", getpid()); |
5341 | ATF_REQUIRE((child = fork()) != -1); | | 5408 | ATF_REQUIRE((child = fork()) != -1); |
5342 | if (child == 0) { | | 5409 | if (child == 0) { |
5343 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 5410 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
5344 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 5411 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
5345 | | | 5412 | |
5346 | happy = check_happy(100); | | 5413 | happy = check_happy(100); |
5347 | | | 5414 | |
5348 | printf("Before raising %s from child\n", strsignal(sigval)); | | 5415 | printf("Before raising %s from child\n", strsignal(sigval)); |
5349 | FORKEE_ASSERT(raise(sigval) == 0); | | 5416 | FORKEE_ASSERT(raise(sigval) == 0); |
5350 | | | 5417 | |
5351 | FORKEE_ASSERT_EQ(happy, check_happy(100)); | | 5418 | FORKEE_ASSERT_EQ(happy, check_happy(100)); |
5352 | | | 5419 | |
5353 | printf("Before exiting of the child process\n"); | | 5420 | printf("Before exiting of the child process\n"); |
5354 | _exit(exitval); | | 5421 | _exit(exitval); |
5355 | } | | 5422 | } |
5356 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 5423 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
5357 | | | 5424 | |
5358 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5425 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5359 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5426 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5360 | | | 5427 | |
5361 | validate_status_stopped(status, sigval); | | 5428 | validate_status_stopped(status, sigval); |
5362 | | | 5429 | |
5363 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 5430 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
5364 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5431 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
5365 | | | 5432 | |
5366 | printf("Before checking siginfo_t\n"); | | 5433 | printf("Before checking siginfo_t\n"); |
5367 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); | | 5434 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, sigval); |
5368 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); | | 5435 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, SI_LWP); |
5369 | | | 5436 | |
5370 | printf("Before resuming the child process where it left off and " | | 5437 | printf("Before resuming the child process where it left off and " |
5371 | "without signal to be sent (use PT_STEP)\n"); | | 5438 | "without signal to be sent (use PT_STEP)\n"); |
5372 | ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); | | 5439 | ATF_REQUIRE(ptrace(PT_STEP, child, (void *)1, 0) != -1); |
5373 | | | 5440 | |
5374 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5441 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5375 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5442 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5376 | | | 5443 | |
5377 | validate_status_stopped(status, SIGTRAP); | | 5444 | validate_status_stopped(status, SIGTRAP); |
5378 | | | 5445 | |
5379 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); | | 5446 | printf("Before calling ptrace(2) with PT_GET_SIGINFO for child\n"); |
5380 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); | | 5447 | ATF_REQUIRE(ptrace(PT_GET_SIGINFO, child, &info, sizeof(info)) != -1); |
5381 | | | 5448 | |
5382 | printf("Before checking siginfo_t\n"); | | 5449 | printf("Before checking siginfo_t\n"); |
5383 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); | | 5450 | ATF_REQUIRE_EQ(info.psi_siginfo.si_signo, SIGTRAP); |
5384 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); | | 5451 | ATF_REQUIRE_EQ(info.psi_siginfo.si_code, TRAP_TRACE); |
5385 | | | 5452 | |
5386 | printf("Before resuming the child process where it left off and " | | 5453 | printf("Before resuming the child process where it left off and " |
5387 | "without signal to be sent\n"); | | 5454 | "without signal to be sent\n"); |
5388 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 5455 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
5389 | | | 5456 | |
5390 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5457 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5391 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5458 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5392 | | | 5459 | |
5393 | validate_status_exited(status, exitval); | | 5460 | validate_status_exited(status, exitval); |
5394 | | | 5461 | |
5395 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5462 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5396 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 5463 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
5397 | } | | 5464 | } |
5398 | #endif | | 5465 | #endif |
5399 | | | 5466 | |
5400 | volatile lwpid_t the_lwp_id = 0; | | 5467 | volatile lwpid_t the_lwp_id = 0; |
5401 | | | 5468 | |
5402 | static void | | 5469 | static void |
5403 | lwp_main_func(void *arg) | | 5470 | lwp_main_func(void *arg) |
5404 | { | | 5471 | { |
5405 | the_lwp_id = _lwp_self(); | | 5472 | the_lwp_id = _lwp_self(); |
5406 | _lwp_exit(); | | 5473 | _lwp_exit(); |
5407 | } | | 5474 | } |
5408 | | | 5475 | |
5409 | ATF_TC(lwp_create1); | | 5476 | ATF_TC(lwp_create1); |
5410 | ATF_TC_HEAD(lwp_create1, tc) | | 5477 | ATF_TC_HEAD(lwp_create1, tc) |
5411 | { | | 5478 | { |
5412 | atf_tc_set_md_var(tc, "descr", | | 5479 | atf_tc_set_md_var(tc, "descr", |
5413 | "Verify that 1 LWP creation is intercepted by ptrace(2) with " | | 5480 | "Verify that 1 LWP creation is intercepted by ptrace(2) with " |
5414 | "EVENT_MASK set to PTRACE_LWP_CREATE"); | | 5481 | "EVENT_MASK set to PTRACE_LWP_CREATE"); |
5415 | } | | 5482 | } |
5416 | | | 5483 | |
5417 | ATF_TC_BODY(lwp_create1, tc) | | 5484 | ATF_TC_BODY(lwp_create1, tc) |
5418 | { | | 5485 | { |
5419 | const int exitval = 5; | | 5486 | const int exitval = 5; |
5420 | const int sigval = SIGSTOP; | | 5487 | const int sigval = SIGSTOP; |
5421 | pid_t child, wpid; | | 5488 | pid_t child, wpid; |
5422 | #if defined(TWAIT_HAVE_STATUS) | | 5489 | #if defined(TWAIT_HAVE_STATUS) |
5423 | int status; | | 5490 | int status; |
5424 | #endif | | 5491 | #endif |
5425 | ptrace_state_t state; | | 5492 | ptrace_state_t state; |
5426 | const int slen = sizeof(state); | | 5493 | const int slen = sizeof(state); |
5427 | ptrace_event_t event; | | 5494 | ptrace_event_t event; |
5428 | const int elen = sizeof(event); | | 5495 | const int elen = sizeof(event); |
5429 | ucontext_t uc; | | 5496 | ucontext_t uc; |
5430 | lwpid_t lid; | | 5497 | lwpid_t lid; |
5431 | static const size_t ssize = 16*1024; | | 5498 | static const size_t ssize = 16*1024; |
5432 | void *stack; | | 5499 | void *stack; |
5433 | | | 5500 | |
5434 | printf("Before forking process PID=%d\n", getpid()); | | 5501 | printf("Before forking process PID=%d\n", getpid()); |
5435 | ATF_REQUIRE((child = fork()) != -1); | | 5502 | ATF_REQUIRE((child = fork()) != -1); |
5436 | if (child == 0) { | | 5503 | if (child == 0) { |
5437 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 5504 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
5438 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 5505 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
5439 | | | 5506 | |
5440 | printf("Before raising %s from child\n", strsignal(sigval)); | | 5507 | printf("Before raising %s from child\n", strsignal(sigval)); |
5441 | FORKEE_ASSERT(raise(sigval) == 0); | | 5508 | FORKEE_ASSERT(raise(sigval) == 0); |
5442 | | | 5509 | |
5443 | printf("Before allocating memory for stack in child\n"); | | 5510 | printf("Before allocating memory for stack in child\n"); |
5444 | FORKEE_ASSERT((stack = malloc(ssize)) != NULL); | | 5511 | FORKEE_ASSERT((stack = malloc(ssize)) != NULL); |
5445 | | | 5512 | |
5446 | printf("Before making context for new lwp in child\n"); | | 5513 | printf("Before making context for new lwp in child\n"); |
5447 | _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); | | 5514 | _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); |
5448 | | | 5515 | |
5449 | printf("Before creating new in child\n"); | | 5516 | printf("Before creating new in child\n"); |
5450 | FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); | | 5517 | FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); |
5451 | | | 5518 | |
5452 | printf("Before waiting for lwp %d to exit\n", lid); | | 5519 | printf("Before waiting for lwp %d to exit\n", lid); |
5453 | FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); | | 5520 | FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); |
5454 | | | 5521 | |
5455 | printf("Before verifying that reported %d and running lid %d " | | 5522 | printf("Before verifying that reported %d and running lid %d " |
5456 | "are the same\n", lid, the_lwp_id); | | 5523 | "are the same\n", lid, the_lwp_id); |
5457 | FORKEE_ASSERT_EQ(lid, the_lwp_id); | | 5524 | FORKEE_ASSERT_EQ(lid, the_lwp_id); |
5458 | | | 5525 | |
5459 | printf("Before exiting of the child process\n"); | | 5526 | printf("Before exiting of the child process\n"); |
5460 | _exit(exitval); | | 5527 | _exit(exitval); |
5461 | } | | 5528 | } |
5462 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 5529 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
5463 | | | 5530 | |
5464 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5531 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5465 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5532 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5466 | | | 5533 | |
5467 | validate_status_stopped(status, sigval); | | 5534 | validate_status_stopped(status, sigval); |
5468 | | | 5535 | |
5469 | printf("Set empty EVENT_MASK for the child %d\n", child); | | 5536 | printf("Set empty EVENT_MASK for the child %d\n", child); |
5470 | event.pe_set_event = PTRACE_LWP_CREATE; | | 5537 | event.pe_set_event = PTRACE_LWP_CREATE; |
5471 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); | | 5538 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); |
5472 | | | 5539 | |
5473 | printf("Before resuming the child process where it left off and " | | 5540 | printf("Before resuming the child process where it left off and " |
5474 | "without signal to be sent\n"); | | 5541 | "without signal to be sent\n"); |
5475 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 5542 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
5476 | | | 5543 | |
5477 | printf("Before calling %s() for the child - expected stopped " | | 5544 | printf("Before calling %s() for the child - expected stopped " |
5478 | "SIGTRAP\n", TWAIT_FNAME); | | 5545 | "SIGTRAP\n", TWAIT_FNAME); |
5479 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5546 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5480 | | | 5547 | |
5481 | validate_status_stopped(status, SIGTRAP); | | 5548 | validate_status_stopped(status, SIGTRAP); |
5482 | | | 5549 | |
5483 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); | | 5550 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); |
5484 | | | 5551 | |
5485 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); | | 5552 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_CREATE); |
5486 | | | 5553 | |
5487 | lid = state.pe_lwp; | | 5554 | lid = state.pe_lwp; |
5488 | printf("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); | | 5555 | printf("Reported PTRACE_LWP_CREATE event with lid %d\n", lid); |
5489 | | | 5556 | |
5490 | printf("Before resuming the child process where it left off and " | | 5557 | printf("Before resuming the child process where it left off and " |
5491 | "without signal to be sent\n"); | | 5558 | "without signal to be sent\n"); |
5492 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 5559 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
5493 | | | 5560 | |
5494 | printf("Before calling %s() for the child - expected exited\n", | | 5561 | printf("Before calling %s() for the child - expected exited\n", |
5495 | TWAIT_FNAME); | | 5562 | TWAIT_FNAME); |
5496 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5563 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5497 | | | 5564 | |
5498 | validate_status_exited(status, exitval); | | 5565 | validate_status_exited(status, exitval); |
5499 | | | 5566 | |
5500 | printf("Before calling %s() for the child - expected no process\n", | | 5567 | printf("Before calling %s() for the child - expected no process\n", |
5501 | TWAIT_FNAME); | | 5568 | TWAIT_FNAME); |
5502 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 5569 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
5503 | } | | 5570 | } |
5504 | | | 5571 | |
5505 | ATF_TC(lwp_exit1); | | 5572 | ATF_TC(lwp_exit1); |
5506 | ATF_TC_HEAD(lwp_exit1, tc) | | 5573 | ATF_TC_HEAD(lwp_exit1, tc) |
5507 | { | | 5574 | { |
5508 | atf_tc_set_md_var(tc, "descr", | | 5575 | atf_tc_set_md_var(tc, "descr", |
5509 | "Verify that 1 LWP creation is intercepted by ptrace(2) with " | | 5576 | "Verify that 1 LWP creation is intercepted by ptrace(2) with " |
5510 | "EVENT_MASK set to PTRACE_LWP_EXIT"); | | 5577 | "EVENT_MASK set to PTRACE_LWP_EXIT"); |
5511 | } | | 5578 | } |
5512 | | | 5579 | |
5513 | ATF_TC_BODY(lwp_exit1, tc) | | 5580 | ATF_TC_BODY(lwp_exit1, tc) |
5514 | { | | 5581 | { |
5515 | const int exitval = 5; | | 5582 | const int exitval = 5; |
5516 | const int sigval = SIGSTOP; | | 5583 | const int sigval = SIGSTOP; |
5517 | pid_t child, wpid; | | 5584 | pid_t child, wpid; |
5518 | #if defined(TWAIT_HAVE_STATUS) | | 5585 | #if defined(TWAIT_HAVE_STATUS) |
5519 | int status; | | 5586 | int status; |
5520 | #endif | | 5587 | #endif |
5521 | ptrace_state_t state; | | 5588 | ptrace_state_t state; |
5522 | const int slen = sizeof(state); | | 5589 | const int slen = sizeof(state); |
5523 | ptrace_event_t event; | | 5590 | ptrace_event_t event; |
5524 | const int elen = sizeof(event); | | 5591 | const int elen = sizeof(event); |
5525 | ucontext_t uc; | | 5592 | ucontext_t uc; |
5526 | lwpid_t lid; | | 5593 | lwpid_t lid; |
5527 | static const size_t ssize = 16*1024; | | 5594 | static const size_t ssize = 16*1024; |
5528 | void *stack; | | 5595 | void *stack; |
5529 | | | 5596 | |
5530 | printf("Before forking process PID=%d\n", getpid()); | | 5597 | printf("Before forking process PID=%d\n", getpid()); |
5531 | ATF_REQUIRE((child = fork()) != -1); | | 5598 | ATF_REQUIRE((child = fork()) != -1); |
5532 | if (child == 0) { | | 5599 | if (child == 0) { |
5533 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); | | 5600 | printf("Before calling PT_TRACE_ME from child %d\n", getpid()); |
5534 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); | | 5601 | FORKEE_ASSERT(ptrace(PT_TRACE_ME, 0, NULL, 0) != -1); |
5535 | | | 5602 | |
5536 | printf("Before raising %s from child\n", strsignal(sigval)); | | 5603 | printf("Before raising %s from child\n", strsignal(sigval)); |
5537 | FORKEE_ASSERT(raise(sigval) == 0); | | 5604 | FORKEE_ASSERT(raise(sigval) == 0); |
5538 | | | 5605 | |
5539 | printf("Before allocating memory for stack in child\n"); | | 5606 | printf("Before allocating memory for stack in child\n"); |
5540 | FORKEE_ASSERT((stack = malloc(ssize)) != NULL); | | 5607 | FORKEE_ASSERT((stack = malloc(ssize)) != NULL); |
5541 | | | 5608 | |
5542 | printf("Before making context for new lwp in child\n"); | | 5609 | printf("Before making context for new lwp in child\n"); |
5543 | _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); | | 5610 | _lwp_makecontext(&uc, lwp_main_func, NULL, NULL, stack, ssize); |
5544 | | | 5611 | |
5545 | printf("Before creating new in child\n"); | | 5612 | printf("Before creating new in child\n"); |
5546 | FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); | | 5613 | FORKEE_ASSERT(_lwp_create(&uc, 0, &lid) == 0); |
5547 | | | 5614 | |
5548 | printf("Before waiting for lwp %d to exit\n", lid); | | 5615 | printf("Before waiting for lwp %d to exit\n", lid); |
5549 | FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); | | 5616 | FORKEE_ASSERT(_lwp_wait(lid, NULL) == 0); |
5550 | | | 5617 | |
5551 | printf("Before verifying that reported %d and running lid %d " | | 5618 | printf("Before verifying that reported %d and running lid %d " |
5552 | "are the same\n", lid, the_lwp_id); | | 5619 | "are the same\n", lid, the_lwp_id); |
5553 | FORKEE_ASSERT_EQ(lid, the_lwp_id); | | 5620 | FORKEE_ASSERT_EQ(lid, the_lwp_id); |
5554 | | | 5621 | |
5555 | printf("Before exiting of the child process\n"); | | 5622 | printf("Before exiting of the child process\n"); |
5556 | _exit(exitval); | | 5623 | _exit(exitval); |
5557 | } | | 5624 | } |
5558 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); | | 5625 | printf("Parent process PID=%d, child's PID=%d\n", getpid(), child); |
5559 | | | 5626 | |
5560 | printf("Before calling %s() for the child\n", TWAIT_FNAME); | | 5627 | printf("Before calling %s() for the child\n", TWAIT_FNAME); |
5561 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5628 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5562 | | | 5629 | |
5563 | validate_status_stopped(status, sigval); | | 5630 | validate_status_stopped(status, sigval); |
5564 | | | 5631 | |
5565 | printf("Set empty EVENT_MASK for the child %d\n", child); | | 5632 | printf("Set empty EVENT_MASK for the child %d\n", child); |
5566 | event.pe_set_event = PTRACE_LWP_EXIT; | | 5633 | event.pe_set_event = PTRACE_LWP_EXIT; |
5567 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); | | 5634 | ATF_REQUIRE(ptrace(PT_SET_EVENT_MASK, child, &event, elen) != -1); |
5568 | | | 5635 | |
5569 | printf("Before resuming the child process where it left off and " | | 5636 | printf("Before resuming the child process where it left off and " |
5570 | "without signal to be sent\n"); | | 5637 | "without signal to be sent\n"); |
5571 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 5638 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
5572 | | | 5639 | |
5573 | printf("Before calling %s() for the child - expected stopped " | | 5640 | printf("Before calling %s() for the child - expected stopped " |
5574 | "SIGTRAP\n", TWAIT_FNAME); | | 5641 | "SIGTRAP\n", TWAIT_FNAME); |
5575 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5642 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5576 | | | 5643 | |
5577 | validate_status_stopped(status, SIGTRAP); | | 5644 | validate_status_stopped(status, SIGTRAP); |
5578 | | | 5645 | |
5579 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); | | 5646 | ATF_REQUIRE(ptrace(PT_GET_PROCESS_STATE, child, &state, slen) != -1); |
5580 | | | 5647 | |
5581 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); | | 5648 | ATF_REQUIRE_EQ(state.pe_report_event, PTRACE_LWP_EXIT); |
5582 | | | 5649 | |
5583 | lid = state.pe_lwp; | | 5650 | lid = state.pe_lwp; |
5584 | printf("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); | | 5651 | printf("Reported PTRACE_LWP_EXIT event with lid %d\n", lid); |
5585 | | | 5652 | |
5586 | printf("Before resuming the child process where it left off and " | | 5653 | printf("Before resuming the child process where it left off and " |
5587 | "without signal to be sent\n"); | | 5654 | "without signal to be sent\n"); |
5588 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); | | 5655 | ATF_REQUIRE(ptrace(PT_CONTINUE, child, (void *)1, 0) != -1); |
5589 | | | 5656 | |
5590 | printf("Before calling %s() for the child - expected exited\n", | | 5657 | printf("Before calling %s() for the child - expected exited\n", |
5591 | TWAIT_FNAME); | | 5658 | TWAIT_FNAME); |
5592 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); | | 5659 | TWAIT_REQUIRE_SUCCESS(wpid = TWAIT_GENERIC(child, &status, 0), child); |
5593 | | | 5660 | |
5594 | validate_status_exited(status, exitval); | | 5661 | validate_status_exited(status, exitval); |
5595 | | | 5662 | |
5596 | printf("Before calling %s() for the child - expected no process\n", | | 5663 | printf("Before calling %s() for the child - expected no process\n", |
5597 | TWAIT_FNAME); | | 5664 | TWAIT_FNAME); |
5598 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); | | 5665 | TWAIT_REQUIRE_FAILURE(ECHILD, wpid = TWAIT_GENERIC(child, &status, 0)); |
5599 | } | | 5666 | } |
5600 | | | 5667 | |
5601 | ATF_TP_ADD_TCS(tp) | | 5668 | ATF_TP_ADD_TCS(tp) |
5602 | { | | 5669 | { |
5603 | setvbuf(stdout, NULL, _IONBF, 0); | | 5670 | setvbuf(stdout, NULL, _IONBF, 0); |
5604 | setvbuf(stderr, NULL, _IONBF, 0); | | 5671 | setvbuf(stderr, NULL, _IONBF, 0); |
5605 | ATF_TP_ADD_TC(tp, traceme1); | | 5672 | ATF_TP_ADD_TC(tp, traceme1); |
5606 | ATF_TP_ADD_TC(tp, traceme2); | | 5673 | ATF_TP_ADD_TC(tp, traceme2); |
5607 | ATF_TP_ADD_TC(tp, traceme3); | | 5674 | ATF_TP_ADD_TC(tp, traceme3); |
5608 | ATF_TP_ADD_TC(tp, traceme4); | | 5675 | ATF_TP_ADD_TC(tp, traceme4); |
5609 | | | 5676 | |
5610 | ATF_TP_ADD_TC_HAVE_PID(tp, attach1); | | 5677 | ATF_TP_ADD_TC_HAVE_PID(tp, attach1); |
5611 | ATF_TP_ADD_TC_HAVE_PID(tp, attach2); | | 5678 | ATF_TP_ADD_TC_HAVE_PID(tp, attach2); |
5612 | ATF_TP_ADD_TC(tp, attach3); | | 5679 | ATF_TP_ADD_TC(tp, attach3); |
5613 | ATF_TP_ADD_TC(tp, attach4); | | 5680 | ATF_TP_ADD_TC(tp, attach4); |
5614 | ATF_TP_ADD_TC_HAVE_PID(tp, attach5); | | 5681 | ATF_TP_ADD_TC_HAVE_PID(tp, attach5); |
5615 | ATF_TP_ADD_TC_HAVE_PID(tp, attach6); | | 5682 | ATF_TP_ADD_TC_HAVE_PID(tp, attach6); |
5616 | ATF_TP_ADD_TC_HAVE_PID(tp, attach7); | | 5683 | ATF_TP_ADD_TC_HAVE_PID(tp, attach7); |
5617 | | | 5684 | |
5618 | ATF_TP_ADD_TC(tp, eventmask1); | | 5685 | ATF_TP_ADD_TC(tp, eventmask1); |
5619 | ATF_TP_ADD_TC(tp, eventmask2); | | 5686 | ATF_TP_ADD_TC(tp, eventmask2); |
5620 | ATF_TP_ADD_TC(tp, eventmask3); | | 5687 | ATF_TP_ADD_TC(tp, eventmask3); |
5621 | ATF_TP_ADD_TC(tp, eventmask4); | | 5688 | ATF_TP_ADD_TC(tp, eventmask4); |
5622 | ATF_TP_ADD_TC(tp, eventmask5); | | 5689 | ATF_TP_ADD_TC(tp, eventmask5); |
5623 | ATF_TP_ADD_TC(tp, eventmask6); | | 5690 | ATF_TP_ADD_TC(tp, eventmask6); |
5624 | | | 5691 | |
5625 | ATF_TP_ADD_TC_HAVE_PID(tp, fork1); | | 5692 | ATF_TP_ADD_TC_HAVE_PID(tp, fork1); |
5626 | ATF_TP_ADD_TC(tp, fork2); | | 5693 | ATF_TP_ADD_TC(tp, fork2); |
5627 | | | 5694 | |
5628 | ATF_TP_ADD_TC_HAVE_PID(tp, vfork1); | | 5695 | ATF_TP_ADD_TC_HAVE_PID(tp, vfork1); |
5629 | ATF_TP_ADD_TC(tp, vfork2); | | 5696 | ATF_TP_ADD_TC(tp, vfork2); |
5630 | | | 5697 | |
5631 | ATF_TP_ADD_TC(tp, vforkdone1); | | 5698 | ATF_TP_ADD_TC(tp, vforkdone1); |
5632 | ATF_TP_ADD_TC(tp, vforkdone2); | | 5699 | ATF_TP_ADD_TC(tp, vforkdone2); |
5633 | | | 5700 | |
5634 | ATF_TP_ADD_TC(tp, io_read_d1); | | 5701 | ATF_TP_ADD_TC(tp, io_read_d1); |
5635 | ATF_TP_ADD_TC(tp, io_read_d2); | | 5702 | ATF_TP_ADD_TC(tp, io_read_d2); |
5636 | ATF_TP_ADD_TC(tp, io_read_d3); | | 5703 | ATF_TP_ADD_TC(tp, io_read_d3); |
5637 | ATF_TP_ADD_TC(tp, io_read_d4); | | 5704 | ATF_TP_ADD_TC(tp, io_read_d4); |
5638 | | | 5705 | |
5639 | ATF_TP_ADD_TC(tp, io_write_d1); | | 5706 | ATF_TP_ADD_TC(tp, io_write_d1); |
5640 | ATF_TP_ADD_TC(tp, io_write_d2); | | 5707 | ATF_TP_ADD_TC(tp, io_write_d2); |
5641 | ATF_TP_ADD_TC(tp, io_write_d3); | | 5708 | ATF_TP_ADD_TC(tp, io_write_d3); |
5642 | ATF_TP_ADD_TC(tp, io_write_d4); | | 5709 | ATF_TP_ADD_TC(tp, io_write_d4); |
5643 | | | 5710 | |
5644 | ATF_TP_ADD_TC(tp, read_d1); | | 5711 | ATF_TP_ADD_TC(tp, read_d1); |
5645 | ATF_TP_ADD_TC(tp, read_d2); | | 5712 | ATF_TP_ADD_TC(tp, read_d2); |
5646 | ATF_TP_ADD_TC(tp, read_d3); | | 5713 | ATF_TP_ADD_TC(tp, read_d3); |
5647 | ATF_TP_ADD_TC(tp, read_d4); | | 5714 | ATF_TP_ADD_TC(tp, read_d4); |
5648 | | | 5715 | |
5649 | ATF_TP_ADD_TC(tp, write_d1); | | 5716 | ATF_TP_ADD_TC(tp, write_d1); |
5650 | ATF_TP_ADD_TC(tp, write_d2); | | 5717 | ATF_TP_ADD_TC(tp, write_d2); |
5651 | ATF_TP_ADD_TC(tp, write_d3); | | 5718 | ATF_TP_ADD_TC(tp, write_d3); |
5652 | ATF_TP_ADD_TC(tp, write_d4); | | 5719 | ATF_TP_ADD_TC(tp, write_d4); |
5653 | | | 5720 | |
5654 | ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1); | | 5721 | ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake1); |
5655 | ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2); | | 5722 | ATF_TP_ADD_TC(tp, io_read_d_write_d_handshake2); |
5656 | | | 5723 | |
5657 | ATF_TP_ADD_TC(tp, read_d_write_d_handshake1); | | 5724 | ATF_TP_ADD_TC(tp, read_d_write_d_handshake1); |
5658 | ATF_TP_ADD_TC(tp, read_d_write_d_handshake2); | | 5725 | ATF_TP_ADD_TC(tp, read_d_write_d_handshake2); |
5659 | | | 5726 | |
5660 | ATF_TP_ADD_TC(tp, io_read_i1); | | 5727 | ATF_TP_ADD_TC(tp, io_read_i1); |
5661 | ATF_TP_ADD_TC(tp, io_read_i2); | | 5728 | ATF_TP_ADD_TC(tp, io_read_i2); |
5662 | ATF_TP_ADD_TC(tp, io_read_i3); | | 5729 | ATF_TP_ADD_TC(tp, io_read_i3); |
5663 | ATF_TP_ADD_TC(tp, io_read_i4); | | 5730 | ATF_TP_ADD_TC(tp, io_read_i4); |
5664 | | | 5731 | |
5665 | ATF_TP_ADD_TC(tp, read_i1); | | 5732 | ATF_TP_ADD_TC(tp, read_i1); |
5666 | ATF_TP_ADD_TC(tp, read_i2); | | 5733 | ATF_TP_ADD_TC(tp, read_i2); |
5667 | ATF_TP_ADD_TC(tp, read_i3); | | 5734 | ATF_TP_ADD_TC(tp, read_i3); |
5668 | ATF_TP_ADD_TC(tp, read_i4); | | 5735 | ATF_TP_ADD_TC(tp, read_i4); |
5669 | | | 5736 | |
| | | 5737 | ATF_TP_ADD_TC(tp, io_read_auxv1); |
| | | 5738 | |
5670 | ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1); | | 5739 | ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs1); |
5671 | ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2); | | 5740 | ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs2); |
5672 | ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3); | | 5741 | ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs3); |
5673 | ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4); | | 5742 | ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs4); |
5674 | ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5); | | 5743 | ATF_TP_ADD_TC_HAVE_GPREGS(tp, regs5); |
5675 | | | 5744 | |
5676 | ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1); | | 5745 | ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs1); |
5677 | ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2); | | 5746 | ATF_TP_ADD_TC_HAVE_FPREGS(tp, fpregs2); |
5678 | | | 5747 | |
5679 | ATF_TP_ADD_TC_PT_STEP(tp, step1); | | 5748 | ATF_TP_ADD_TC_PT_STEP(tp, step1); |
5680 | ATF_TP_ADD_TC_PT_STEP(tp, step2); | | 5749 | ATF_TP_ADD_TC_PT_STEP(tp, step2); |
5681 | ATF_TP_ADD_TC_PT_STEP(tp, step3); | | 5750 | ATF_TP_ADD_TC_PT_STEP(tp, step3); |
5682 | ATF_TP_ADD_TC_PT_STEP(tp, step4); | | 5751 | ATF_TP_ADD_TC_PT_STEP(tp, step4); |
5683 | | | 5752 | |
5684 | ATF_TP_ADD_TC(tp, kill1); | | 5753 | ATF_TP_ADD_TC(tp, kill1); |
5685 | ATF_TP_ADD_TC(tp, kill2); | | 5754 | ATF_TP_ADD_TC(tp, kill2); |
5686 | | | 5755 | |
5687 | ATF_TP_ADD_TC(tp, lwpinfo1); | | 5756 | ATF_TP_ADD_TC(tp, lwpinfo1); |
5688 | ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2); | | 5757 | ATF_TP_ADD_TC_HAVE_PID(tp, lwpinfo2); |
5689 | | | 5758 | |
5690 | ATF_TP_ADD_TC(tp, siginfo1); | | 5759 | ATF_TP_ADD_TC(tp, siginfo1); |
5691 | ATF_TP_ADD_TC(tp, siginfo2); | | 5760 | ATF_TP_ADD_TC(tp, siginfo2); |
5692 | ATF_TP_ADD_TC(tp, siginfo3); | | 5761 | ATF_TP_ADD_TC(tp, siginfo3); |
5693 | ATF_TP_ADD_TC(tp, siginfo4); | | 5762 | ATF_TP_ADD_TC(tp, siginfo4); |
5694 | ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5); | | 5763 | ATF_TP_ADD_TC_HAVE_PID(tp, siginfo5); |
5695 | ATF_TP_ADD_TC_PT_STEP(tp, siginfo6); | | 5764 | ATF_TP_ADD_TC_PT_STEP(tp, siginfo6); |
5696 | | | 5765 | |
5697 | ATF_TP_ADD_TC(tp, lwp_create1); | | 5766 | ATF_TP_ADD_TC(tp, lwp_create1); |
5698 | | | 5767 | |
5699 | ATF_TP_ADD_TC(tp, lwp_exit1); | | 5768 | ATF_TP_ADD_TC(tp, lwp_exit1); |
5700 | | | 5769 | |
5701 | return atf_no_error(); | | 5770 | return atf_no_error(); |
5702 | } | | 5771 | } |