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:
parent
330a895bbd
commit
2fabd0eaf0
33
strace.c
33
strace.c
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user