Linux 系统调用的跟踪

以下内容源自 Professional Linux Kernel Architecture

由本人做整理修改

--------------------------------------------------------------------------


strace 可以用来跟踪Linux下的系统调用。它基于ptrace系统调用。

安装: # aptitude install strace

使用: #strace -o log ./your_app


-----------------------------

关于 strac的跟踪原理可以由下面的小例子反映:


//sct.c 
/*
 * Simple replacement for strace.
 * From Professional Linux Architecture.
 * Modified by Yang Honggang(Joseph).
 *
 * IA-32 or AMD64 Platform.
 */

#include 
#include 
#include 
#include 
#include 
#include 

#define ORIG_EAX 11

static long pid;

int upeek(int pid, long off, long* res)
{
     long val;
    
    /*
     * PEEKUSR reads the normal CPU registers and any other debug registers used.
     */
    val = ptrace(PTRACE_PEEKUSER, pid, off, 0);

    if (val == -1) {
        return -1;
    }

    *res = val;

    return 0;
}

void trace_syscall()
{
    long res;
    /*
     * If ptrace is activated with this option, the
     * kernel starts process execution until a system call is invoked.
     */
    res = ptrace(PTRACE_SYSCALL, pid, (char*) 1, 0);
    if (res < 0) {
        printf("Failed to execute until next syscall: %d\n", res);
    }
}

#define ORIG_RAX 15
void sigchld_handler (int signum)
{
    long scno;
    int res;

    /* Find out the system call (system-dependent)... */
     /* For IA-32 platform */
    //if (upeek(pid, 4 * ORIG_EAX, &scno) < 0) {
     /* For AMD64 platform */
    if (upeek(pid, 8 * ORIG_RAX, &scno) < 0) {    
        return;
    }

    /* output the information */
    if (scno != 0) {
        printf("System call: %u\n", scno);
    }

    /* Activate tracing until the next system call */
    trace_syscall();
}

int main(int argc, char** argv)
{
    int res;

    /* Check the number of arguments */
    if (argc != 2) {
        printf("Usage: ptrace \n");
        exit(-1);
    }

    /* Read the desired pid from the command-line parameters */
    pid = strtol(argv[1], NULL, 10);
    if (pid <=0) {
        printf("No valid pid specified\n");
        exit(-1);
    } else {
        printf("Tracing requested for PID %u\n", pid);
    }

    /* Install handler for SIGCHLD */
    struct sigaction sigact;
    sigact.sa_handler = sigchld_handler;
    sigaction(SIGCHLD, &sigact, NULL);

    /* Attach to the desired process */
    res = ptrace(PTRACE_ATTACH, pid, 0, 0);
    if (res < 0) {
        printf("Failed to attach: %d\n", res);
        exit(-1);
    } else {
        printf("Attached to %u\n", pid);
    }

    for (;;) {
        wait(&res);
        if (res == 0) {
            exit(1);
        }
    }
}

//app.c

#include 
#include 
#include 
#include 

int main(void)
{
    int handle, bytes;
    void* ptr;
 
 while(1) {
    handle = open("/tmp/test.txt", O_RDONLY);

    ptr = (void*)malloc(10);
    
    bytes = read(handle, ptr, 10);
//    printf("%s", ptr);

    close(handle);
 }
    return 0;
}


使用:

生成辅助的文件

 #echo "123456789a“ > /tmp/test.txt

运行待跟踪的程序,得到它的pid,假设为APP_PID

   #./app &

开始跟踪

   #./sct   APP_PID  



你可能感兴趣的:(Linux,内核,实时操作系统,Linux,基础学习)