From e7f1e8c48fc67364824a5ce1ce514b18402be722 Mon Sep 17 00:00:00 2001 From: "zhangyanfei.allen" Date: Wed, 11 Dec 2024 22:18:56 +0800 Subject: [PATCH] feat: add strace test --- tests/cpu/index.md | 3 +- tests/cpu/test11/main.c | 90 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 tests/cpu/test11/main.c diff --git a/tests/cpu/index.md b/tests/cpu/index.md index 1c4bfe9..6a93d35 100644 --- a/tests/cpu/index.md +++ b/tests/cpu/index.md @@ -3,4 +3,5 @@ - [容器 cpu 系统利用率的计算过程](tests/cpu/test07) - [直接使用perf_event_open获取硬件计数](tests/cpu/test08) - [火焰图专用测试代码](tests/cpu/test09) -- [C语言调用Golang函数原理](tests/cpu/test10) \ No newline at end of file +- [C语言调用Golang函数原理](tests/cpu/test10) +- [模拟 strace 命令捕获其它进程系统调用](tests/cpu/test11) \ No newline at end of file diff --git a/tests/cpu/test11/main.c b/tests/cpu/test11/main.c new file mode 100644 index 0000000..71c843f --- /dev/null +++ b/tests/cpu/test11/main.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void handle_syscall(pid_t pid) { + long syscall_number; + char *syscall_name = NULL; + + // 读取系统调用号 + syscall_number = ptrace(PTRACE_PEEKUSER, pid, 8 * ORIG_RAX, NULL); // 8 * ORIG_RAX 是 x86_64 架构下系统调用号的寄存器位置 + + // 根据系统调用号获取系统调用名称 + switch (syscall_number) { + case 5: syscall_name = "read"; break; + case 6: syscall_name = "write"; break; + case 10: syscall_name = "open"; break; + case 11: syscall_name = "close"; break; + // 添加更多系统调用号和名称的映射 + default: syscall_name = "unknown"; break; + } + + printf("Syscall: %s (number: %ld)\n", syscall_name, syscall_number); + + +} + +int main(int argc, char *argv[]) { + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + pid_t pid = atoi(argv[1]); + + int status; + + if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) { + perror("PTRACE_ATTACH"); + exit(1); + } + + if (waitpid(pid, &status, 0) == -1) { + perror("waitpid"); + exit(1); + } + + if (!WIFSTOPPED(status)) { + fprintf(stderr, "Process did not stop\n"); + exit(1); + } + + printf("Attached to process %d\n", pid); + + while (1) { + if (ptrace(PTRACE_SYSCALL, pid, NULL, NULL) == -1) { + perror("PTRACE_SYSCALL"); + exit(1); + } + + if (waitpid(pid, &status, 0) == -1) { + perror("waitpid"); + exit(1); + } + + if (WIFEXITED(status)) { + printf("Process exited\n"); + break; + } + + if (WIFSTOPPED(status)) { + handle_syscall(pid); + } + } + + if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) { + perror("PTRACE_DETACH"); + exit(1); + } + + printf("Detached from process %d\n", pid); + + return 0; +}