gdb attach被跟踪进程时,tracee收到SIGSTOP后的执行逻辑是怎样的?
PTRACE_ATTACH 执行逻辑解答
核心结论
两种猜测均不正确,PTRACE_ATTACH的大部分逻辑由内核直接完成,并不依赖tracee的用户态信号处理函数执行状态标记逻辑,也不会额外产生SIGTRAP信号。
Linux 下PTRACE_ATTACH 完整执行流程
- tracer发起系统调用:tracer调用
ptrace(PTRACE_ATTACH, <tracee_pid>, NULL, NULL),内核首先做权限校验:校验规则包括是否拥有CAP_SYS_PTRACE权限、目标进程是否设置PR_SET_DUMPABLE标志、系统ptrace_scope限制等,校验失败直接返回-EPERM错误。 - 内核标记跟踪状态:权限校验通过后,内核直接修改目标tracee的进程描述符(
task_struct结构体):设置PT_PTRACED标志位,同时将当前tracer的PID写入tracee的ptracer字段,绑定跟踪关系。这一步完全在内核态完成,和tracee的用户态逻辑完全无关,tracee不需要主动感知被跟踪,所有状态都由内核维护。 - 内核发送SIGSTOP信号:完成状态绑定后,内核直接向tracee发送
SIGSTOP信号,该信号不是tracer在用户态主动发送的,是内核处理PTRACE_ATTACH逻辑的内置步骤。 - tracee进入停止状态并通知tracer:tracee收到
SIGSTOP信号后,内核将其状态置为TASK_STOPPED,同时向绑定的tracer发送SIGCHLD信号,通知tracer被跟踪进程状态发生变化。 - tracer接管tracee:tracer收到
SIGCHLD信号后调用wait()系列系统调用,即可获取tracee的停止状态,后续可通过PTRACE_CONT、PTRACE_GETREGS等ptrace请求控制tracee运行。
针对疑问的补充说明
- 关于状态标记逻辑:进程的跟踪状态完全由内核维护,用户态进程可以通过读取
/proc/self/status中的TracerPid字段判断自己是否被跟踪,该字段非0即代表对应PID的进程是当前进程的跟踪者。 - 两种猜测的错误点:
- TRACED状态标记远早于SIGSTOP信号送达tracee的时间点,完全由内核在处理PTRACE_ATTACH请求时完成,和tracee的SIGSTOP信号处理逻辑没有关系。
- PTRACE_ATTACH流程不会产生SIGTRAP信号,SIGTRAP仅会在断点触发、单步执行、系统调用拦截等场景下产生。
内容的提问来源于stack exchange,提问作者Ryan Gao
相关产品推荐
相关产品推荐

