Linux下父进程能否统计子进程nanosleep()调用的睡眠时间?
在Linux中父进程能否确定子进程nanosleep()的睡眠时长
可以,通过Linux提供的ptrace进程跟踪机制,父进程能够捕获子进程对nanosleep()的调用并获取其睡眠时长参数。具体实现逻辑如下:
核心原理
ptrace允许父进程监控、控制子进程的执行流程,包括拦截系统调用、读取子进程的寄存器和内存数据。当子进程调用nanosleep()时,会触发SIGTRAP信号,父进程可通过wait()捕获该事件,进而提取系统调用的参数。
具体步骤
- 启动跟踪:父进程通过
fork()创建子进程后,让子进程调用ptrace(PTRACE_TRACEME, ...)主动接受跟踪;若子进程已运行,父进程可使用ptrace(PTRACE_ATTACH, ...)附加到目标进程(需对应权限)。 - 捕获系统调用:子进程执行
nanosleep()时会暂停并通知父进程,父进程通过wait()获取子进程状态。 - 提取参数:
- 调用
ptrace(PTRACE_GETREGS, ...)读取子进程的寄存器状态。在x86_64架构下,nanosleep()的第一个参数(指向struct timespec的指针)存放在rdi寄存器中。 - 通过
ptrace(PTRACE_PEEKDATA, ...)读取子进程地址空间中该指针指向的struct timespec结构体,从中获取tv_sec(秒数)和tv_nsec(纳秒数)字段,即睡眠时长。
- 调用
- 恢复执行:父进程调用
ptrace(PTRACE_CONT, ...)让子进程继续运行,循环重复上述步骤以跟踪后续的nanosleep()调用。
注意事项
- 性能影响:跟踪过程会中断子进程的执行,频繁的系统调用拦截会导致子进程性能下降。
- 权限要求:跟踪非子进程时,父进程需要
CAP_SYS_PTRACE权限,或调整系统参数/proc/sys/kernel/yama/ptrace_scope放宽跟踪限制。 - 架构差异:不同CPU架构的寄存器传参规则不同,比如x86(32位)使用栈传递参数,需对应调整参数读取逻辑。
示例代码片段
#include <sys/ptrace.h> #include <sys/wait.h> #include <sys/user.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> struct timespec get_nanosleep_param(pid_t child_pid, struct user_regs_struct regs) { struct timespec ts; // x86_64下,nanosleep第一个参数地址存在rdi寄存器 long ts_addr = regs.rdi; // 读取tv_sec和tv_nsec字段 ts.tv_sec = ptrace(PTRACE_PEEKDATA, child_pid, ts_addr, NULL); ts.tv_nsec = ptrace(PTRACE_PEEKDATA, child_pid, ts_addr + sizeof(time_t), NULL); return ts; } int main() { pid_t pid = fork(); if (pid == 0) { // 子进程开启跟踪模式 ptrace(PTRACE_TRACEME, 0, NULL, NULL); // 执行包含nanosleep的程序,这里用sleep命令示例 execl("/bin/sleep", "sleep", "2", NULL); exit(EXIT_FAILURE); } else { int status; wait(&status); // 循环跟踪系统调用 while (WIFSTOPPED(status)) { struct user_regs_struct regs; ptrace(PTRACE_GETREGS, pid, NULL, ®s); // x86_64上nanosleep的系统调用号是35 if (regs.orig_rax == 35) { struct timespec ts = get_nanosleep_param(pid, regs); printf("子进程nanosleep时长:%ld秒 + %ld纳秒\n", ts.tv_sec, ts.tv_nsec); } // 恢复子进程执行 ptrace(PTRACE_CONT, pid, NULL, NULL); wait(&status); } } return 0; }
编译运行:
gcc -Wall ptrace_nanosleep.c -o ptrace_nanosleep ./ptrace_nanosleep
内容的提问来源于stack exchange,提问作者Amit Gabay
相关产品推荐
相关产品推荐

