unstack, sort: cleanup and improvement
[minix.git] / test / test42.c
blobec1f1a8068b8c5fb27e0d6cb32b8539694ff3912
1 /* Tests for MINIX3 ptrace(2) - by D.C. van Moolenbroek */
2 #define _POSIX_SOURCE 1
3 #include <setjmp.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <signal.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <sys/wait.h>
11 #include <sys/select.h>
12 #include <sys/ptrace.h>
14 #define ITERATIONS 3
15 #define MAX_ERROR 4
16 #include "common.c"
18 #define _WIFSTOPPED(s) (WIFSTOPPED(s) && !WIFSIGNALED(s) && !WIFEXITED(s))
19 #define _WIFSIGNALED(s) (!WIFSTOPPED(s) && WIFSIGNALED(s) && !WIFEXITED(s))
20 #define _WIFEXITED(s) (!WIFSTOPPED(s) && !WIFSIGNALED(s) && WIFEXITED(s))
22 #define timed_test(func) (timed_test_func(#func, func));
24 int main(int argc, char **argv);
25 void test(int m, int a);
26 void timed_test_func(const char *s, void (* func)(void));
27 void timed_test_timeout(int signum);
28 pid_t traced_fork(void (*c) (void));
29 pid_t traced_pfork(void (*c) (void));
30 void WRITE(int value);
31 int READ(void);
32 void traced_wait(void);
33 void detach_running(pid_t pid);
34 void dummy_handler(int sig);
35 void exit_handler(int sig);
36 void count_handler(int sig);
37 void catch_handler(int sig);
38 void test_wait_child(void);
39 void test_wait(void);
40 void test_exec_child(void);
41 void test_exec(void);
42 void test_step_child(void);
43 void test_step(void);
44 void test_sig_child(void);
45 void test_sig(void);
46 void test_exit_child(void);
47 void test_exit(void);
48 void test_term_child(void);
49 void test_term(void);
50 void test_catch_child(void);
51 void test_catch(void);
52 void test_kill_child(void);
53 void test_kill(void);
54 void test_attach_child(void);
55 void test_attach(void);
56 void test_detach_child(void);
57 void test_detach(void);
58 void test_death_child(void);
59 void test_death(void);
60 void test_zdeath_child(void);
61 void test_zdeath(void);
62 void test_syscall_child(void);
63 void test_syscall(void);
64 void test_tracefork_child(void);
65 void test_tracefork(void);
66 void sigexec(int setflag, int opt, int *traps, int *stop);
67 void test_trapexec(void);
68 void test_altexec(void);
69 void test_noexec(void);
70 void test_defexec(void);
71 void test_reattach_child(void);
72 void test_reattach(void);
73 void my_e(int n);
75 static char *executable;
76 static int child = 0, attach;
77 static pid_t ppid;
78 static int pfd[4];
79 static int sigs, caught;
81 int main(argc, argv)
82 int argc;
83 char **argv;
85 int i, m = 0xFFFFFF, n = 0xF;
86 char cp_cmd[NAME_MAX + 10];
88 if (strcmp(argv[0], "DO CHECK") == 0) {
89 exit(42);
92 start(42);
94 executable = argv[0];
96 snprintf(cp_cmd, sizeof(cp_cmd), "cp ../%s .", executable);
97 system(cp_cmd);
99 if (argc >= 2) m = atoi(argv[1]);
100 if (argc >= 3) n = atoi(argv[2]);
102 for (i = 0; i < ITERATIONS; i++) {
103 if (n & 001) test(m, 0);
104 if (n & 002) test(m, 1);
105 if (n & 004) test(m, 2);
106 if (n & 010) test(m, 3);
109 quit();
110 return(-1); /* impossible */
113 void test(m, a)
114 int m;
115 int a;
117 attach = a;
119 if (m & 00000001) timed_test(test_wait);
120 if (m & 00000002) timed_test(test_exec);
121 if (m & 00000004) timed_test(test_step);
122 if (m & 00000010) timed_test(test_sig);
123 if (m & 00000020) timed_test(test_exit);
124 if (m & 00000040) timed_test(test_term);
125 if (m & 00000100) timed_test(test_catch);
126 if (m & 00000200) timed_test(test_kill);
127 if (m & 00000400) timed_test(test_attach);
128 if (m & 00001000) timed_test(test_detach);
129 if (m & 00002000) timed_test(test_death);
130 if (m & 00004000) timed_test(test_zdeath);
131 if (m & 00010000) timed_test(test_syscall);
132 if (m & 00020000) timed_test(test_tracefork);
133 if (m & 00040000) timed_test(test_trapexec);
134 if (m & 00100000) timed_test(test_altexec);
135 if (m & 00200000) timed_test(test_noexec);
136 if (m & 00400000) timed_test(test_defexec);
137 if (m & 01000000) test_reattach(); /* not timed, catches SIGALRM */
140 static jmp_buf timed_test_context;
142 void timed_test_timeout(int signum)
144 longjmp(timed_test_context, -1);
145 my_e(700);
146 quit();
147 exit(-1);
150 void timed_test_func(const char *s, void (* func)(void))
152 if (setjmp(timed_test_context) == 0)
154 /* the function gets 60 seconds to complete */
155 if (signal(SIGALRM, timed_test_timeout) == SIG_ERR) { my_e(701); return; }
156 alarm(60);
157 func();
158 alarm(0);
160 else
162 /* report timeout as error */
163 printf("timeout in %s\n", s);
164 my_e(702);
168 pid_t traced_fork(c)
169 void(*c) (void);
171 pid_t pid;
172 int r, status;
174 if (pipe(pfd) != 0) my_e(200);
175 if (pipe(&pfd[2]) != 0) my_e(201);
177 switch (attach) {
178 case 0: /* let child volunteer to be traced */
179 pid = fork();
181 if (pid < 0) my_e(202);
183 if (pid == 0) {
184 child = 1;
186 if (ptrace(T_OK, 0, 0, 0) != 0) my_e(203);
188 WRITE(0);
190 c();
192 my_e(204);
195 if (READ() != 0) my_e(205);
197 break;
199 case 1: /* attach to child process */
200 pid = fork();
202 if (pid < 0) my_e(206);
204 if (pid == 0) {
205 child = 1;
207 if (READ() != 0) my_e(207);
209 c();
211 my_e(208);
214 if (ptrace(T_ATTACH, pid, 0, 0) != 0) my_e(209);
216 if (waitpid(pid, &status, 0) != pid) my_e(210);
217 if (!_WIFSTOPPED(status)) my_e(211);
218 if (WSTOPSIG(status) != SIGSTOP) my_e(212);
220 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(213);
222 WRITE(0);
224 break;
226 case 2: /* attach to non-child process */
227 ppid = fork();
229 if (ppid < 0) my_e(214);
231 if (ppid == 0) {
232 pid = fork();
234 if (pid < 0) exit(215);
236 if (pid == 0) {
237 child = 1;
239 if (READ() != 0) my_e(216);
241 c();
243 my_e(217);
246 child = 1;
248 WRITE(pid);
250 if (waitpid(pid, &status, 0) != pid) my_e(218);
251 if (_WIFSTOPPED(status)) my_e(219);
252 if (_WIFEXITED(status) && (r = WEXITSTATUS(status)) != 42) my_e(r);
254 exit(0);
257 pid = READ();
259 if (ptrace(T_ATTACH, pid, 0, 0) != 0) my_e(220);
261 if (waitpid(pid, &status, 0) != pid) my_e(221);
262 if (!_WIFSTOPPED(status)) my_e(222);
263 if (WSTOPSIG(status) != SIGSTOP) my_e(223);
265 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(224);
267 WRITE(0);
269 break;
271 case 3: /* attach by forking from child */
272 ppid = fork();
274 if (ppid < 0) my_e(225);
276 if (ppid == 0) {
277 child = 1;
279 if (ptrace(T_OK, 0, 0, 0) != 0) my_e(226);
281 WRITE(0);
283 if (READ() != 0) my_e(227);
285 pid = fork();
287 if (pid < 0) my_e(228);
289 if (pid == 0) {
290 c();
292 my_e(229);
295 WRITE(pid);
297 if (waitpid(pid, &status, 0) != pid) my_e(230);
298 if (_WIFSTOPPED(status)) my_e(231);
299 if (_WIFEXITED(status) && (r = WEXITSTATUS(status)) != 42) my_e(r);
301 exit(0);
304 if (READ() != 0) my_e(232);
306 if (kill(ppid, SIGSTOP) != 0) my_e(233);
308 if (waitpid(ppid, &status, 0) != ppid) my_e(234);
309 if (!_WIFSTOPPED(status)) my_e(235);
310 if (WSTOPSIG(status) != SIGSTOP) my_e(236);
312 if (ptrace(T_SETOPT, ppid, 0, TO_TRACEFORK) != 0) my_e(237);
314 if (ptrace(T_RESUME, ppid, 0, 0) != 0) my_e(238);
316 WRITE(0);
318 pid = READ();
320 if (waitpid(pid, &status, 0) != pid) my_e(239);
321 if (!_WIFSTOPPED(status)) my_e(240);
322 if (WSTOPSIG(status) != SIGSTOP) my_e(241);
324 if (ptrace(T_SETOPT, pid, 0, 0) != 0) my_e(242);
325 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(243);
327 detach_running(ppid);
329 break;
332 return pid;
335 pid_t traced_pfork(c)
336 void(*c) (void);
338 pid_t pid;
340 if (pipe(pfd) != 0) my_e(300);
341 if (pipe(&pfd[2]) != 0) my_e(301);
343 pid = fork();
345 if (pid < 0) my_e(302);
347 if (pid == 0) {
348 child = 1;
350 c();
352 my_e(303);
355 return pid;
358 void WRITE(value)
359 int value;
361 if (write(pfd[child*2+1], &value, sizeof(value)) != sizeof(value)) my_e(400);
364 int READ()
366 int value;
368 if (read(pfd[2-child*2], &value, sizeof(value)) != sizeof(value)) my_e(401);
370 return value;
373 void traced_wait()
375 int r, status;
377 if (attach == 2) {
378 if (waitpid(ppid, &status, 0) != ppid) my_e(500);
379 if (!_WIFEXITED(status)) my_e(501);
380 if ((r = WEXITSTATUS(status)) != 0) my_e(r);
382 else {
383 /* Quick hack to clean up detached children */
384 waitpid(-1, NULL, WNOHANG);
387 close(pfd[0]);
388 close(pfd[1]);
389 close(pfd[2]);
390 close(pfd[3]);
393 void detach_running(pid)
394 pid_t pid;
396 /* Detach from a process that is not already stopped. This is the way to do it.
397 * We have to stop the child in order to detach from it, but as the child may
398 * have other signals pending for the tracer, we cannot assume we get our own
399 * signal back immediately. However, because we know that the kill is instant
400 * and resuming with pending signals will only stop the process immediately
401 * again, we can use T_RESUME for all the signals until we get our own signal,
402 * and then detach. A complicating factor is that anywhere during this
403 * procedure, the child may die (e.g. by getting a SIGKILL). In our tests, this
404 * will not happen.
406 int status;
408 if (kill(pid, SIGSTOP) != 0) my_e(600);
410 if (waitpid(pid, &status, 0) != pid) my_e(601);
412 while (_WIFSTOPPED(status)) {
413 if (WSTOPSIG(status) == SIGSTOP) {
414 if (ptrace(T_DETACH, pid, 0, 0) != 0) my_e(602);
416 return;
419 if (ptrace(T_RESUME, pid, 0, WSTOPSIG(status)) != 0) my_e(603);
421 if (waitpid(pid, &status, 0) != pid) my_e(604);
424 /* Apparently the process exited. */
425 if (!_WIFEXITED(status) && !_WIFSIGNALED(status)) my_e(605);
427 /* In our tests, that should not happen. */
428 my_e(606);
431 void dummy_handler(sig)
432 int sig;
436 void exit_handler(sig)
437 int sig;
439 exit(42);
442 void count_handler(sig)
443 int sig;
445 sigs++;
448 void catch_handler(sig)
449 int sig;
451 sigset_t set;
452 int bit;
454 switch (sig) {
455 case SIGUSR1: bit = 1; break;
456 case SIGUSR2: bit = 2; break;
457 case SIGTERM: bit = 4; break;
458 default: my_e(100);
461 sigfillset(&set);
462 sigprocmask(SIG_SETMASK, &set, NULL);
464 if (caught & bit) my_e(101);
465 caught |= bit;
468 void test_wait_child()
470 exit(42);
473 void test_wait()
475 pid_t pid;
476 int status;
478 subtest = 1;
480 pid = traced_fork(test_wait_child);
482 if (waitpid(pid, &status, 0) != pid) my_e(1);
483 if (!_WIFEXITED(status)) my_e(2);
484 if (WEXITSTATUS(status) != 42) my_e(3);
486 traced_wait();
489 void test_exec_child()
491 if (READ() != 0) my_e(100);
493 execl(executable, "DO CHECK", NULL);
495 my_e(101);
498 void test_exec()
500 pid_t pid;
501 int r, status;
503 /* This test covers the T_OK case. */
504 if (attach != 0) return;
506 subtest = 2;
508 pid = traced_fork(test_exec_child);
510 WRITE(0);
512 /* An exec() should result in a trap signal. */
513 if (waitpid(pid, &status, 0) != pid) my_e(1);
514 if (!_WIFSTOPPED(status)) my_e(2);
515 if (WSTOPSIG(status) != SIGTRAP) my_e(3);
517 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(4);
519 if (waitpid(pid, &status, 0) != pid) my_e(5);
520 if (!_WIFEXITED(status)) my_e(6);
521 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
523 traced_wait();
526 void test_step_child()
528 sigset_t set;
530 signal(SIGUSR1, SIG_IGN);
532 WRITE(0);
534 if (READ() != 0) my_e(100);
536 /* It must not be possible for the child to stop the single-step signal. */
537 signal(SIGTRAP, SIG_IGN);
538 sigfillset(&set);
539 sigprocmask(SIG_SETMASK, &set, NULL);
541 exit(42);
544 void test_step()
546 pid_t pid;
547 int r, status, count;
549 subtest = 3;
551 pid = traced_fork(test_step_child);
553 if (READ() != 0) my_e(1);
555 /* While the child is running, neither waitpid() nor ptrace() should work. */
556 if (waitpid(pid, &status, WNOHANG) != 0) my_e(2);
557 if (ptrace(T_RESUME, pid, 0, 0) != -1) my_e(3);
558 if (errno != EBUSY) my_e(4);
560 if (kill(pid, SIGUSR1) != 0) my_e(5);
562 WRITE(0);
564 /* A kill() signal (other than SIGKILL) should be delivered to the tracer. */
565 if (waitpid(pid, &status, 0) != pid) my_e(6);
566 if (!_WIFSTOPPED(status)) my_e(7);
567 if (WSTOPSIG(status) != SIGUSR1) my_e(8);
569 /* ptrace(T_STEP) should result in instruction-wise progress. */
570 for (count = 0; ; count++) {
571 if (ptrace(T_STEP, pid, 0, 0) != 0) my_e(9);
573 if (waitpid(pid, &status, 0) != pid) my_e(10);
574 if (_WIFEXITED(status)) break;
575 if (!_WIFSTOPPED(status)) my_e(11);
576 if (WSTOPSIG(status) != SIGTRAP) my_e(12);
579 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
581 if (count < 10) my_e(13); /* in practice: hundreds */
583 traced_wait();
586 void test_sig_child()
588 signal(SIGUSR1, exit_handler);
590 if (READ() != 0) my_e(100);
592 pause();
594 my_e(101);
597 void test_sig()
599 pid_t pid;
600 int r, sig, status;
602 subtest = 4;
604 pid = traced_fork(test_sig_child);
606 WRITE(0);
608 /* allow the child to enter the pause */
609 sleep(1);
611 if (kill(pid, SIGUSR1) != 0) my_e(1);
612 if (kill(pid, SIGUSR2) != 0) my_e(2);
614 /* All signals should arrive at the tracer, although in "random" order. */
615 if (waitpid(pid, &status, 0) != pid) my_e(3);
616 if (!_WIFSTOPPED(status)) my_e(4);
617 if (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGUSR2) my_e(5);
619 /* The tracer should see kills arriving while the tracee is stopped. */
620 if (kill(pid, WSTOPSIG(status)) != 0) my_e(6);
622 if (waitpid(pid, &status, WNOHANG) != pid) my_e(7);
623 if (!_WIFSTOPPED(status)) my_e(8);
624 if (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGUSR2) my_e(9);
625 sig = (WSTOPSIG(status) == SIGUSR1) ? SIGUSR2 : SIGUSR1;
627 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(10);
629 if (waitpid(pid, &status, 0) != pid) my_e(11);
630 if (!_WIFSTOPPED(status)) my_e(12);
631 if (WSTOPSIG(status) != sig) my_e(13);
633 if (waitpid(pid, &status, WNOHANG) != 0) my_e(14);
635 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(15);
637 /* Ignored signals passed via ptrace() should be ignored. */
638 if (kill(pid, SIGUSR1) != 0) my_e(16);
640 if (waitpid(pid, &status, 0) != pid) my_e(17);
641 if (!_WIFSTOPPED(status)) my_e(18);
642 if (WSTOPSIG(status) != SIGUSR1) my_e(19);
644 if (ptrace(T_RESUME, pid, 0, SIGCHLD) != 0) my_e(20);
646 /* if the pause has been aborted (shouldn't happen!), let the child exit */
647 sleep(1);
649 if (waitpid(pid, &status, WNOHANG) != 0) my_e(21);
651 /* Caught signals passed via ptrace() should invoke their signal handlers. */
652 if (kill(pid, SIGUSR1) != 0) my_e(22);
654 if (waitpid(pid, &status, 0) != pid) my_e(23);
655 if (!_WIFSTOPPED(status)) my_e(24);
656 if (WSTOPSIG(status) != SIGUSR1) my_e(25);
658 if (ptrace(T_RESUME, pid, 0, SIGUSR1) != 0) my_e(26);
660 if (waitpid(pid, &status, 0) != pid) my_e(27);
661 if (!_WIFEXITED(status)) my_e(28);
662 if ((r = WEXITSTATUS(status)) != 42) my_e(29);
664 traced_wait();
667 void test_exit_child()
669 WRITE(0);
671 for(;;);
674 void test_exit()
676 pid_t pid;
677 int r, status;
679 subtest = 5;
681 pid = traced_fork(test_exit_child);
683 if (READ() != 0) my_e(1);
685 sleep(1);
687 if (kill(pid, SIGSTOP) != 0) my_e(2);
689 if (waitpid(pid, &status, 0) != pid) my_e(3);
690 if (!_WIFSTOPPED(status)) my_e(4);
691 if (WSTOPSIG(status) != SIGSTOP) my_e(5);
693 /* There should be no more signals pending for the tracer now. */
694 if (waitpid(pid, &status, WNOHANG) != 0) my_e(6);
696 /* ptrace(T_EXIT) should terminate the process with the given exit value. */
697 if (ptrace(T_EXIT, pid, 0, 42) != 0) my_e(7);
699 if (waitpid(pid, &status, 0) != pid) my_e(8);
700 if (!_WIFEXITED(status)) my_e(9);
701 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
703 traced_wait();
706 void test_term_child()
708 signal(SIGUSR1, SIG_DFL);
709 signal(SIGUSR2, dummy_handler);
711 WRITE(0);
713 pause();
715 my_e(100);
718 void test_term()
720 pid_t pid;
721 int status;
723 subtest = 6;
725 pid = traced_fork(test_term_child);
727 if (READ() != 0) my_e(1);
729 /* If the first of two signals terminates the traced child, the second signal
730 * may or may not be delivered to the tracer - this is merely a policy issue.
731 * However, nothing unexpected should happen.
733 if (kill(pid, SIGUSR1) != 0) my_e(2);
734 if (kill(pid, SIGUSR2) != 0) my_e(3);
736 if (waitpid(pid, &status, 0) != pid) my_e(4);
737 if (!_WIFSTOPPED(status)) my_e(5);
739 if (ptrace(T_RESUME, pid, 0, SIGUSR1) != 0) my_e(6);
741 if (waitpid(pid, &status, 0) != pid) my_e(7);
743 if (_WIFSTOPPED(status)) {
744 if (ptrace(T_RESUME, pid, 0, SIGUSR1) != 0) my_e(8);
746 if (waitpid(pid, &status, 0) != pid) my_e(9);
749 if (!_WIFSIGNALED(status)) my_e(10);
750 if (WTERMSIG(status) != SIGUSR1) my_e(11);
752 traced_wait();
755 void test_catch_child()
757 struct sigaction sa;
758 sigset_t set, oset;
760 sa.sa_handler = catch_handler;
761 sigemptyset(&sa.sa_mask);
762 sa.sa_flags = SA_NODEFER;
764 sigaction(SIGUSR1, &sa, NULL);
765 sigaction(SIGUSR2, &sa, NULL);
766 sigaction(SIGTERM, &sa, NULL);
768 sigfillset(&set);
769 sigprocmask(SIG_SETMASK, &set, &oset);
771 caught = 0;
773 WRITE(0);
775 while (caught != 7) sigsuspend(&oset);
777 exit(42);
780 void test_catch()
782 pid_t pid;
783 int r, sig, status;
785 subtest = 7;
787 pid = traced_fork(test_catch_child);
789 if (READ() != 0) my_e(1);
791 if (kill(pid, SIGUSR1) != 0) my_e(2);
792 if (kill(pid, SIGUSR2) != 0) my_e(3);
794 if (waitpid(pid, &status, 0) != pid) my_e(4);
795 if (!_WIFSTOPPED(status)) my_e(5);
796 if (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGUSR2) my_e(6);
797 sig = (WSTOPSIG(status) == SIGUSR1) ? SIGUSR2 : SIGUSR1;
799 if (ptrace(T_RESUME, pid, 0, WSTOPSIG(status)) != 0) my_e(7);
801 if (kill(pid, SIGTERM) != 0) my_e(8);
803 if (waitpid(pid, &status, 0) != pid) my_e(9);
804 if (!_WIFSTOPPED(status)) my_e(10);
805 if (WSTOPSIG(status) != sig && WSTOPSIG(status) != SIGTERM) my_e(11);
806 if (WSTOPSIG(status) == sig) sig = SIGTERM;
808 if (ptrace(T_RESUME, pid, 0, WSTOPSIG(status)) != 0) my_e(12);
810 if (kill(pid, SIGBUS) != 0) my_e(13);
812 if (waitpid(pid, &status, 0) != pid) my_e(14);
813 if (!_WIFSTOPPED(status)) my_e(15);
814 if (WSTOPSIG(status) != sig && WSTOPSIG(status) != SIGBUS) my_e(16);
816 if (ptrace(T_RESUME, pid, 0, sig) != 0) my_e(17);
818 if (WSTOPSIG(status) == sig) sig = SIGBUS;
820 if (waitpid(pid, &status, 0) != pid) my_e(18);
821 if (!_WIFSTOPPED(status)) my_e(19);
822 if (WSTOPSIG(status) != sig) my_e(20);
824 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(21);
826 if (waitpid(pid, &status, 0) != pid) my_e(22);
827 if (!_WIFEXITED(status)) my_e(23);
828 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
830 traced_wait();
833 void test_kill_child()
835 sigset_t set;
837 signal(SIGKILL, SIG_IGN);
838 sigfillset(&set);
839 sigprocmask(SIG_SETMASK, &set, NULL);
841 WRITE(0);
843 pause();
845 my_e(100);
848 void test_kill()
850 pid_t pid;
851 int status;
853 subtest = 8;
855 pid = traced_fork(test_kill_child);
857 if (READ() != 0) my_e(1);
859 /* SIGKILL must be unstoppable in every way. */
860 if (kill(pid, SIGKILL) != 0) my_e(2);
862 if (waitpid(pid, &status, 0) != pid) my_e(3);
863 if (!_WIFSIGNALED(status)) my_e(4);
864 if (WTERMSIG(status) != SIGKILL) my_e(5);
866 /* After termination, the child must no longer be visible to the tracer. */
867 if (waitpid(pid, &status, WNOHANG) != -1) my_e(6);
868 if (errno != ECHILD) my_e(7);
870 traced_wait();
873 void test_attach_child()
875 if (ptrace(T_OK, 0, 0, 0) != -1) my_e(100);
876 if (errno != EBUSY) my_e(101);
878 WRITE(0);
880 if (READ() != 0) my_e(102);
882 exit(42);
885 void test_attach()
887 pid_t pid;
889 subtest = 9;
891 /* Attaching to kernel processes is not allowed. */
892 if (ptrace(T_ATTACH, -1, 0, 0) != -1) my_e(1);
893 if (errno != ESRCH) my_e(2);
895 /* Attaching to self is not allowed. */
896 if (ptrace(T_ATTACH, getpid(), 0, 0) != -1) my_e(3);
897 if (errno != EPERM) my_e(4);
899 /* Attaching to PM is not allowed. */
900 #if 0
901 /* FIXME: disabled until we can reliably determine PM's pid */
902 if (ptrace(T_ATTACH, 0, 0, 0) != -1) my_e(5);
903 if (errno != EPERM) my_e(6);
904 #endif
906 pid = traced_fork(test_attach_child);
908 /* Attaching more than once is not allowed. */
909 if (ptrace(T_ATTACH, pid, 0, 0) != -1) my_e(7);
910 if (errno != EBUSY) my_e(8);
912 if (READ() != 0) my_e(9);
914 /* Detaching a running child should not succeed. */
915 if (ptrace(T_DETACH, pid, 0, 0) == 0) my_e(10);
916 if (errno != EBUSY) my_e(11);
918 detach_running(pid);
920 WRITE(0);
922 traced_wait();
925 void test_detach_child()
927 struct sigaction sa;
928 sigset_t set, sset, oset;
930 sa.sa_handler = catch_handler;
931 sigemptyset(&sa.sa_mask);
932 sa.sa_flags = SA_NODEFER;
934 sigaction(SIGUSR1, &sa, NULL);
935 sigaction(SIGUSR2, &sa, NULL);
936 sigaction(SIGTERM, &sa, NULL);
938 sigfillset(&set);
939 sigprocmask(SIG_SETMASK, &set, &oset);
941 sigfillset(&sset);
942 sigdelset(&sset, SIGUSR1);
944 caught = 0;
946 WRITE(0);
948 if (sigsuspend(&sset) != -1) my_e(102);
949 if (errno != EINTR) my_e(103);
951 if (caught != 1) my_e(104);
953 if (READ() != 0) my_e(105);
955 while (caught != 7) sigsuspend(&oset);
957 exit(42);
960 void test_detach()
962 pid_t pid;
963 int r, status;
965 /* Can't use traced_fork(), so simplify a bit */
966 if (attach != 0) return;
968 subtest = 10;
970 pid = traced_pfork(test_detach_child);
972 if (READ() != 0) my_e(1);
974 /* The tracer should not see signals sent to the process before attaching. */
975 if (kill(pid, SIGUSR2) != 0) my_e(2);
977 if (ptrace(T_ATTACH, pid, 0, 0) != 0) my_e(3);
979 if (waitpid(pid, &status, 0) != pid) my_e(4);
980 if (!_WIFSTOPPED(status)) my_e(5);
981 if (WSTOPSIG(status) != SIGSTOP) my_e(6);
983 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(7);
985 if (kill(pid, SIGUSR1) != 0) my_e(8);
987 if (waitpid(pid, &status, 0) != pid) my_e(9);
988 if (!_WIFSTOPPED(status)) my_e(10);
989 if (WSTOPSIG(status) != SIGUSR1) my_e(11);
991 /* Signals pending at the tracer should be passed on after detaching. */
992 if (kill(pid, SIGTERM) != 0) my_e(12);
994 /* A signal may be passed with the detach request. */
995 if (ptrace(T_DETACH, pid, 0, SIGUSR1) != 0) my_e(13);
997 WRITE(0);
999 if (waitpid(pid, &status, 0) != pid) my_e(14);
1000 if (!_WIFEXITED(status)) my_e(15);
1001 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1003 traced_wait();
1006 void test_death_child()
1008 pid_t pid;
1010 pid = fork();
1012 if (pid < 0) my_e(100);
1014 if (pid == 0) {
1015 ptrace(T_OK, 0, 0, 0);
1017 WRITE(getpid());
1019 for (;;) pause();
1022 if (READ() != 0) my_e(101);
1024 kill(getpid(), SIGKILL);
1026 my_e(102);
1029 void test_death()
1031 pid_t pid, cpid;
1032 int status;
1034 subtest = 11;
1036 pid = traced_fork(test_death_child);
1038 cpid = READ();
1040 if (kill(cpid, 0) != 0) my_e(1);
1042 WRITE(0);
1044 if (waitpid(pid, &status, 0) != pid) my_e(2);
1045 if (!_WIFSIGNALED(status)) my_e(3);
1046 if (WTERMSIG(status) != SIGKILL) my_e(4);
1048 /* The children of killed tracers should be terminated. */
1049 while (kill(cpid, 0) == 0) sleep(1);
1050 if (errno != ESRCH) my_e(5);
1052 traced_wait();
1055 void test_zdeath_child()
1057 if (READ() != 0) my_e(100);
1059 exit(42);
1062 void test_zdeath()
1064 pid_t pid, tpid;
1065 int r, status;
1067 /* Can't use traced_fork(), so simplify a bit */
1068 if (attach != 0) return;
1070 subtest = 12;
1072 pid = traced_pfork(test_zdeath_child);
1074 tpid = fork();
1076 if (tpid < 0) my_e(1);
1078 if (tpid == 0) {
1079 if (ptrace(T_ATTACH, pid, 0, 0) != 0) exit(101);
1081 if (waitpid(pid, &status, 0) != pid) exit(102);
1082 if (!_WIFSTOPPED(status)) exit(103);
1083 if (WSTOPSIG(status) != SIGSTOP) exit(104);
1085 if (ptrace(T_RESUME, pid, 0, 0) != 0) exit(105);
1087 WRITE(0);
1089 /* Unwaited-for traced zombies should be passed to their parent. */
1090 sleep(2);
1092 exit(84);
1095 sleep(1);
1097 /* However, that should only happen once the tracer has actually died. */
1098 if (waitpid(pid, &status, WNOHANG) != 0) my_e(2);
1100 if (waitpid(tpid, &status, 0) != tpid) my_e(3);
1101 if (!_WIFEXITED(status)) my_e(4);
1102 if ((r = WEXITSTATUS(status)) != 84) my_e(r);
1104 if (waitpid(pid, &status, 0) != pid) my_e(5);
1105 if (!_WIFEXITED(status)) my_e(6);
1106 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1108 traced_wait();
1111 void test_syscall_child()
1113 signal(SIGUSR1, count_handler);
1114 signal(SIGUSR2, count_handler);
1116 sigs = 0;
1118 WRITE(0);
1120 if (READ() != 0) my_e(100);
1122 /* Three calls (may fail) */
1123 setuid(0);
1124 close(123);
1125 getpid();
1127 if (sigs != 2) my_e(101);
1129 exit(42);
1132 void test_syscall()
1134 pid_t pid;
1135 int i, r, sig, status;
1137 subtest = 13;
1139 pid = traced_fork(test_syscall_child);
1141 if (READ() != 0) my_e(1);
1143 if (kill(pid, SIGSTOP) != 0) my_e(2);
1145 if (waitpid(pid, &status, 0) != pid) my_e(3);
1146 if (!_WIFSTOPPED(status)) my_e(4);
1147 if (WSTOPSIG(status) != SIGSTOP) my_e(5);
1149 WRITE(0);
1151 /* Upon resuming a first system call, no syscall leave event must be sent. */
1152 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(6);
1154 if (waitpid(pid, &status, 0) != pid) my_e(7);
1156 for (i = 0; _WIFSTOPPED(status); i++) {
1157 if (WSTOPSIG(status) != SIGTRAP) my_e(8);
1159 /* Signals passed via T_SYSCALL should arrive, on enter and exit. */
1160 if (i == 3) sig = SIGUSR1;
1161 else if (i == 6) sig = SIGUSR2;
1162 else sig = 0;
1164 if (ptrace(T_SYSCALL, pid, 0, sig) != 0) my_e(9);
1166 if (waitpid(pid, &status, 0) != pid) my_e(10);
1169 if (!_WIFEXITED(status)) my_e(11);
1170 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1172 /* The number of events seen is deterministic but libc-dependent. */
1173 if (i < 10 || i > 100) my_e(12);
1175 /* The last system call event must be for entering exit(). */
1176 if (!(i % 2)) my_e(13);
1178 traced_wait();
1181 void test_tracefork_child()
1183 pid_t pid;
1185 signal(SIGHUP, SIG_IGN);
1187 pid = setsid();
1189 WRITE(pid);
1191 if (READ() != 0) my_e(100);
1193 if ((pid = fork()) < 0) my_e(101);
1195 exit(pid > 0 ? 42 : 84);
1198 void test_tracefork()
1200 pid_t pgrp, ppid, cpid, wpid;
1201 int r, status, gotstop, ptraps, ctraps;
1203 subtest = 14;
1205 ppid = traced_fork(test_tracefork_child);
1207 if ((pgrp = READ()) <= 0) my_e(1);
1209 if (kill(ppid, SIGSTOP) != 0) my_e(2);
1211 if (waitpid(ppid, &status, 0) != ppid) my_e(3);
1212 if (!_WIFSTOPPED(status)) my_e(4);
1213 if (WSTOPSIG(status) != SIGSTOP) my_e(5);
1215 if (ptrace(T_SETOPT, ppid, 0, TO_TRACEFORK) != 0) my_e(6);
1217 WRITE(0);
1219 if (ptrace(T_SYSCALL, ppid, 0, 0) != 0) my_e(7);
1221 cpid = -1;
1222 gotstop = -1;
1224 /* Count how many traps we get for parent and child, until they both exit. */
1225 for (ptraps = ctraps = 0; ppid || cpid; ) {
1226 wpid = waitpid(-pgrp, &status, 0);
1228 if (wpid <= 0) my_e(8);
1229 if (cpid < 0 && wpid != ppid) {
1230 cpid = wpid;
1231 gotstop = 0;
1233 if (wpid != ppid && wpid != cpid) my_e(9);
1235 if (_WIFEXITED(status)) {
1236 if (wpid == ppid) {
1237 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1238 ppid = 0;
1240 else {
1241 if ((r = WEXITSTATUS(status)) != 84) my_e(r);
1242 cpid = 0;
1245 else {
1246 if (!_WIFSTOPPED(status)) my_e(10);
1248 switch (WSTOPSIG(status)) {
1249 case SIGCHLD:
1250 case SIGHUP:
1251 break;
1252 case SIGSTOP:
1253 if (wpid != cpid) my_e(11);
1254 if (gotstop) my_e(12);
1255 gotstop = 1;
1256 break;
1257 case SIGTRAP:
1258 if (wpid == ppid) ptraps++;
1259 else ctraps++;
1260 break;
1261 default:
1262 my_e(13);
1265 if (ptrace(T_SYSCALL, wpid, 0, 0) != 0) my_e(14);
1269 /* The parent should get an odd number of traps: the first one is a syscall
1270 * enter trap (typically for the fork()), the last one is the syscall enter
1271 * trap for its exit().
1273 if (ptraps < 3) my_e(15);
1274 if (!(ptraps % 2)) my_e(16);
1276 /* The child should get an even number of traps: the first one is a syscall
1277 * leave trap from the fork(), the last one is the syscall enter trap for
1278 * its exit().
1280 if (ctraps < 2) my_e(17);
1281 if (ctraps % 2) my_e(18);
1283 traced_wait();
1286 void sigexec(setflag, opt, traps, stop)
1287 int setflag;
1288 int opt;
1289 int *traps;
1290 int *stop;
1292 pid_t pid;
1293 int r, status;
1295 pid = traced_fork(test_exec_child);
1297 if (kill(pid, SIGSTOP) != 0) my_e(1);
1299 if (waitpid(pid, &status, 0) != pid) my_e(2);
1300 if (!_WIFSTOPPED(status)) my_e(3);
1301 if (WSTOPSIG(status) != SIGSTOP) my_e(4);
1303 if (setflag && ptrace(T_SETOPT, pid, 0, opt) != 0) my_e(5);
1305 WRITE(0);
1307 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(6);
1309 *traps = 0;
1310 *stop = -1;
1312 for (;;) {
1313 if (waitpid(pid, &status, 0) != pid) my_e(7);
1315 if (_WIFEXITED(status)) break;
1317 if (!_WIFSTOPPED(status)) my_e(8);
1319 switch (WSTOPSIG(status)) {
1320 case SIGTRAP:
1321 (*traps)++;
1322 break;
1323 case SIGSTOP:
1324 if (*stop >= 0) my_e(9);
1325 *stop = *traps;
1326 break;
1327 default:
1328 my_e(10);
1331 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(11);
1334 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1336 traced_wait();
1339 void test_trapexec()
1341 int traps, stop;
1343 subtest = 15;
1345 sigexec(1, 0, &traps, &stop);
1347 /* The exec does not cause a SIGSTOP. This gives us an even number of traps;
1348 * as above, but plus the exec()'s extra SIGTRAP. This trap is
1349 * indistinguishable from a syscall trap, especially when considering failed
1350 * exec() calls and immediately following signal handler invocations.
1352 if (traps < 4) my_e(12);
1353 if (traps % 2) my_e(13);
1354 if (stop >= 0) my_e(14);
1357 void test_altexec()
1359 int traps, stop;
1361 subtest = 16;
1363 sigexec(1, TO_ALTEXEC, &traps, &stop);
1365 /* The exec causes a SIGSTOP. This gives us an odd number of traps: a pair
1366 * for each system call, plus one for the final exit(). The stop must have
1367 * taken place after a syscall enter event, i.e. must be odd as well.
1369 if (traps < 3) my_e(12);
1370 if (!(traps % 2)) my_e(13);
1371 if (stop < 0) my_e(14);
1372 if (!(stop % 2)) my_e(15);
1375 void test_noexec()
1377 int traps, stop;
1379 subtest = 17;
1381 sigexec(1, TO_NOEXEC, &traps, &stop);
1383 /* The exec causes no signal at all. As above, but without the SIGSTOPs. */
1384 if (traps < 3) my_e(12);
1385 if (!(traps % 2)) my_e(13);
1386 if (stop >= 0) my_e(14);
1389 void test_defexec()
1391 int traps, stop;
1393 /* We want to test the default of T_OK (0) and T_ATTACH (TO_NOEXEC). */
1394 if (attach != 0 && attach != 1) return;
1396 subtest = 18;
1398 /* Do not set any options this time. */
1399 sigexec(0, 0, &traps, &stop);
1401 /* See above. */
1402 if (attach == 0) {
1403 if (traps < 4) my_e(12);
1404 if (traps % 2) my_e(13);
1405 if (stop >= 0) my_e(14);
1407 else {
1408 if (traps < 3) my_e(15);
1409 if (!(traps % 2)) my_e(16);
1410 if (stop >= 0) my_e(17);
1414 void test_reattach_child()
1416 struct timeval tv;
1418 if (READ() != 0) my_e(100);
1420 tv.tv_sec = 2;
1421 tv.tv_usec = 0;
1422 if (select(0, NULL, NULL, NULL, &tv) != 0) my_e(101);
1424 exit(42);
1427 void test_reattach()
1429 pid_t pid;
1430 int r, status, count;
1432 subtest = 19;
1434 pid = traced_fork(test_reattach_child);
1436 if (kill(pid, SIGSTOP) != 0) my_e(1);
1438 if (waitpid(pid, &status, 0) != pid) my_e(2);
1439 if (!_WIFSTOPPED(status)) my_e(3);
1440 if (WSTOPSIG(status) != SIGSTOP) my_e(4);
1442 WRITE(0);
1444 signal(SIGALRM, dummy_handler);
1445 alarm(1);
1447 /* Start tracing system calls. We don't know how many there will be until
1448 * we reach the child's select(), so we have to interrupt ourselves.
1449 * The hard assumption here is that the child is able to enter the select()
1450 * within a second, despite being traced. If this is not the case, the test
1451 * may hang or fail, and the child may die from a SIGTRAP.
1453 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(5);
1455 for (count = 0; (r = waitpid(pid, &status, 0)) == pid; count++) {
1456 if (!_WIFSTOPPED(status)) my_e(6);
1457 if (WSTOPSIG(status) != SIGTRAP) my_e(7);
1459 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(8);
1462 if (r != -1 || errno != EINTR) my_e(9);
1464 /* We always start with syscall enter event; the last event we should have
1465 * seen before the alarm was entering the select() call.
1467 if (!(count % 2)) my_e(10);
1469 /* Detach, and immediately attach again. */
1470 detach_running(pid);
1472 if (ptrace(T_ATTACH, pid, 0, 0) != 0) my_e(11);
1474 if (waitpid(pid, &status, 0) != pid) my_e(12);
1475 if (!_WIFSTOPPED(status)) my_e(13);
1476 if (WSTOPSIG(status) != SIGSTOP) my_e(14);
1478 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(15);
1480 if (waitpid(pid, &status, 0) != pid) my_e(16);
1482 for (count = 0; _WIFSTOPPED(status); count++) {
1483 if (WSTOPSIG(status) != SIGTRAP) my_e(17);
1485 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(18);
1487 if (waitpid(pid, &status, 0) != pid) my_e(19);
1490 if (!_WIFEXITED(status)) my_e(20);
1491 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1493 /* We must not have seen the select()'s syscall leave event, and the last
1494 * event will be the syscall enter for the exit().
1496 if (!(count % 2)) my_e(21);
1498 traced_wait();
1501 void my_e(n)
1502 int n;
1505 if (child) exit(n);
1507 printf("Attach type %d, ", attach);
1508 e(n);