| 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
|