帖子末尾的代码是该问题的一个答案。
您可以拥有一个跟踪进程的线程。 
如果有人感兴趣,我正在试验的问题是,由于一些难以理解的原因,跟踪线程并不是发送所有跟踪命令的线程。其中一个负责调用fork并负责trace,另一个负责发送
- ptrace(PTRACE_CONT, childPID, 0, 0);
- ptrace(PTRACE_GETREGS,childPID,0,寄存器);
结果错误是: ptrace (PTRACE_GETREGS,..) 无法获取寄存器:没有这样的过程
#include <pthread.h>
#include <sys/ptrace.h>    
#include <sys/wait.h>    
#include <stdlib.h>    
#include <stdio.h>    
#include <unistd.h>    
#include <sys/reg.h>    
#include <sys/user.h>
#define NUM_THREADS    9
int childPID;    
int fatherPID;    
void print_registers(struct user_regs_struct *registers){        
   printf("\tReg ebx 0x%lx\n",registers->ebx);    
   printf("\tReg ecx 0x%lx\n",registers->ecx);    
   printf("\tReg edx 0x%lx\n",registers->edx);    
   printf("\tReg esi 0x%lx\n",registers->esi);    
   printf("\tReg edi 0x%lx\n",registers->edi);    
   printf("\tReg ebp 0x%lx\n",registers->ebp);   
   printf("\tReg eax 0x%lx\n",registers->eax);    
   printf("\tReg xds 0x%lx\n",registers->xds);   
   printf("\tReg xes 0x%lx\n",registers->xes);    
   printf("\tReg xfs 0x%lx\n",registers->xfs);    
   printf("\tReg xgs 0x%lx\n",registers->xgs);    
   printf("\tReg orig_eax 0x%lx\n",registers->orig_eax);    
   printf("\tReg eip 0x%lx\n",registers->eip);    
   printf("\tReg xcs 0x%lx\n",registers->xcs);    
   printf("\tReg eflags 0x%lx\n",registers->eflags);    
   printf("\tReg esp 0x%lx\n",registers->esp);    
   printf("\tReg xss 0x%lx\n",registers->xss);    
}
int load(char * execPath){    
   switch( childPID=fork() ){    
      case -1:       
         perror("fork()");    
         return -1;    
      case 0 :    
         if( access(execPath, X_OK)==-1){    
            printf("\tAcces denied to\n",execPath);    
         }    
         else {    
            printf("\tChild Process pid :%d %d\n",childPID,getpid());            
            if(ptrace(PTRACE_TRACEME, 0, NULL, NULL)<0){    
               perror("ptrace(PTRACE_TRACEME)");    
            return -1;    
            }            
            execve(execPath,NULL,NULL);    
            perror("execve()");    
         }    
         return -1;    
      default:    
         wait(NULL);    
         fatherPID=getpid();    
         printf("\tParent Process pid :%d  %d\n",fatherPID,childPID);    
         if (ptrace(PTRACE_SETOPTIONS, childPID, 0, PTRACE_O_TRACEEXIT)){    
            perror("stopper: ptrace(PTRACE_SETOPTIONS, ...)");    
            return -1;   
         }   
         break;   
   }    
   return -1;    
}
void registers(){    
   printf("\t@@Command get_registers@\n");    
   struct user_regs_struct * registers = (struct user_regs_struct*)(calloc(1, sizeof(struct user_regs_struct)));    
   long ret = ptrace (PTRACE_GETREGS, childPID, 0,  registers);    
   if (ret <0) perror("ptrace (PTRACE_GETREGS,..) Couldn't get registers");     
   print_registers(registers);    
   free(registers);
}  
int continuE(){  
   int status = 0;    
   int signo;    
   long long_var=0;    
   // to continue the execution is needed to trigger the event                       
   while (1) {    
      ptrace(PTRACE_CONT, childPID, 0, 0);    
      waitpid( childPID, &status, 0);    
      if (WIFEXITED(status))    
            printf("Child exited by %d\n",WEXITSTATUS(status));    
        if (WIFSIGNALED(status))
         printf(" child process terminated by a signal %d \n",WTERMSIG(status) );
        if (WIFSTOPPED(status)) {    
         signo = WSTOPSIG(status);    
         //printf("Child stopped by %d\n",signo);    
        }        
        // we had the sigtrap and we are at the exec    
      if (status>>8 == (SIGTRAP | (PTRACE_EVENT_EXEC<<8))){    
         printf("\t###Stopped the tracee at EXEC, with status %d###\n",WEXITSTATUS(status));    
         ptrace(PTRACE_GETEVENTMSG, childPID,0,&long_var);    
         printf("\t###PTRACE_GETEVENTMSG result %lu ,%d ###\n",long_var,WEXITSTATUS(long_var));     
      }    
      // we have a sigtrap and we are on the exit    
      // we could think to take out PTRACE_O_TRACEEXIT    
      if (status>>8 == (SIGTRAP | (PTRACE_EVENT_EXIT<<8))){   
         printf("\t###Stopped the tracee at EXIT###\n");    
         signo= SIGHUP;    
      }
      // normal cases   
        if ((signo == SIGTRAP) || (signo == SIGTERM) ||(signo ==SIGINT) || (signo == SIGHUP)    
        || ( signo == SIGSEGV) ){    
         break;    
        }    
   }        
   return signo;    
}
void *work(void *threadid)    
{    
   long tid;    
   tid = (long)threadid;    
   printf("Hello World! It's me, thread #%ld!\n", tid);    
   load("/home/rtems/plibeagleeye/Plib/Tests/bin/stanford.o");    
   registers();    
   continuE();    
   registers();
   pthread_exit(NULL);    
}
void *work2(void *threadid)    
{    
   long tid;    
   tid = (long)threadid;   
   printf("Hello World! It's me, thread #%ld!\n", tid);            
   pthread_exit(NULL);    
}
int main (int argc, char *argv[])    
{    
   pthread_t threads[NUM_THREADS];    
   pthread_attr_t attr;    
   int rc;    
   long *taskids;    
   void *status;    
   taskids = (long *) malloc( NUM_THREADS * sizeof(long));    
   long t=0;        
   /* Initialize and set thread detached attribute */
   pthread_attr_init(&attr);    
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);   
   taskids[t] = 0;    
   rc = pthread_create(&threads[t], &attr, work, (void *)taskids[t]);
   for(t=1; t<NUM_THREADS; t++){    
      taskids[t] = t;    
      printf("Creating thread %ld\n", t);
      rc = pthread_create(&threads[t], &attr, work2, (void *)taskids[t]);
      if (rc){    
         printf("ERROR; return code from pthread_create() is %d\n", rc);    
         exit(-1);    
      }    
   }      
   pthread_attr_destroy(&attr);
   for(t=0; t<NUM_THREADS; t++){
      rc = pthread_join(threads[t], &status);
      if (rc) {    
         printf("ERROR; return code from pthread_join()  is %d\n", rc);
         exit(-1);
         }
      printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status);
   }
   printf("Ciaoz all threads finished their jobs\n");
   free(taskids);
   /* Last thing that main() should do */
   pthread_exit(NULL);
   return 0;
}
真正让我惊讶的是,没有迹象表明哪个线程是示踪剂。ptrace(PTRACE_TRACEME, 0, NULL, NULL) 0 似乎工作得很好。