Linuxシステム呼び出しの追跡
4157 ワード
以下はProfessional Linux Kernel Architectureから
本人が整理して修正する
--------------------------------------------------------------------------
straceはLinuxでのシステム呼び出しを追跡するために使用できます.ptraceシステム呼び出しに基づいています.
インストール:#aptitude install strace
使用:#strace-o log./your_app
-----------------------------
stracに関する追跡原理は、以下の小さな例によって反映されることができる.
次の操作を行います.
補助ファイルの生成
#echo "123456789a“>/tmp/test.txt
追跡対象のプログラムを実行し、そのpidを取得し、APP_PIDと仮定する
#./app &
トレース開始
#./sct APP_PID
本人が整理して修正する
--------------------------------------------------------------------------
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