I couldn't trace fork / exec events when I attached to another process, the status
returned from waitpid was always zero (after right shift of 16 times).
I've successfully attached to bash shell, but whatever commands I ran, the status was always zero, so I didn't catch any fork or exec events:
#define PALL PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE \
| PTRACE_O_TRACEEXEC | PTRACE_O_TRACEVFORKDONE | PTRACE_O_TRACEEXIT
int main(int argc, char **argv)
{
pid_t child = 0;
int status = 0;
if (argc != 2) { ... }
child = atoi (argv[1]);
if (ptrace (PTRACE_ATTACH, child, 0, 0) < 0) { ... }
ptrace(PTRACE_SETOPTIONS, child, NULL, PALL);
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
ptrace(PTRACE_CONT, child, NULL, NULL);
while(1) {
waitpid(child, &status, 0);
if(WIFEXITED(status))
break;
status >>= 16;
if (status != 0)
printf ("Status: %d\n", status >> 16);
ptrace(PTRACE_SYSCALL, child, NULL, NULL);
}
ptrace(PTRACE_DETACH, child, NULL, NULL);
return 0;
}
You shifted the
status
bits not 16, but 32 times by doingstatus >>= 16
first and thenprintf (…, status >> 16);
so always0
was printed. Also there are some less obvious flaws:WIFSIGNALED
.wait
for and process them as well.PTRACE_SYSCALL
immediately precedingPTRACE_CONT
doesn't make sense.PTRACE_SETOPTIONS
may fail ifPTRACE_ATTACH
has not yet completed, thus we mustwait
.Considering all this, the program could look like