Skip to content

feat(ptrace): - #2198

Open
oeasy1412 wants to merge 2 commits into
DragonOS-Community:masterfrom
oeasy1412:feat-ptrace
Open

feat(ptrace): #2198
oeasy1412 wants to merge 2 commits into
DragonOS-Community:masterfrom
oeasy1412:feat-ptrace

Conversation

@oeasy1412

Copy link
Copy Markdown
Member

feat(ptrace): 完整实现ptrace系统调用与信号/系统调用跟踪机制

概述

本PR为DragonOS实现了Linux兼容的ptrace系统调用,覆盖传统attach模式与seize模式(PTRACE_SEIZE/INTERRUPT/LISTEN)的完整跟踪语义。

核心交付:完整的ptrace状态机、信号递送路径的ptrace_signal拦截、系统调用入口/出口stop、进程生命周期事件(fork/clone/exec/exit/seccomp)上报,以及/proc/[pid]/mem跨进程内存访问。

主要功能

1. ptrace关系建立与解除

  • PTRACE_TRACEME:子进程主动声明被父进程跟踪,含traceme_allowed权限校验
  • PTRACE_ATTACH:附加到任意进程。正确处理“目标已处于group-stop”场景——直接将group-stop转为ptrace-stop,否则发送SIGSTOP
  • PTRACE_SEIZE:seize模式附加,不发SIGSTOP,设置PT_SEIZED与选项位
  • PTRACE_DETACH:解除关系并可选注入信号,正确处理exit_ptrace级联释放

