For Programmers: Free Programming Magazines  


Home > Archive > Unix Programming > January 2008 > How to trace a process with ptrace when it forks a new process ?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author How to trace a process with ptrace when it forks a new process ?
Zheng Da

2008-01-22, 7:27 pm

Hello,

I'm programming in the Linux.
Basically, what I want to do is:
to trace a process,
to trace its child too, if the process forks a child,
and so on.
So first I have to find where the child process calls fork()(or vfork()
or clone()).
I want to use PTRACE_SETOPTIONS and set PTRACE_O_TRACEFORK option.
As my understanding, the traced process should be stopped by SIGTRAP
when it calls fork(), and the tracer should get the control of it, and
get its status with wait().
Unfortunately, ptrace() doesn't work as I thought.
So I wonder how I use ptrace() to do it.
My test code is below, and I want to use "tracer" to trace "traced".
Can anyone tell me which part is wrong?


---------------tracer.c----------------
#include <stdio.h>
#include <string.h>
#include <sys/ptrace.h>
#include <linux/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <asm-i486/ptrace.h> /* For constants
ORIG_EAX etc */
int main(int argc , char *argv[])
{
pid_t child;

if(argc != 2){
fprintf(stderr , "usage: %s program\n" , argv[0]);
return 1;
}

child = fork();
if(child == 0) {
sleep(1);
execl(argv[1] , argv[1] , NULL);
}
else {
int status;
long data=PTRACE_O_TRACEEXIT
|PTRACE_O_TRACEFORK
|PTRACE_O_TRACEVFORK
|PTRACE_O_TRACECLONE;

ptrace(PTRACE_ATTACH , child , NULL , NULL);
ptrace(PTRACE_SETOPTIONS , child , NULL , data);
while(1){
if(wait(&status) == -1){
perror("wait");
return 0;
}
printf("the child process stops. status: %d, signal? %d, "
"exit? %d, continue? %d, stop? %d\n" ,
WEXITSTATUS(status) , WIFSIGNALED(status) ,
WIFEXITED(status) , WIFCONTINUED(status) ,
WIFSTOPPED(status));
if(WSTOPSIG(status) == SIGTRAP){
if(status & (PTRACE_EVENT_EXIT << 8)){
printf("get the child process while it's exiting\n");
break;
}
else if(status & (PTRACE_EVENT_FORK << 8)){
printf("the child process fork a new process\n");
}
else if(status & (PTRACE_EVENT_VFORK << 8)){
printf("the child process vfork a new process\n");
}
else if(status & (PTRACE_EVENT_CLONE << 8)){
printf("the child process clone a new process\n");
}
}
if (ptrace(PTRACE_CONT, child, 0, /*WSTOPSIG(status)*/SIGSTOP)) {
perror("stopper: ptrace(PTRACE_CONT, ...)");
return 1;
}
}
if (ptrace(PTRACE_CONT, child, 0, 0)) {
perror("stopper: ptrace(PTRACE_CONT, ...)");
return 1;
}
}
return 0;
}


-----------------traced.c---------------------
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
pid_t child=fork();
if(child){
printf("create a child %d\n" , child);
sleep(1);
}
else{
printf("I'm a child\n");
sleep(1);
}
}

best,
Zheng Da

--
Posted via a free Usenet account from http://www.teranews.com

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com