从
ptrace
man
:
信号注入与抑制
当跟踪器观察到信号传送停止后,跟踪器
应该用呼叫重新启动跟踪对象
ptrace(PTRACE_restart, pid, 0, sig)
其中PTRACE_restart是重新启动PTRACE请求之一。如果
为0,则不传递信号。否则,信号信号
已送达。这个操作叫做信号注入
另一页,以区别于信号传送停止。
sig值可能不同于WSTOPSIG(status)值:
示踪剂可导致注入不同的信号。
注意a
抑制的信号仍会导致系统调用返回
过早地。在这种情况下,系统调用将重新启动
:的
追踪者将观察被追踪者重新执行中断的系统
调用(或重新启动)系统调用
如果跟踪程序使用
在信号被抑制后重新启动信号后可重新启动;
但是,存在内核错误,这会导致一些系统调用失败。
即使没有可观察到的信号注入被跟踪者。
在我的例子中,终止逻辑从一个信号的传递(被gdb截获)开始,然后注入被跟踪的进程。
strace
-ing公司
gdb
生产:
ptrace(PTRACE_PEEKTEXT, 2274, 0x7f0c9d0ee2e0, [0x7f0ca013ab80]) = 0 <-- gdb woke up to SIGTERM directed at tracee
ptrace(PTRACE_PEEKUSER, 2274, 8*SS + 8, [0x7f0ca013a8c0]) = 0
ptrace(PTRACE_GETREGS, 2274, 0, 0x7ffdb4f2c3a0) = 0
...
ptrace(PTRACE_CONT, 2338, 0x1, SIG_0) = 0
ptrace(PTRACE_CONT, 2274, 0x1, SIGTERM) = 0 <-- SIGTERM is delivered to a thread chosen by kernel
...
ptrace(PTRACE_CONT, 2276, 0x1, SIG_0) = 0 <-- all other threads are restarted
...
注意,这不足以完全解释行为,因为线程在
accept()
可以在其他线程关闭文件描述符之前重新启动系统调用。
但是
斯特拉斯
日志中充满了类似的命令序列(
PTRACE_PEEKTEXT
接下来是不断减少
PTRACE_CONT
). 这里发生的是
gdb公司
每次线程终止时唤醒,从跟踪对象中提取一些数据并重新启动(剩余的)线程,导致系统调用重新启动。即当线程逐个退出时,每个剩余线程停止并重新启动多次,最终导致
接受()
重新启动
之后
文件描述符被另一个线程关闭。事实上,它是保证发生的,因为该线程在关闭之后退出。