2. tracee执行恢复

  • PTRACE_CONT:恢复执行,支持注入信号
  • PTRACE_SYSCALL:单步到下一次系统调用入口/出口
  • PTRACE_SINGLESTEP:单步执行一条指令(置RFLAGS.TF
  • PTRACE_SYSEMU / PTRACE_SYSEMU_SINGLESTEP:仿真模式,跳过真实系统调用执行

3. seize模式操作

  • PTRACE_INTERRUPT:让运行中的seized tracee进入ptrace-stop
  • PTRACE_LISTEN:使tracee脱离ptrace-stop但保持stopped状态(不阻塞group-stop语义)
  • PTRACE_EVENT_STOP编码((Stop<<8)|signal),对齐seize/group-stop/INTERRUPT的重陷路径

4. 寄存器与内存访问

  • PTRACE_GETREGS / PTRACE_SETREGS:读写user_regs_struct,段选择子校验防止清IF导致用户态挂死
  • PTRACE_GETREGSET / PTRACE_SETREGSETNT_PRSTATUS
  • PTRACE_PEEKUSER / PTRACE_POKEUSER:含调试寄存器(DR0-DR7)读写
  • PTRACE_PEEKDATA/PEEKTEXT / PTRACE_POKEDATA/POKETEXT:正确处理跨页word访问
  • PTRACE_GETREGS配合GETREGS读取系统调用号

5. 信号与siginfo

  • PTRACE_GETSIGINFO / PTRACE_SETSIGINFO:读写last_siginfo
  • PTRACE_GETSIGMASK / PTRACE_SETSIGMASK:读写阻塞掩码(SIGKILL/SIGSTOP不可阻塞)
  • signal-delivery-stop:被跟踪任务的所有非SIGKILL信号先交由tracer决策,tracer可抑制或改写信号号

6. 选项与事件

  • PTRACE_SETOPTIONSTRACESYSGOOD/TRACEFORK/TRACEVFORK/TRACECLONE/TRACEEXEC/TRACEVFORKDONE/TRACEEXIT/TRACESECCOMP/EXITKILL/SUSPEND_SECCOMP
  • PTRACE_GETEVENTMSG:读取最近事件message(fork的child pid等)
  • PTRACE_GET_SYSCALL_INFO:返回ptrace_syscall_info结构

7. 调试陷阱处理(x86_64)

  • do_int3(软件断点):traced用户态触发ptrace_notify(SIGTRAP, TRAP_BRKPT)
  • do_debug(单步/硬件断点):解析DR6区分X86_DR_BS(单步,TRAP_TRACE)与X86_DR_B_MASK(硬件断点,TRAP_HWBKPT

8. /proc/[pid]/mem

  • 新增/proc/[pid]/mem/proc/[tid]/mem,文件偏移即目标进程用户虚拟地址,复用ptrace的页表翻译+缺页fault-in路径

核心实现

新增文件

  • kernel/src/process/syscall/sys_personality.rspersonality系统调用(调试器依赖ADDR_COMPAT_LAYOUT等执行域标志)
  • kernel/src/filesystem/procfs/pid/mem.rs/proc/[pid]/mem文件操作
  • user/apps/c_unitest/test_ptrace.c — ptrace功能测试用例

核心文件

  • kernel/src/process/ptrace.rs — ptrace状态机与全部PCB方法
    • PtraceState:跟踪exit_code/injected_signal/last_siginfo/event_message/options/listening/in_ptrace_stop/forced_trap_flag/debug_regs
    • ptrace_stop:进入ptrace-stop的核心阻塞与唤醒机制
    • ptrace_signal:信号递送路径的拦截hook
    • ptrace_notify / ptrace_event / ptrace_event_stop:trap与事件通知
    • ptrace_resume:CONT/SYSCALL/SINGLESTEP/SYSEMU恢复逻辑
    • ptrace_report_syscall:系统调用入口/出口stop
    • ptrace_interrupt / ptrace_listen / ptrace_trap_notify:seize模式操作
    • exit_ptrace:tracer退出时级联解除所有tracee关系
    • 关系建立采用PTRACE_RELATION_LOCK(关IRQ自旋锁)保护,TRAPPING位处理attach期间的竞态
  • kernel/src/process/syscall/sys_ptrace.rs — 请求分发、参数校验、ptrace_check_attach前置检查

修改文件

  • kernel/src/process/state.rs — 新增PT_SEIZED/TRAPPING/PENDING_PTRACE_STOP标志位;ProcessFlags重构为AtomicProcessFlags(原子存储,支持ptrace路径并发安全读写)
  • kernel/src/syscall/mod.rs — 系统调用分发集成:入口ptrace_report_syscall(entry)(含SYSEMU跳过)+ 出口统一ptrace_report_syscall(exit);ptrace后重取syscall号/参数再过seccomp
  • kernel/src/arch/x86_64/syscall/mod.rs — syscall入口无条件置rax=-ENOSYS(先于ptrace/seccomp);返回用户态前处理ptrace-stop;IA32_FMASK配置
  • kernel/src/arch/x86_64/ipc/signal.rsdo_signal集成signal-delivery-stop;返回用户态前检查PENDING_PTRACE_STOP发起PTRACE_EVENT_STOP;sigreturn改用异常表保护读取
  • kernel/src/arch/x86_64/interrupt/trap.rsdo_debug/do_int3的ptrace stop分支
  • kernel/src/ipc/signal.rs — 被跟踪任务的非SIGKILL信号不视为ignored;seized tracee的SIGCONTptrace_trap_notify而非直接唤醒
  • kernel/src/ipc/sighand.rsptrace_participate_group_stop
  • kernel/src/ipc/signal_types.rsSigInfo::from_posixset_signoPosixSigInfo::Default
  • kernel/src/process/fork.rsptrace_report_fork_event(按exit_signal!=SIGCHLD区分FORK/CLONE);子侧attach在wake_up_new_task之后上报,避免死锁;继承personality
  • kernel/src/process/execve.rsPTRACE_EVENT_EXEC上报old_vpid;非seized传统attach发裸SIGTRAP
  • kernel/src/process/exit.rsWaitRelation::Ptraced;ptraced zombie可见性门控(tracer ack前对real_parent不可见);notify_real_parent_after_ptrace_ack级联通知
  • kernel/src/process/seccomp.rsSECCOMP_RET_TRACE集成PTRACE_EVENT_SECCOMP(含recheck防重入、tracer改写syscall号/跳过)
  • kernel/src/syscall/user_access.rs — 新增read_one_from_user_protected

测试验证

自测用例输出

  • user/apps/c_unitest/test_ptrace.c

gVisor测试

  • ptrace_test纳入 gvisor syscall 测试 whitelist (blocklist暂时需要屏蔽PtraceTest.Int3

构建集成

  • user/apps/default.nix 新增静态链接的 stracegdb,便于真实验证

后续工作

  • 多线程tracee的线程级事件(PTRACE_O_TRACECLONE子线程自动attach等)
  • PTRACE_GETREGSET/SETREGSET扩展更多note type(FP/XSTATE等)
image image

Signed-off-by: aLinChe <1129332011@qq.com>
Signed-off-by: aLinChe <1129332011@qq.com>
@github-actions github-actions Bot added enhancement New feature or request test Unitest/User space test labels Aug 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request test Unitest/User space test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant