以下内容源自 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\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 <pid>\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 <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