Drop main() prototype. Syncs with NetBSD-8
[minix.git] / minix / tests / test42.c
blob78427a2081fdfaf47925fbb728fd4a06192d75fc
1 /* Tests for MINIX3 ptrace(2) - by D.C. van Moolenbroek */
2 #include <setjmp.h>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <signal.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <sys/wait.h>
10 #include <sys/select.h>
11 #include <sys/ptrace.h>
12 #include <sys/syslimits.h>
14 #define ITERATIONS 3
15 int max_error = 4;
16 #include "common.h"
18 #define my_e(n) { \
19 if (child) exit(n); printf("Attach type %d, ", attach); e(n); }
22 #define _WIFSTOPPED(s) (WIFSTOPPED(s) && !WIFSIGNALED(s) && !WIFEXITED(s))
23 #define _WIFSIGNALED(s) (!WIFSTOPPED(s) && WIFSIGNALED(s) && !WIFEXITED(s))
24 #define _WIFEXITED(s) (!WIFSTOPPED(s) && !WIFSIGNALED(s) && WIFEXITED(s))
26 #define timed_test(func) (timed_test_func(#func, func));
28 int main(int argc, char **argv);
29 void test(int m, int a);
30 void timed_test_func(const char *s, void (* func)(void));
31 void timed_test_timeout(int signum);
32 pid_t traced_fork(void (*c) (void));
33 pid_t traced_pfork(void (*c) (void));
34 void WRITE(int value);
35 int READ(void);
36 void traced_wait(void);
37 void detach_running(pid_t pid);
38 void dummy_handler(int sig);
39 void exit_handler(int sig);
40 void count_handler(int sig);
41 void catch_handler(int sig);
42 void test_wait_child(void);
43 void test_wait(void);
44 void test_exec_child(void);
45 void test_exec(void);
46 void test_step_child(void);
47 void test_step(void);
48 void test_sig_child(void);
49 void test_sig(void);
50 void test_exit_child(void);
51 void test_exit(void);
52 void test_term_child(void);
53 void test_term(void);
54 void test_catch_child(void);
55 void test_catch(void);
56 void test_kill_child(void);
57 void test_kill(void);
58 void test_attach_child(void);
59 void test_attach(void);
60 void test_detach_child(void);
61 void test_detach(void);
62 void test_death_child(void);
63 void test_death(void);
64 void test_zdeath_child(void);
65 void test_zdeath(void);
66 void test_syscall_child(void);
67 void test_syscall(void);
68 void test_tracefork_child(void);
69 void test_tracefork(void);
70 void sigexec(int setflag, int opt, int *traps, int *stop);
71 void test_trapexec(void);
72 void test_altexec(void);
73 void test_noexec(void);
74 void test_defexec(void);
75 void test_reattach_child(void);
76 void test_reattach(void);
78 static char *executable;
79 static int child = 0, attach;
80 static pid_t ppid;
81 static int pfd[4];
82 static int sigs, caught;
84 int main(argc, argv)
85 int argc;
86 char **argv;
88 int i, m = 0xFFFFFF, n = 0xF;
89 char cp_cmd[NAME_MAX + 10];
91 if (strcmp(argv[0], "DO CHECK") == 0) {
92 exit(42);
95 start(42);
97 executable = argv[0];
99 snprintf(cp_cmd, sizeof(cp_cmd), "cp ../%s .", executable);
100 system(cp_cmd);
102 if (argc >= 2) m = atoi(argv[1]);
103 if (argc >= 3) n = atoi(argv[2]);
105 for (i = 0; i < ITERATIONS; i++) {
106 if (n & 001) test(m, 0);
107 if (n & 002) test(m, 1);
108 if (n & 004) test(m, 2);
109 if (n & 010) test(m, 3);
112 quit();
113 return(-1); /* impossible */
116 void test(m, a)
117 int m;
118 int a;
120 attach = a;
122 if (m & 00000001) timed_test(test_wait);
123 if (m & 00000002) timed_test(test_exec);
124 #if !defined(__arm__)
125 /* BJG: single-stepping isn't implemented on ARM */
126 if (m & 00000004) timed_test(test_step);
127 #endif
128 if (m & 00000010) timed_test(test_sig);
129 if (m & 00000020) timed_test(test_exit);
130 if (m & 00000040) timed_test(test_term);
131 if (m & 00000100) timed_test(test_catch);
132 if (m & 00000200) timed_test(test_kill);
133 if (m & 00000400) timed_test(test_attach);
134 if (m & 00001000) timed_test(test_detach);
135 if (m & 00002000) timed_test(test_death);
136 if (m & 00004000) timed_test(test_zdeath);
137 if (m & 00010000) timed_test(test_syscall);
138 if (m & 00020000) timed_test(test_tracefork);
139 if (m & 00040000) timed_test(test_trapexec);
140 if (m & 00100000) timed_test(test_altexec);
141 if (m & 00200000) timed_test(test_noexec);
142 if (m & 00400000) timed_test(test_defexec);
143 if (m & 01000000) test_reattach(); /* not timed, catches SIGALRM */
146 static jmp_buf timed_test_context;
148 void timed_test_timeout(int signum)
150 longjmp(timed_test_context, -1);
151 my_e(700);
152 quit();
153 exit(-1);
156 void timed_test_func(const char *s, void (* func)(void))
158 if (setjmp(timed_test_context) == 0)
160 /* the function gets 60 seconds to complete */
161 if (signal(SIGALRM, timed_test_timeout) == SIG_ERR) { my_e(701); return; }
162 alarm(60);
163 func();
164 alarm(0);
166 else
168 /* report timeout as error */
169 printf("timeout in %s\n", s);
170 my_e(702);
174 pid_t traced_fork(c)
175 void (*c)(void);
177 pid_t pid;
178 int r, status;
180 if (pipe(pfd) != 0) my_e(200);
181 if (pipe(&pfd[2]) != 0) my_e(201);
183 switch (attach) {
184 case 0: /* let child volunteer to be traced */
185 pid = fork();
187 if (pid < 0) my_e(202);
189 if (pid == 0) {
190 child = 1;
192 if (ptrace(T_OK, 0, 0, 0) != 0) my_e(203);
194 WRITE(0);
196 c();
198 my_e(204);
201 if (READ() != 0) my_e(205);
203 break;
205 case 1: /* attach to child process */
206 pid = fork();
208 if (pid < 0) my_e(206);
210 if (pid == 0) {
211 child = 1;
213 if (READ() != 0) my_e(207);
215 c();
217 my_e(208);
220 if (ptrace(T_ATTACH, pid, 0, 0) != 0) my_e(209);
222 if (waitpid(pid, &status, 0) != pid) my_e(210);
223 if (!_WIFSTOPPED(status)) my_e(211);
224 if (WSTOPSIG(status) != SIGSTOP) my_e(212);
226 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(213);
228 WRITE(0);
230 break;
232 case 2: /* attach to non-child process */
233 ppid = fork();
235 if (ppid < 0) my_e(214);
237 if (ppid == 0) {
238 pid = fork();
240 if (pid < 0) exit(215);
242 if (pid == 0) {
243 child = 1;
245 if (READ() != 0) my_e(216);
247 c();
249 my_e(217);
252 child = 1;
254 WRITE(pid);
256 if (waitpid(pid, &status, 0) != pid) my_e(218);
257 if (_WIFSTOPPED(status)) my_e(219);
258 if (_WIFEXITED(status) && (r = WEXITSTATUS(status)) != 42) my_e(r);
260 exit(0);
263 pid = READ();
265 if (ptrace(T_ATTACH, pid, 0, 0) != 0) my_e(220);
267 if (waitpid(pid, &status, 0) != pid) my_e(221);
268 if (!_WIFSTOPPED(status)) my_e(222);
269 if (WSTOPSIG(status) != SIGSTOP) my_e(223);
271 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(224);
273 WRITE(0);
275 break;
277 case 3: /* attach by forking from child */
278 ppid = fork();
280 if (ppid < 0) my_e(225);
282 if (ppid == 0) {
283 child = 1;
285 if (ptrace(T_OK, 0, 0, 0) != 0) my_e(226);
287 WRITE(0);
289 if (READ() != 0) my_e(227);
291 pid = fork();
293 if (pid < 0) my_e(228);
295 if (pid == 0) {
296 c();
298 my_e(229);
301 WRITE(pid);
303 if (waitpid(pid, &status, 0) != pid) my_e(230);
304 if (_WIFSTOPPED(status)) my_e(231);
305 if (_WIFEXITED(status) && (r = WEXITSTATUS(status)) != 42) my_e(r);
307 exit(0);
310 if (READ() != 0) my_e(232);
312 if (kill(ppid, SIGSTOP) != 0) my_e(233);
314 if (waitpid(ppid, &status, 0) != ppid) my_e(234);
315 if (!_WIFSTOPPED(status)) my_e(235);
316 if (WSTOPSIG(status) != SIGSTOP) my_e(236);
318 if (ptrace(T_SETOPT, ppid, 0, TO_TRACEFORK) != 0) my_e(237);
320 if (ptrace(T_RESUME, ppid, 0, 0) != 0) my_e(238);
322 WRITE(0);
324 pid = READ();
326 if (waitpid(pid, &status, 0) != pid) my_e(239);
327 if (!_WIFSTOPPED(status)) my_e(240);
328 if (WSTOPSIG(status) != SIGSTOP) my_e(241);
330 if (ptrace(T_SETOPT, pid, 0, 0) != 0) my_e(242);
331 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(243);
333 detach_running(ppid);
335 break;
337 default:
338 abort();
341 return pid;
344 pid_t traced_pfork(c)
345 void(*c) (void);
347 pid_t pid;
349 if (pipe(pfd) != 0) my_e(300);
350 if (pipe(&pfd[2]) != 0) my_e(301);
352 pid = fork();
354 if (pid < 0) my_e(302);
356 if (pid == 0) {
357 child = 1;
359 c();
361 my_e(303);
364 return pid;
367 void WRITE(value)
368 int value;
370 if (write(pfd[child*2+1], &value, sizeof(value)) != sizeof(value)) my_e(400);
373 int READ()
375 int value;
377 if (read(pfd[2-child*2], &value, sizeof(value)) != sizeof(value)) my_e(401);
379 return value;
382 void traced_wait()
384 int r, status;
386 if (attach == 2) {
387 if (waitpid(ppid, &status, 0) != ppid) my_e(500);
388 if (!_WIFEXITED(status)) my_e(501);
389 if ((r = WEXITSTATUS(status)) != 0) my_e(r);
391 else {
392 /* Quick hack to clean up detached children */
393 waitpid(-1, NULL, WNOHANG);
396 close(pfd[0]);
397 close(pfd[1]);
398 close(pfd[2]);
399 close(pfd[3]);
402 void detach_running(pid)
403 pid_t pid;
405 /* Detach from a process that is not already stopped. This is the way to do it.
406 * We have to stop the child in order to detach from it, but as the child may
407 * have other signals pending for the tracer, we cannot assume we get our own
408 * signal back immediately. However, because we know that the kill is instant
409 * and resuming with pending signals will only stop the process immediately
410 * again, we can use T_RESUME for all the signals until we get our own signal,
411 * and then detach. A complicating factor is that anywhere during this
412 * procedure, the child may die (e.g. by getting a SIGKILL). In our tests, this
413 * will not happen.
415 int status;
417 if (kill(pid, SIGSTOP) != 0) my_e(600);
419 if (waitpid(pid, &status, 0) != pid) my_e(601);
421 while (_WIFSTOPPED(status)) {
422 if (WSTOPSIG(status) == SIGSTOP) {
423 if (ptrace(T_DETACH, pid, 0, 0) != 0) my_e(602);
425 return;
428 if (ptrace(T_RESUME, pid, 0, WSTOPSIG(status)) != 0) my_e(603);
430 if (waitpid(pid, &status, 0) != pid) my_e(604);
433 /* Apparently the process exited. */
434 if (!_WIFEXITED(status) && !_WIFSIGNALED(status)) my_e(605);
436 /* In our tests, that should not happen. */
437 my_e(606);
440 void dummy_handler(sig)
441 int sig;
445 void exit_handler(sig)
446 int sig;
448 exit(42);
451 void count_handler(sig)
452 int sig;
454 sigs++;
457 void catch_handler(sig)
458 int sig;
460 sigset_t set;
461 int bit;
463 switch (sig) {
464 case SIGUSR1: bit = 1; break;
465 case SIGUSR2: bit = 2; break;
466 case SIGTERM: bit = 4; break;
467 default: bit = 0; my_e(100);
470 sigfillset(&set);
471 sigprocmask(SIG_SETMASK, &set, NULL);
473 if (caught & bit) my_e(101);
474 caught |= bit;
477 void test_wait_child()
479 exit(42);
482 void test_wait()
484 pid_t pid;
485 int status;
487 subtest = 1;
489 pid = traced_fork(test_wait_child);
491 if (waitpid(pid, &status, 0) != pid) my_e(1);
492 if (!_WIFEXITED(status)) my_e(2);
493 if (WEXITSTATUS(status) != 42) my_e(3);
495 traced_wait();
498 void test_exec_child()
500 if (READ() != 0) my_e(100);
502 execl(executable, "DO CHECK", NULL);
504 my_e(101);
507 void test_exec()
509 pid_t pid;
510 int r, status;
512 /* This test covers the T_OK case. */
513 if (attach != 0) return;
515 subtest = 2;
517 pid = traced_fork(test_exec_child);
519 WRITE(0);
521 /* An exec() should result in a trap signal. */
522 if (waitpid(pid, &status, 0) != pid) my_e(1);
523 if (!_WIFSTOPPED(status)) my_e(2);
524 if (WSTOPSIG(status) != SIGTRAP) my_e(3);
526 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(4);
528 if (waitpid(pid, &status, 0) != pid) my_e(5);
529 if (!_WIFEXITED(status)) my_e(6);
530 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
532 traced_wait();
535 void test_step_child()
537 sigset_t set;
539 signal(SIGUSR1, SIG_IGN);
541 WRITE(0);
543 if (READ() != 0) my_e(100);
545 /* It must not be possible for the child to stop the single-step signal. */
546 signal(SIGTRAP, SIG_IGN);
547 sigfillset(&set);
548 sigprocmask(SIG_SETMASK, &set, NULL);
550 exit(42);
553 void test_step()
555 pid_t pid;
556 int r, status, count;
558 subtest = 3;
560 pid = traced_fork(test_step_child);
562 if (READ() != 0) my_e(1);
564 /* While the child is running, neither waitpid() nor ptrace() should work. */
565 if (waitpid(pid, &status, WNOHANG) != 0) my_e(2);
566 if (ptrace(T_RESUME, pid, 0, 0) != -1) my_e(3);
567 if (errno != EBUSY) my_e(4);
569 if (kill(pid, SIGUSR1) != 0) my_e(5);
571 WRITE(0);
573 /* A kill() signal (other than SIGKILL) should be delivered to the tracer. */
574 if (waitpid(pid, &status, 0) != pid) my_e(6);
575 if (!_WIFSTOPPED(status)) my_e(7);
576 if (WSTOPSIG(status) != SIGUSR1) my_e(8);
578 /* ptrace(T_STEP) should result in instruction-wise progress. */
579 for (count = 0; ; count++) {
580 if (ptrace(T_STEP, pid, 0, 0) != 0) my_e(9);
582 if (waitpid(pid, &status, 0) != pid) my_e(10);
583 if (_WIFEXITED(status)) break;
584 if (!_WIFSTOPPED(status)) my_e(11);
585 if (WSTOPSIG(status) != SIGTRAP) my_e(12);
588 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
590 if (count < 10) my_e(13); /* in practice: hundreds */
592 traced_wait();
595 void test_sig_child()
597 signal(SIGUSR1, exit_handler);
599 if (READ() != 0) my_e(100);
601 pause();
603 my_e(101);
606 void test_sig()
608 pid_t pid;
609 int r, sig, status;
611 subtest = 4;
613 pid = traced_fork(test_sig_child);
615 WRITE(0);
617 /* allow the child to enter the pause */
618 sleep(1);
620 if (kill(pid, SIGUSR1) != 0) my_e(1);
621 if (kill(pid, SIGUSR2) != 0) my_e(2);
623 /* All signals should arrive at the tracer, although in "random" order. */
624 if (waitpid(pid, &status, 0) != pid) my_e(3);
625 if (!_WIFSTOPPED(status)) my_e(4);
626 if (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGUSR2) my_e(5);
628 /* The tracer should see kills arriving while the tracee is stopped. */
629 if (kill(pid, WSTOPSIG(status)) != 0) my_e(6);
631 if (waitpid(pid, &status, WNOHANG) != pid) my_e(7);
632 if (!_WIFSTOPPED(status)) my_e(8);
633 if (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGUSR2) my_e(9);
634 sig = (WSTOPSIG(status) == SIGUSR1) ? SIGUSR2 : SIGUSR1;
636 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(10);
638 if (waitpid(pid, &status, 0) != pid) my_e(11);
639 if (!_WIFSTOPPED(status)) my_e(12);
640 if (WSTOPSIG(status) != sig) my_e(13);
642 if (waitpid(pid, &status, WNOHANG) != 0) my_e(14);
644 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(15);
646 /* Ignored signals passed via ptrace() should be ignored. */
647 if (kill(pid, SIGUSR1) != 0) my_e(16);
649 if (waitpid(pid, &status, 0) != pid) my_e(17);
650 if (!_WIFSTOPPED(status)) my_e(18);
651 if (WSTOPSIG(status) != SIGUSR1) my_e(19);
653 if (ptrace(T_RESUME, pid, 0, SIGCHLD) != 0) my_e(20);
655 /* if the pause has been aborted (shouldn't happen!), let the child exit */
656 sleep(1);
658 if (waitpid(pid, &status, WNOHANG) != 0) my_e(21);
660 /* Caught signals passed via ptrace() should invoke their signal handlers. */
661 if (kill(pid, SIGUSR1) != 0) my_e(22);
663 if (waitpid(pid, &status, 0) != pid) my_e(23);
664 if (!_WIFSTOPPED(status)) my_e(24);
665 if (WSTOPSIG(status) != SIGUSR1) my_e(25);
667 if (ptrace(T_RESUME, pid, 0, SIGUSR1) != 0) my_e(26);
669 if (waitpid(pid, &status, 0) != pid) my_e(27);
670 if (!_WIFEXITED(status)) my_e(28);
671 if ((r = WEXITSTATUS(status)) != 42) my_e(29);
673 traced_wait();
676 void test_exit_child()
678 WRITE(0);
680 for(;;);
683 void test_exit()
685 pid_t pid;
686 int r, status;
688 subtest = 5;
690 pid = traced_fork(test_exit_child);
692 if (READ() != 0) my_e(1);
694 sleep(1);
696 if (kill(pid, SIGSTOP) != 0) my_e(2);
698 if (waitpid(pid, &status, 0) != pid) my_e(3);
699 if (!_WIFSTOPPED(status)) my_e(4);
700 if (WSTOPSIG(status) != SIGSTOP) my_e(5);
702 /* There should be no more signals pending for the tracer now. */
703 if (waitpid(pid, &status, WNOHANG) != 0) my_e(6);
705 /* ptrace(T_EXIT) should terminate the process with the given exit value. */
706 if (ptrace(T_EXIT, pid, 0, 42) != 0) my_e(7);
708 if (waitpid(pid, &status, 0) != pid) my_e(8);
709 if (!_WIFEXITED(status)) my_e(9);
710 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
712 traced_wait();
715 void test_term_child()
717 signal(SIGUSR1, SIG_DFL);
718 signal(SIGUSR2, dummy_handler);
720 WRITE(0);
722 pause();
724 my_e(100);
727 void test_term()
729 pid_t pid;
730 int status;
732 subtest = 6;
734 pid = traced_fork(test_term_child);
736 if (READ() != 0) my_e(1);
738 /* If the first of two signals terminates the traced child, the second signal
739 * may or may not be delivered to the tracer - this is merely a policy issue.
740 * However, nothing unexpected should happen.
742 if (kill(pid, SIGUSR1) != 0) my_e(2);
743 if (kill(pid, SIGUSR2) != 0) my_e(3);
745 if (waitpid(pid, &status, 0) != pid) my_e(4);
746 if (!_WIFSTOPPED(status)) my_e(5);
748 if (ptrace(T_RESUME, pid, 0, SIGUSR1) != 0) my_e(6);
750 if (waitpid(pid, &status, 0) != pid) my_e(7);
752 if (_WIFSTOPPED(status)) {
753 if (ptrace(T_RESUME, pid, 0, SIGUSR1) != 0) my_e(8);
755 if (waitpid(pid, &status, 0) != pid) my_e(9);
758 if (!_WIFSIGNALED(status)) my_e(10);
759 if (WTERMSIG(status) != SIGUSR1) my_e(11);
761 traced_wait();
764 void test_catch_child()
766 struct sigaction sa;
767 sigset_t set, oset;
769 sa.sa_handler = catch_handler;
770 sigemptyset(&sa.sa_mask);
771 sa.sa_flags = SA_NODEFER;
773 sigaction(SIGUSR1, &sa, NULL);
774 sigaction(SIGUSR2, &sa, NULL);
775 sigaction(SIGTERM, &sa, NULL);
777 sigfillset(&set);
778 sigprocmask(SIG_SETMASK, &set, &oset);
780 caught = 0;
782 WRITE(0);
784 while (caught != 7) sigsuspend(&oset);
786 exit(42);
789 void test_catch()
791 pid_t pid;
792 int r, sig, status;
794 subtest = 7;
796 pid = traced_fork(test_catch_child);
798 if (READ() != 0) my_e(1);
800 if (kill(pid, SIGUSR1) != 0) my_e(2);
801 if (kill(pid, SIGUSR2) != 0) my_e(3);
803 if (waitpid(pid, &status, 0) != pid) my_e(4);
804 if (!_WIFSTOPPED(status)) my_e(5);
805 if (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGUSR2) my_e(6);
806 sig = (WSTOPSIG(status) == SIGUSR1) ? SIGUSR2 : SIGUSR1;
808 if (ptrace(T_RESUME, pid, 0, WSTOPSIG(status)) != 0) my_e(7);
810 if (kill(pid, SIGTERM) != 0) my_e(8);
812 if (waitpid(pid, &status, 0) != pid) my_e(9);
813 if (!_WIFSTOPPED(status)) my_e(10);
814 if (WSTOPSIG(status) != sig && WSTOPSIG(status) != SIGTERM) my_e(11);
815 if (WSTOPSIG(status) == sig) sig = SIGTERM;
817 if (ptrace(T_RESUME, pid, 0, WSTOPSIG(status)) != 0) my_e(12);
819 if (kill(pid, SIGBUS) != 0) my_e(13);
821 if (waitpid(pid, &status, 0) != pid) my_e(14);
822 if (!_WIFSTOPPED(status)) my_e(15);
823 if (WSTOPSIG(status) != sig && WSTOPSIG(status) != SIGBUS) my_e(16);
825 if (ptrace(T_RESUME, pid, 0, sig) != 0) my_e(17);
827 if (WSTOPSIG(status) == sig) sig = SIGBUS;
829 if (waitpid(pid, &status, 0) != pid) my_e(18);
830 if (!_WIFSTOPPED(status)) my_e(19);
831 if (WSTOPSIG(status) != sig) my_e(20);
833 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(21);
835 if (waitpid(pid, &status, 0) != pid) my_e(22);
836 if (!_WIFEXITED(status)) my_e(23);
837 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
839 traced_wait();
842 void test_kill_child()
844 sigset_t set;
846 signal(SIGKILL, SIG_IGN);
847 sigfillset(&set);
848 sigprocmask(SIG_SETMASK, &set, NULL);
850 WRITE(0);
852 pause();
854 my_e(100);
857 void test_kill()
859 pid_t pid;
860 int status;
862 subtest = 8;
864 pid = traced_fork(test_kill_child);
866 if (READ() != 0) my_e(1);
868 /* SIGKILL must be unstoppable in every way. */
869 if (kill(pid, SIGKILL) != 0) my_e(2);
871 if (waitpid(pid, &status, 0) != pid) my_e(3);
872 if (!_WIFSIGNALED(status)) my_e(4);
873 if (WTERMSIG(status) != SIGKILL) my_e(5);
875 /* After termination, the child must no longer be visible to the tracer. */
876 if (waitpid(pid, &status, WNOHANG) != -1) my_e(6);
877 if (errno != ECHILD) my_e(7);
879 traced_wait();
882 void test_attach_child()
884 if (ptrace(T_OK, 0, 0, 0) != -1) my_e(100);
885 if (errno != EBUSY) my_e(101);
887 WRITE(0);
889 if (READ() != 0) my_e(102);
891 exit(42);
894 void test_attach()
896 pid_t pid;
898 subtest = 9;
900 /* Attaching to kernel processes is not allowed. */
901 if (ptrace(T_ATTACH, -1, 0, 0) != -1) my_e(1);
902 if (errno != ESRCH) my_e(2);
904 /* Attaching to self is not allowed. */
905 if (ptrace(T_ATTACH, getpid(), 0, 0) != -1) my_e(3);
906 if (errno != EPERM) my_e(4);
908 /* Attaching to PM is not allowed. */
909 #if 0
910 /* FIXME: disabled until we can reliably determine PM's pid */
911 if (ptrace(T_ATTACH, 0, 0, 0) != -1) my_e(5);
912 if (errno != EPERM) my_e(6);
913 #endif
915 pid = traced_fork(test_attach_child);
917 /* Attaching more than once is not allowed. */
918 if (ptrace(T_ATTACH, pid, 0, 0) != -1) my_e(7);
919 if (errno != EBUSY) my_e(8);
921 if (READ() != 0) my_e(9);
923 /* Detaching a running child should not succeed. */
924 if (ptrace(T_DETACH, pid, 0, 0) == 0) my_e(10);
925 if (errno != EBUSY) my_e(11);
927 detach_running(pid);
929 WRITE(0);
931 traced_wait();
934 void test_detach_child()
936 struct sigaction sa;
937 sigset_t set, sset, oset;
939 sa.sa_handler = catch_handler;
940 sigemptyset(&sa.sa_mask);
941 sa.sa_flags = SA_NODEFER;
943 sigaction(SIGUSR1, &sa, NULL);
944 sigaction(SIGUSR2, &sa, NULL);
945 sigaction(SIGTERM, &sa, NULL);
947 sigfillset(&set);
948 sigprocmask(SIG_SETMASK, &set, &oset);
950 sigfillset(&sset);
951 sigdelset(&sset, SIGUSR1);
953 caught = 0;
955 WRITE(0);
957 if (sigsuspend(&sset) != -1) my_e(102);
958 if (errno != EINTR) my_e(103);
960 if (caught != 1) my_e(104);
962 if (READ() != 0) my_e(105);
964 while (caught != 7) sigsuspend(&oset);
966 exit(42);
969 void test_detach()
971 pid_t pid;
972 int r, status;
974 /* Can't use traced_fork(), so simplify a bit */
975 if (attach != 0) return;
977 subtest = 10;
979 pid = traced_pfork(test_detach_child);
981 if (READ() != 0) my_e(1);
983 /* The tracer should not see signals sent to the process before attaching. */
984 if (kill(pid, SIGUSR2) != 0) my_e(2);
986 if (ptrace(T_ATTACH, pid, 0, 0) != 0) my_e(3);
988 if (waitpid(pid, &status, 0) != pid) my_e(4);
989 if (!_WIFSTOPPED(status)) my_e(5);
990 if (WSTOPSIG(status) != SIGSTOP) my_e(6);
992 if (ptrace(T_RESUME, pid, 0, 0) != 0) my_e(7);
994 if (kill(pid, SIGUSR1) != 0) my_e(8);
996 if (waitpid(pid, &status, 0) != pid) my_e(9);
997 if (!_WIFSTOPPED(status)) my_e(10);
998 if (WSTOPSIG(status) != SIGUSR1) my_e(11);
1000 /* Signals pending at the tracer should be passed on after detaching. */
1001 if (kill(pid, SIGTERM) != 0) my_e(12);
1003 /* A signal may be passed with the detach request. */
1004 if (ptrace(T_DETACH, pid, 0, SIGUSR1) != 0) my_e(13);
1006 WRITE(0);
1008 if (waitpid(pid, &status, 0) != pid) my_e(14);
1009 if (!_WIFEXITED(status)) my_e(15);
1010 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1012 traced_wait();
1015 void test_death_child()
1017 pid_t pid;
1019 pid = fork();
1021 if (pid < 0) my_e(100);
1023 if (pid == 0) {
1024 ptrace(T_OK, 0, 0, 0);
1026 WRITE(getpid());
1028 for (;;) pause();
1031 if (READ() != 0) my_e(101);
1033 kill(getpid(), SIGKILL);
1035 my_e(102);
1038 void test_death()
1040 pid_t pid, cpid;
1041 int status;
1043 subtest = 11;
1045 pid = traced_fork(test_death_child);
1047 cpid = READ();
1049 if (kill(cpid, 0) != 0) my_e(1);
1051 WRITE(0);
1053 if (waitpid(pid, &status, 0) != pid) my_e(2);
1054 if (!_WIFSIGNALED(status)) my_e(3);
1055 if (WTERMSIG(status) != SIGKILL) my_e(4);
1057 /* The children of killed tracers should be terminated. */
1058 while (kill(cpid, 0) == 0) sleep(1);
1059 if (errno != ESRCH) my_e(5);
1061 traced_wait();
1064 void test_zdeath_child()
1066 if (READ() != 0) my_e(100);
1068 exit(42);
1071 void test_zdeath()
1073 pid_t pid, tpid;
1074 int r, status;
1076 /* Can't use traced_fork(), so simplify a bit */
1077 if (attach != 0) return;
1079 subtest = 12;
1081 pid = traced_pfork(test_zdeath_child);
1083 tpid = fork();
1085 if (tpid < 0) my_e(1);
1087 if (tpid == 0) {
1088 if (ptrace(T_ATTACH, pid, 0, 0) != 0) exit(101);
1090 if (waitpid(pid, &status, 0) != pid) exit(102);
1091 if (!_WIFSTOPPED(status)) exit(103);
1092 if (WSTOPSIG(status) != SIGSTOP) exit(104);
1094 if (ptrace(T_RESUME, pid, 0, 0) != 0) exit(105);
1096 WRITE(0);
1098 /* Unwaited-for traced zombies should be passed to their parent. */
1099 sleep(2);
1101 exit(84);
1104 sleep(1);
1106 /* However, that should only happen once the tracer has actually died. */
1107 if (waitpid(pid, &status, WNOHANG) != 0) my_e(2);
1109 if (waitpid(tpid, &status, 0) != tpid) my_e(3);
1110 if (!_WIFEXITED(status)) my_e(4);
1111 if ((r = WEXITSTATUS(status)) != 84) my_e(r);
1113 if (waitpid(pid, &status, 0) != pid) my_e(5);
1114 if (!_WIFEXITED(status)) my_e(6);
1115 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1117 traced_wait();
1120 void test_syscall_child()
1122 signal(SIGUSR1, count_handler);
1123 signal(SIGUSR2, count_handler);
1125 sigs = 0;
1127 WRITE(0);
1129 if (READ() != 0) my_e(100);
1131 /* Three calls (may fail) */
1132 setuid(0);
1133 close(123);
1134 getpid();
1136 if (sigs != 2) my_e(101);
1138 exit(42);
1141 void test_syscall()
1143 pid_t pid;
1144 int i, r, sig, status;
1146 subtest = 13;
1148 pid = traced_fork(test_syscall_child);
1150 if (READ() != 0) my_e(1);
1152 if (kill(pid, SIGSTOP) != 0) my_e(2);
1154 if (waitpid(pid, &status, 0) != pid) my_e(3);
1155 if (!_WIFSTOPPED(status)) my_e(4);
1156 if (WSTOPSIG(status) != SIGSTOP) my_e(5);
1158 WRITE(0);
1160 /* Upon resuming a first system call, no syscall leave event must be sent. */
1161 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(6);
1163 if (waitpid(pid, &status, 0) != pid) my_e(7);
1165 for (i = 0; _WIFSTOPPED(status); i++) {
1166 if (WSTOPSIG(status) != SIGTRAP) my_e(8);
1168 /* Signals passed via T_SYSCALL should arrive, on enter and exit. */
1169 if (i == 3) sig = SIGUSR1;
1170 else if (i == 6) sig = SIGUSR2;
1171 else sig = 0;
1173 if (ptrace(T_SYSCALL, pid, 0, sig) != 0) my_e(9);
1175 if (waitpid(pid, &status, 0) != pid) my_e(10);
1178 if (!_WIFEXITED(status)) my_e(11);
1179 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1181 /* The number of events seen is deterministic but libc-dependent. */
1182 if (i < 10 || i > 100) my_e(12);
1184 /* The last system call event must be for entering exit(). */
1185 if (!(i % 2)) my_e(13);
1187 traced_wait();
1190 void test_tracefork_child()
1192 pid_t pid;
1194 signal(SIGHUP, SIG_IGN);
1196 pid = setsid();
1198 WRITE(pid);
1200 if (READ() != 0) my_e(100);
1202 if ((pid = fork()) < 0) my_e(101);
1204 exit(pid > 0 ? 42 : 84);
1207 void test_tracefork()
1209 pid_t pgrp, ppid, cpid, wpid;
1210 int r, status, gotstop, ptraps, ctraps;
1212 subtest = 14;
1214 ppid = traced_fork(test_tracefork_child);
1216 if ((pgrp = READ()) <= 0) my_e(1);
1218 if (kill(ppid, SIGSTOP) != 0) my_e(2);
1220 if (waitpid(ppid, &status, 0) != ppid) my_e(3);
1221 if (!_WIFSTOPPED(status)) my_e(4);
1222 if (WSTOPSIG(status) != SIGSTOP) my_e(5);
1224 if (ptrace(T_SETOPT, ppid, 0, TO_TRACEFORK) != 0) my_e(6);
1226 WRITE(0);
1228 if (ptrace(T_SYSCALL, ppid, 0, 0) != 0) my_e(7);
1230 cpid = -1;
1231 gotstop = -1;
1233 /* Count how many traps we get for parent and child, until they both exit. */
1234 for (ptraps = ctraps = 0; ppid || cpid; ) {
1235 wpid = waitpid(-pgrp, &status, 0);
1237 if (wpid <= 0) my_e(8);
1238 if (cpid < 0 && wpid != ppid) {
1239 cpid = wpid;
1240 gotstop = 0;
1242 if (wpid != ppid && wpid != cpid) my_e(9);
1244 if (_WIFEXITED(status)) {
1245 if (wpid == ppid) {
1246 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1247 ppid = 0;
1249 else {
1250 if ((r = WEXITSTATUS(status)) != 84) my_e(r);
1251 cpid = 0;
1254 else {
1255 if (!_WIFSTOPPED(status)) my_e(10);
1257 switch (WSTOPSIG(status)) {
1258 case SIGCHLD:
1259 case SIGHUP:
1260 break;
1261 case SIGSTOP:
1262 if (wpid != cpid) my_e(11);
1263 if (gotstop) my_e(12);
1264 gotstop = 1;
1265 break;
1266 case SIGTRAP:
1267 if (wpid == ppid) ptraps++;
1268 else ctraps++;
1269 break;
1270 default:
1271 my_e(13);
1274 if (ptrace(T_SYSCALL, wpid, 0, 0) != 0) my_e(14);
1278 /* The parent should get an odd number of traps: the first one is a syscall
1279 * enter trap (typically for the fork()), the last one is the syscall enter
1280 * trap for its exit().
1282 if (ptraps < 3) my_e(15);
1283 if (!(ptraps % 2)) my_e(16);
1285 /* The child should get an even number of traps: the first one is a syscall
1286 * leave trap from the fork(), the last one is the syscall enter trap for
1287 * its exit().
1289 if (ctraps < 2) my_e(17);
1290 if (ctraps % 2) my_e(18);
1292 traced_wait();
1295 void sigexec(setflag, opt, traps, stop)
1296 int setflag;
1297 int opt;
1298 int *traps;
1299 int *stop;
1301 pid_t pid;
1302 int r, status;
1304 pid = traced_fork(test_exec_child);
1306 if (kill(pid, SIGSTOP) != 0) my_e(1);
1308 if (waitpid(pid, &status, 0) != pid) my_e(2);
1309 if (!_WIFSTOPPED(status)) my_e(3);
1310 if (WSTOPSIG(status) != SIGSTOP) my_e(4);
1312 if (setflag && ptrace(T_SETOPT, pid, 0, opt) != 0) my_e(5);
1314 WRITE(0);
1316 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(6);
1318 *traps = 0;
1319 *stop = -1;
1321 for (;;) {
1322 if (waitpid(pid, &status, 0) != pid) my_e(7);
1324 if (_WIFEXITED(status)) break;
1326 if (!_WIFSTOPPED(status)) my_e(8);
1328 switch (WSTOPSIG(status)) {
1329 case SIGTRAP:
1330 (*traps)++;
1331 break;
1332 case SIGSTOP:
1333 if (*stop >= 0) my_e(9);
1334 *stop = *traps;
1335 break;
1336 default:
1337 my_e(10);
1340 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(11);
1343 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1345 traced_wait();
1348 void test_trapexec()
1350 int traps, stop;
1352 subtest = 15;
1354 sigexec(1, 0, &traps, &stop);
1356 /* The exec does not cause a SIGSTOP. This gives us an even number of traps;
1357 * as above, but plus the exec()'s extra SIGTRAP. This trap is
1358 * indistinguishable from a syscall trap, especially when considering failed
1359 * exec() calls and immediately following signal handler invocations.
1361 if (traps < 4) my_e(12);
1362 if (traps % 2) my_e(13);
1363 if (stop >= 0) my_e(14);
1366 void test_altexec()
1368 int traps, stop;
1370 subtest = 16;
1372 sigexec(1, TO_ALTEXEC, &traps, &stop);
1374 /* The exec causes a SIGSTOP. This gives us an odd number of traps: a pair
1375 * for each system call, plus one for the final exit(). The stop must have
1376 * taken place after a syscall enter event, i.e. must be odd as well.
1378 if (traps < 3) my_e(12);
1379 if (!(traps % 2)) my_e(13);
1380 if (stop < 0) my_e(14);
1381 if (!(stop % 2)) my_e(15);
1384 void test_noexec()
1386 int traps, stop;
1388 subtest = 17;
1390 sigexec(1, TO_NOEXEC, &traps, &stop);
1392 /* The exec causes no signal at all. As above, but without the SIGSTOPs. */
1393 if (traps < 3) my_e(12);
1394 if (!(traps % 2)) my_e(13);
1395 if (stop >= 0) my_e(14);
1398 void test_defexec()
1400 int traps, stop;
1402 /* We want to test the default of T_OK (0) and T_ATTACH (TO_NOEXEC). */
1403 if (attach != 0 && attach != 1) return;
1405 subtest = 18;
1407 /* Do not set any options this time. */
1408 sigexec(0, 0, &traps, &stop);
1410 /* See above. */
1411 if (attach == 0) {
1412 if (traps < 4) my_e(12);
1413 if (traps % 2) my_e(13);
1414 if (stop >= 0) my_e(14);
1416 else {
1417 if (traps < 3) my_e(15);
1418 if (!(traps % 2)) my_e(16);
1419 if (stop >= 0) my_e(17);
1423 void test_reattach_child()
1425 struct timeval tv;
1427 if (READ() != 0) my_e(100);
1429 tv.tv_sec = 2;
1430 tv.tv_usec = 0;
1431 if (select(0, NULL, NULL, NULL, &tv) != 0) my_e(101);
1433 exit(42);
1436 void test_reattach()
1438 pid_t pid;
1439 int r, status, count;
1441 subtest = 19;
1443 pid = traced_fork(test_reattach_child);
1445 if (kill(pid, SIGSTOP) != 0) my_e(1);
1447 if (waitpid(pid, &status, 0) != pid) my_e(2);
1448 if (!_WIFSTOPPED(status)) my_e(3);
1449 if (WSTOPSIG(status) != SIGSTOP) my_e(4);
1451 WRITE(0);
1453 signal(SIGALRM, dummy_handler);
1454 alarm(1);
1456 /* Start tracing system calls. We don't know how many there will be until
1457 * we reach the child's select(), so we have to interrupt ourselves.
1458 * The hard assumption here is that the child is able to enter the select()
1459 * within a second, despite being traced. If this is not the case, the test
1460 * may hang or fail, and the child may die from a SIGTRAP.
1462 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(5);
1464 for (count = 0; (r = waitpid(pid, &status, 0)) == pid; count++) {
1465 if (!_WIFSTOPPED(status)) my_e(6);
1466 if (WSTOPSIG(status) != SIGTRAP) my_e(7);
1468 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(8);
1471 if (r != -1 || errno != EINTR) my_e(9);
1473 /* We always start with syscall enter event; the last event we should have
1474 * seen before the alarm was entering the select() call.
1476 if (!(count % 2)) my_e(10);
1478 /* Detach, and immediately attach again. */
1479 detach_running(pid);
1481 if (ptrace(T_ATTACH, pid, 0, 0) != 0) my_e(11);
1483 if (waitpid(pid, &status, 0) != pid) my_e(12);
1484 if (!_WIFSTOPPED(status)) my_e(13);
1485 if (WSTOPSIG(status) != SIGSTOP) my_e(14);
1487 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(15);
1489 if (waitpid(pid, &status, 0) != pid) my_e(16);
1491 for (count = 0; _WIFSTOPPED(status); count++) {
1492 if (WSTOPSIG(status) != SIGTRAP) my_e(17);
1494 if (ptrace(T_SYSCALL, pid, 0, 0) != 0) my_e(18);
1496 if (waitpid(pid, &status, 0) != pid) my_e(19);
1499 if (!_WIFEXITED(status)) my_e(20);
1500 if ((r = WEXITSTATUS(status)) != 42) my_e(r);
1502 /* We must not have seen the select()'s syscall leave event, and the last
1503 * event will be the syscall enter for the exit().
1505 if (!(count % 2)) my_e(21);
1507 traced_wait();