summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry V. Levin <ldv@altlinux.org>2011-02-19 21:33:50 +0000
committerDmitry V. Levin <ldv@altlinux.org>2011-02-19 21:33:50 +0000
commit007e003e3a687761f1cb71dfb0e77737429b2e2c (patch)
treef4664ec4f1a8f2bae4c5d66ac105d2d119814f0c
parente44a4a262ab1d47815262a6bb03ba6001c79096a (diff)
downloadstrace-ldv/PTRACE_GETEVENTMSG.tar.gz
Fix PTRACE_GETEVENTMSG usage and enhance test_ptrace_setoptions()ldv/PTRACE_GETEVENTMSG
* strace.c (handle_ptrace_event): Fix PTRACE_GETEVENTMSG usage. (test_ptrace_setoptions): Test that PTRACE_GETEVENTMSG works properly.
-rw-r--r--strace.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/strace.c b/strace.c
index 6b0ebacf7..89fda4f09 100644
--- a/strace.c
+++ b/strace.c
@@ -696,7 +696,10 @@ startup_child (char **argv)
static int
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)
return -1;
@@ -720,29 +723,37 @@ test_ptrace_setoptions(void)
return -1;
}
if (tracee_pid != pid) {
- /* the grandchild */
+ found_grandchild = tracee_pid;
if (ptrace(PTRACE_CONT, tracee_pid, 0, 0) < 0 &&
errno != ESRCH)
kill(tracee_pid, SIGKILL);
}
else if (WIFSTOPPED(status)) {
- const unsigned int test_options = PTRACE_O_TRACECLONE |
- PTRACE_O_TRACEFORK |
- PTRACE_O_TRACEVFORK;
- if (status >> 16 == PTRACE_EVENT_FORK)
- ptrace_setoptions |= test_options;
- if (WSTOPSIG(status) == SIGSTOP) {
- if (ptrace(PTRACE_SETOPTIONS, pid, NULL,
- test_options) < 0) {
+ switch (WSTOPSIG(status)) {
+ case SIGSTOP:
+ if (ptrace(PTRACE_SETOPTIONS, pid,
+ NULL, test_options) < 0) {
kill(pid, SIGKILL);
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 &&
errno != ESRCH)
kill(pid, SIGKILL);
}
}
+ if (expected_grandchild && expected_grandchild == found_grandchild)
+ ptrace_setoptions |= test_options;
return 0;
}
#endif
@@ -2365,7 +2376,7 @@ handle_ptrace_event(int status, struct tcb *tcp)
if (status >> 16 == PTRACE_EVENT_VFORK ||
status >> 16 == PTRACE_EVENT_CLONE ||
status >> 16 == PTRACE_EVENT_FORK) {
- int childpid;
+ long childpid;
if (do_ptrace(PTRACE_GETEVENTMSG, tcp, NULL, &childpid) < 0) {
if (errno != ESRCH) {