3

我正在开发一个需要Linux 上所有执行进程的调用堆栈的应用程序。我正在尝试使用 ptrace 但无法继续使用它,因为我需要在代码中遵循的步骤对我来说并不清楚。

我也尝试过回溯,但它的使用仅限于当前进程。

有人可以指导我吗?

谢谢,桑迪普

4

2 回答 2

2

看一下 pstack 代码。pstack 在 ubuntu lucid 上可用。

于 2010-11-02T23:37:37.487 回答
0

此代码取自 ptrace 的 HP UX 手册页。希望这是有用的。

以下示例说明了跟踪进程对某些 ptrace() 调用的使用

 #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;
        }
    }
于 2010-04-01T10:04:47.550 回答