Fix PTRACE_GETEVENTMSG usage and enhance test_ptrace_setoptions()

* strace.c (handle_ptrace_event): Fix PTRACE_GETEVENTMSG usage.
(test_ptrace_setoptions): Test that PTRACE_GETEVENTMSG works properly.
This commit is contained in:
Дмитрий Левин 2011-02-19 21:33:50 +00:00
parent 330a895bbd
commit 2fabd0eaf0

View File

@ -696,7 +696,10 @@ startup_child (char **argv)
static int static int
test_ptrace_setoptions(void) test_ptrace_setoptions(void)
{ {
int pid; int pid, expected_grandchild = 0, found_grandchild = 0;
const unsigned int test_options = PTRACE_O_TRACECLONE |
PTRACE_O_TRACEFORK |
PTRACE_O_TRACEVFORK;
if ((pid = fork()) < 0) if ((pid = fork()) < 0)
return -1; return -1;
@ -720,29 +723,37 @@ test_ptrace_setoptions(void)
return -1; return -1;
} }
if (tracee_pid != pid) { if (tracee_pid != pid) {
/* the grandchild */ found_grandchild = tracee_pid;
if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0 && if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0 &&
errno != ESRCH) errno != ESRCH)
kill(tracee_pid, SIGKILL); kill(tracee_pid, SIGKILL);
} }
else if (WIFSTOPPED(status)) { else if (WIFSTOPPED(status)) {
const unsigned int test_options = PTRACE_O_TRACECLONE | switch (WSTOPSIG(status)) {
PTRACE_O_TRACEFORK | case SIGSTOP:
PTRACE_O_TRACEVFORK; if (ptrace(PTRACE_SETOPTIONS, pid,
if (status >> 16 == PTRACE_EVENT_FORK) NULL, test_options) < 0) {
ptrace_setoptions |= test_options;
if (WSTOPSIG(status) == SIGSTOP) {
if (ptrace(PTRACE_SETOPTIONS, pid, NULL,
test_options) < 0) {
kill(pid, SIGKILL); kill(pid, SIGKILL);
return -1; return -1;
} }
break;
case SIGTRAP:
if (status >> 16 == PTRACE_EVENT_FORK) {
long msg = 0;
if (ptrace(PTRACE_GETEVENTMSG, pid,
NULL, (long) &msg) == 0)
expected_grandchild = msg;
}
break;
} }
if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0 && if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0 &&
errno != ESRCH) errno != ESRCH)
kill(pid, SIGKILL); kill(pid, SIGKILL);
} }
} }
if (expected_grandchild && expected_grandchild == found_grandchild)
ptrace_setoptions |= test_options;
return 0; return 0;
} }
#endif #endif
@ -2365,7 +2376,7 @@ handle_ptrace_event(int status, struct tcb *tcp)
if (status >> 16 == PTRACE_EVENT_VFORK || if (status >> 16 == PTRACE_EVENT_VFORK ||
status >> 16 == PTRACE_EVENT_CLONE || status >> 16 == PTRACE_EVENT_CLONE ||
status >> 16 == PTRACE_EVENT_FORK) { status >> 16 == PTRACE_EVENT_FORK) {
int childpid; long childpid;
if (do_ptrace(PTRACE_GETEVENTMSG, tcp, NULL, &childpid) < 0) { if (do_ptrace(PTRACE_GETEVENTMSG, tcp, NULL, &childpid) < 0) {
if (errno != ESRCH) { if (errno != ESRCH) {