How to trace a process for system calls?

后端 未结 4 747
醉话见心
醉话见心 2021-02-04 20:03

I am trying to code a program that traces itself for system calls. I am having a difficult time making this work. I tried calling a fork() to create an instance of itself (the c

4条回答
  •  不要未来只要你来
    2021-02-04 20:40

    The problem is that when the child calls ptrace(TRACEME) it sets itself up for tracing but doesn't actually stop -- it keeps going until it calls exec (in which case it stops with a SIGTRAP), or it gets some other signal. So in order for you to have the parent see what it does WITHOUT an exec call, you need to arrange for the child to receive a signal. The easiest way to do that is probably to have the child call raise(SIGCONT); (or any other signal) immediately after calling ptrace(TRACEME)

    Now in the parent you just wait (once) and assume that the child is now stopped at a system call. This won't be the case if it stopped at a signal, so you instead need to call wait(&status) to get the child status and call WIFSTOPPED(status) and WSTOPSIG(status) to see WHY it has stopped. If it has stopped due to a syscall, the signal will be SIGTRAP.

    If you want to see multiple system calls in the client, you'll need to do all of this in a loop; something like:

    while(1) {
        wait(&status);
        if (WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP) {
            // stopped before or after a system call -- query the child and print out info
        }
        if (WIFEXITED(status) || WIFSIGNALED(status)) {
            // child has exited or terminated
            break;
        }
        ptrace(PTRACE_SYSCALL, 0, 0, 0);  // ignore any signal and continue the child
    }
    

    Note that it will stop TWICE for each system call -- once before the system call and a second time just after the system call completes.

提交回复
热议问题