2010-04-01 22 views
2

Je travaille sur une application qui nécessite une pile d'appel de tous les processus d'exécution sous Linux. J'essaie d'utiliser ptrace mais pas en mesure d'aller de l'avant car les étapes je dois suivre dans mon code ne sont pas claires pour moi.Comment utiliser Ptrace sur Linux pour imprimer la pile d'appels d'autres processus de C++

J'ai également essayé backtrace, mais son utilisation est limitée au processus actuel.

quelqu'un pourrait me guider sur le même.

Merci, Sandeep

Répondre

0

Ce code est tiré de la page de manuel HP UX de ptrace. J'espère que c'est utile.

L'exemple suivant illustre l'utilisation de certains des ptrace() appels par un processus de traçage.

#include <stdio.h> 
#include <signal.h> 
#include <sys/wait.h> 
#include <sys/ptrace.h> 
#define BUFSIZ 1024 
#define MAXPATH 1024 

pid_t   npid, cpid, pid; 
int    status, errors=0, pathlength; 
ptrace_event_t *event_addr; 
ptrace_state_t *state_addr; 
char   *buf_addr; 
size_t   event_len, state_len; 
int    filed[2]; 

child() 
{ 
    int n, bar; 

    close(filed[1]); 
    /* Wait for parent to write to pipe */ 
    while ((n = read(filed[0], &bar, BUFSIZ)) == 0); 

    /* Now the child can exec. */ 
    if (execlp("ls", "ls", (char *)0) < 0) /* error during exec */ 
      printf("Child: exec failed\n"); 
    exit(0); 
} 

parent() 
{ 
    close(filed[0]); 

    /* Before child does an exec, attach it and set its event flag. */ 
    if (ptrace(PT_ATTACH,pid)) /* failed to attach process */ 
     printf("Parent: Failed to attach child\n"); 
    if (pid != wait(&status)) /* wait failed */ 
     printf("Parent: attach failed with wrong wait status\n"); 
    if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) 
     printf("Parent: SIGTRAP didn't stop child\n"); 

    /* 
     * The child process has now stopped. Set its event flag indicating 
     * that it needs to trigger on a PTRACE_EXEC event. 
     */ 
    event_addr->pe_set_event = PTRACE_EXEC; 
    if (ptrace(PT_SET_EVENT_MASK, pid, event_addr, event_len)) 
     printf("Parent: PT_SET_EVENT_MASK ptrace request failed\n"); 
    if (pid != wait(&status)) /* wait failed */ 
     printf("Parent: wait() failed with wrong wait status\n"); 

    /* 
     * Send the child a message so it can break out of the while loop. 
     * Get it running so it can exec. 
     */ 
    write(filed[1], "now run", 7); 
    if (ptrace(PT_CONTIN, pid, 1, 0) != 0) 
     printf("Parent: failed to get child process running\n"); 
    /* 
     * Wait for the traced child to stop after the exec system call in 
     * response to an exec event set in its ptrace_event structure. 
     */ 
    if (pid != (npid = wait(&status))) /* wait failed */ 
     printf("Parent: wait() failed with wrong status\n"); 
    if (!WIFSTOPPED(status)) 
     printf("Parent: invalid wait() completion\n"); 

    /* 
    * Child has stopped; fetch its process state and examine state 
    * information. 
    */ 
    if (ptrace(PT_GET_PROCESS_STATE, pid, state_addr, state_len) < 0) 
     printf("Parent: PT_GET_PROCESS_STATE ptrace request failed\n"); 
    if (pid != wait(&status)) /* wait failed */ 
     printf("Parent: wait() failed with wrong wait status\n"); 

    /* Check if the pathlength value returned is non-zero */ 
    if ((pathlength = state_addr->pe_path_len) == 0) 

      printf("Parent: zero length pathname returned\n"); 

     /* Fetch exec'd file pathname and store it in the buffer. */ 
     if (ptrace(PT_GET_PROCESS_PATHNAME, pid, buf_addr, (pathlength+1)) 
      < 0){ 
      printf("Parent: Failed to get exec pathname\n"); 
     } else { 
      printf("Parent: the exec pathname is %s\n", buf_addr); 
      if (pid != wait(&status)) /* wait failed */ 
       printf("Parent: wait() failed with wrong status\n"); 
     } 
    } 

    main() 
    { 
     event_len = sizeof(ptrace_event_t); 
     state_len = sizeof(ptrace_state_t); 
     event_addr = calloc(event_len, 1); 
     state_addr = calloc(state_len, 1); 
     buf_addr = calloc(MAXPATH, 1); 
     pipe(filed); 
     switch (pid = fork()) { 
      case -1: 
       exit(1); 
      case 0: 
       child(); 
       break; 
      default: 
       parent(); 
       break; 
     } 
    } 
+1

Merci pour votre réponse, mais je ne suis pas capable de compiler mon code sur Linux car je ne vois pas d'en-tête pour ptrace_event_t. –

+0

yup, ne peut trouver aucune référence à cela dans le manuel soit – hoymkot

2

Jetez un oeil au code pstack. pstack est disponible sur ubuntu lucid.

+0

source est ici https://launchpad.net/ubuntu/+source/pstack – osgx

+0

ou ici http://packages.debian.org/source/sid/ pstack – osgx