You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Linux下父进程能否统计子进程nanosleep()调用的睡眠时间?

在Linux中父进程能否确定子进程nanosleep()的睡眠时长

可以,通过Linux提供的ptrace进程跟踪机制,父进程能够捕获子进程对nanosleep()的调用并获取其睡眠时长参数。具体实现逻辑如下:

核心原理

ptrace允许父进程监控、控制子进程的执行流程,包括拦截系统调用、读取子进程的寄存器和内存数据。当子进程调用nanosleep()时,会触发SIGTRAP信号,父进程可通过wait()捕获该事件,进而提取系统调用的参数。

具体步骤

  • 启动跟踪:父进程通过fork()创建子进程后,让子进程调用ptrace(PTRACE_TRACEME, ...)主动接受跟踪;若子进程已运行,父进程可使用ptrace(PTRACE_ATTACH, ...)附加到目标进程(需对应权限)。
  • 捕获系统调用:子进程执行nanosleep()时会暂停并通知父进程,父进程通过wait()获取子进程状态。
  • 提取参数:
    1. 调用ptrace(PTRACE_GETREGS, ...)读取子进程的寄存器状态。在x86_64架构下,nanosleep()的第一个参数(指向struct timespec的指针)存放在rdi寄存器中。
    2. 通过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, &regs);
            // 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:10:45