问题描述
因此,我有一个不错的合作PTRACE_TRACEME
子程序,该程序由PTRACE
包装程序处理。
问题是,如果管理员(或其他人)决定SIGSTOP
子程序,我该如何处理?当然,稍后再拿起SIGCONT
。
答案可能是“你不能” ?毕竟是PTRACE
!
我可以看到PTRACE_LISTEN
(从Linux 3.4开始)起着一定的作用,使子程序处于停止状态,但是据证明,只有当子程序与PTRACE_SEIZE
连接时,子程序才能工作
我尝试了在Group-stop中处于PTRACE_LISTEN
模式时调用PTRACE_TRACEME
的琐事,并且据记录,我收到了Old McDonald错误-EIO
。
我认为我可以注入代码来执行sigsuspend
,但是当然,这只会暂停子程序的1个线程。我将不得不向每个线程注入信号然后停止所有线程?然后重启?
也许重新交付的SIGSTOP
的实施已经阻止了它们?在哪种情况下,我的sigsuspend
实际上会被触发?我想如果另一个线程报告了SIGCONT
,我可以直接触发它。
这听起来很有趣,但是我想知道我是否错过了PTRACE
文档中的技巧吗?也许有一种方法可以让我缺少PTRACE_SEIZE
兼容模式?
[更多的小孔]
为什么不首先使用PTRACE_SEIZE?
可以得出结论:API中是否存在一种机制可以进入PTRACE_SEIZE
模式或模拟SIGSTOP
行为?
解决方法
下面是示例 PTRACE_SEIZE 的模拟SIGSTOP行为的测试程序。
#define PTRACE_SEIZE 0x4206
#define PTRACE_SEIZE_DEVEL 0x80000000
static const struct timespec ts100ms = { .tv_nsec = 100000000 };
static const struct timespec ts1s = { .tv_sec = 1 };
static const struct timespec ts3s = { .tv_sec = 3 };
int main(int argc,char **argv)
{
pid_t tracee;
tracee = fork();
if (tracee == 0) {
nanosleep(&ts100ms,NULL);
while (1) {
printf("tracee: alive\n");
nanosleep(&ts1s,NULL);
}
}
if (argc > 1)
kill(tracee,SIGSTOP);
nanosleep(&ts100ms,NULL);
ptrace(PTRACE_SEIZE,tracee,NULL,(void *)(unsigned long)PTRACE_SEIZE_DEVEL);
waitid(P_PID,WSTOPPED);
ptrace(PTRACE_CONT,NULL);
nanosleep(&ts3s,NULL);
printf("tracer: exiting\n");
return 0;
}
在不带参数的情况下调用上述代码时,会从 运行状态并持续。跟踪程序退出时,tracee返回到 运行状态并不断打印。
# ./test-seize
tracee: alive
tracee: alive
tracee: alive
tracer: exiting
# tracee: alive
tracee: alive
tracee: alive
当使用参数调用时,tracee将从停止状态中捕获,并且 继续,并在退出跟踪器时返回停止状态。
# ./test-seize
tracee: alive
tracee: alive
tracee: alive
tracer: exiting
# ps -el|grep test-seize
1 T 0 4720 1 0 80 0 - 941 signal ttyS0 00:00:00 test-seize
您可以在此thread
了解更多信息