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