Linuxシステム呼び出しの追跡

4157 ワード

以下は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 <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/wait.h>

#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
", 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
", 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 <pid>
"); 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
"); exit(-1); } else { printf("Tracing requested for PID %u
", 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
", res); exit(-1); } else { printf("Attached to %u
", pid); } for (;;) { wait(&res); if (res == 0) { exit(1); } } }
//app.c

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <malloc.h>

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