1 /* Tests for MINIX3 ptrace(2) - by D.C. van Moolenbroek */
2 #define _POSIX_SOURCE 1
11 #include <sys/select.h>
12 #include <sys/ptrace.h>
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
);
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);
40 void test_exec_child(void);
42 void test_step_child(void);
44 void test_sig_child(void);
46 void test_exit_child(void);
48 void test_term_child(void);
50 void test_catch_child(void);
51 void test_catch(void);
52 void test_kill_child(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);
75 static char *executable
;
76 static int child
= 0, attach
;
79 static int sigs
, caught
;
85 int i
, m
= 0xFFFFFF, n
= 0xF;
86 char cp_cmd
[NAME_MAX
+ 10];
88 if (strcmp(argv
[0], "DO CHECK") == 0) {
96 snprintf(cp_cmd
, sizeof(cp_cmd
), "cp ../%s .", executable
);
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);
110 return(-1); /* impossible */
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);
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; }
162 /* report timeout as error */
163 printf("timeout in %s\n", s
);
174 if (pipe(pfd
) != 0) my_e(200);
175 if (pipe(&pfd
[2]) != 0) my_e(201);
178 case 0: /* let child volunteer to be traced */
181 if (pid
< 0) my_e(202);
186 if (ptrace(T_OK
, 0, 0, 0) != 0) my_e(203);
195 if (READ() != 0) my_e(205);
199 case 1: /* attach to child process */
202 if (pid
< 0) my_e(206);
207 if (READ() != 0) my_e(207);
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);
226 case 2: /* attach to non-child process */
229 if (ppid
< 0) my_e(214);
234 if (pid
< 0) exit(215);
239 if (READ() != 0) my_e(216);
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
);
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);
271 case 3: /* attach by forking from child */
274 if (ppid
< 0) my_e(225);
279 if (ptrace(T_OK
, 0, 0, 0) != 0) my_e(226);
283 if (READ() != 0) my_e(227);
287 if (pid
< 0) my_e(228);
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
);
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);
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
);
335 pid_t
traced_pfork(c
)
340 if (pipe(pfd
) != 0) my_e(300);
341 if (pipe(&pfd
[2]) != 0) my_e(301);
345 if (pid
< 0) my_e(302);
361 if (write(pfd
[child
*2+1], &value
, sizeof(value
)) != sizeof(value
)) my_e(400);
368 if (read(pfd
[2-child
*2], &value
, sizeof(value
)) != sizeof(value
)) my_e(401);
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
);
383 /* Quick hack to clean up detached children */
384 waitpid(-1, NULL
, WNOHANG
);
393 void detach_running(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
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);
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. */
431 void dummy_handler(sig
)
436 void exit_handler(sig
)
442 void count_handler(sig
)
448 void catch_handler(sig
)
455 case SIGUSR1
: bit
= 1; break;
456 case SIGUSR2
: bit
= 2; break;
457 case SIGTERM
: bit
= 4; break;
462 sigprocmask(SIG_SETMASK
, &set
, NULL
);
464 if (caught
& bit
) my_e(101);
468 void test_wait_child()
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);
489 void test_exec_child()
491 if (READ() != 0) my_e(100);
493 execl(executable
, "DO CHECK", NULL
);
503 /* This test covers the T_OK case. */
504 if (attach
!= 0) return;
508 pid
= traced_fork(test_exec_child
);
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
);
526 void test_step_child()
530 signal(SIGUSR1
, SIG_IGN
);
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
);
539 sigprocmask(SIG_SETMASK
, &set
, NULL
);
547 int r
, status
, count
;
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);
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 */
586 void test_sig_child()
588 signal(SIGUSR1
, exit_handler
);
590 if (READ() != 0) my_e(100);
604 pid
= traced_fork(test_sig_child
);
608 /* allow the child to enter the pause */
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 */
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);
667 void test_exit_child()
681 pid
= traced_fork(test_exit_child
);
683 if (READ() != 0) my_e(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
);
706 void test_term_child()
708 signal(SIGUSR1
, SIG_DFL
);
709 signal(SIGUSR2
, dummy_handler
);
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);
755 void test_catch_child()
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
);
769 sigprocmask(SIG_SETMASK
, &set
, &oset
);
775 while (caught
!= 7) sigsuspend(&oset
);
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
);
833 void test_kill_child()
837 signal(SIGKILL
, SIG_IGN
);
839 sigprocmask(SIG_SETMASK
, &set
, NULL
);
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);
873 void test_attach_child()
875 if (ptrace(T_OK
, 0, 0, 0) != -1) my_e(100);
876 if (errno
!= EBUSY
) my_e(101);
880 if (READ() != 0) my_e(102);
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. */
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);
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);
925 void test_detach_child()
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
);
939 sigprocmask(SIG_SETMASK
, &set
, &oset
);
942 sigdelset(&sset
, SIGUSR1
);
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
);
965 /* Can't use traced_fork(), so simplify a bit */
966 if (attach
!= 0) return;
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);
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
);
1006 void test_death_child()
1012 if (pid
< 0) my_e(100);
1015 ptrace(T_OK
, 0, 0, 0);
1022 if (READ() != 0) my_e(101);
1024 kill(getpid(), SIGKILL
);
1036 pid
= traced_fork(test_death_child
);
1040 if (kill(cpid
, 0) != 0) my_e(1);
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);
1055 void test_zdeath_child()
1057 if (READ() != 0) my_e(100);
1067 /* Can't use traced_fork(), so simplify a bit */
1068 if (attach
!= 0) return;
1072 pid
= traced_pfork(test_zdeath_child
);
1076 if (tpid
< 0) my_e(1);
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);
1089 /* Unwaited-for traced zombies should be passed to their parent. */
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
);
1111 void test_syscall_child()
1113 signal(SIGUSR1
, count_handler
);
1114 signal(SIGUSR2
, count_handler
);
1120 if (READ() != 0) my_e(100);
1122 /* Three calls (may fail) */
1127 if (sigs
!= 2) my_e(101);
1135 int i
, r
, sig
, status
;
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);
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
;
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);
1181 void test_tracefork_child()
1185 signal(SIGHUP
, SIG_IGN
);
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
;
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);
1219 if (ptrace(T_SYSCALL
, ppid
, 0, 0) != 0) my_e(7);
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
) {
1233 if (wpid
!= ppid
&& wpid
!= cpid
) my_e(9);
1235 if (_WIFEXITED(status
)) {
1237 if ((r
= WEXITSTATUS(status
)) != 42) my_e(r
);
1241 if ((r
= WEXITSTATUS(status
)) != 84) my_e(r
);
1246 if (!_WIFSTOPPED(status
)) my_e(10);
1248 switch (WSTOPSIG(status
)) {
1253 if (wpid
!= cpid
) my_e(11);
1254 if (gotstop
) my_e(12);
1258 if (wpid
== ppid
) ptraps
++;
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
1280 if (ctraps
< 2) my_e(17);
1281 if (ctraps
% 2) my_e(18);
1286 void sigexec(setflag
, opt
, traps
, stop
)
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);
1307 if (ptrace(T_SYSCALL
, pid
, 0, 0) != 0) my_e(6);
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
)) {
1324 if (*stop
>= 0) my_e(9);
1331 if (ptrace(T_SYSCALL
, pid
, 0, 0) != 0) my_e(11);
1334 if ((r
= WEXITSTATUS(status
)) != 42) my_e(r
);
1339 void test_trapexec()
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);
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);
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);
1393 /* We want to test the default of T_OK (0) and T_ATTACH (TO_NOEXEC). */
1394 if (attach
!= 0 && attach
!= 1) return;
1398 /* Do not set any options this time. */
1399 sigexec(0, 0, &traps
, &stop
);
1403 if (traps
< 4) my_e(12);
1404 if (traps
% 2) my_e(13);
1405 if (stop
>= 0) my_e(14);
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()
1418 if (READ() != 0) my_e(100);
1422 if (select(0, NULL
, NULL
, NULL
, &tv
) != 0) my_e(101);
1427 void test_reattach()
1430 int r
, status
, count
;
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);
1444 signal(SIGALRM
, dummy_handler
);
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);
1507 printf("Attach type %d, ", attach
);