在我的项目中,我需要附加到进程,恢复它们,然后使用ptrace
进行分离。但是,errno=ESRCH (No such process)
分离失败。
如果我没有使用PTRACE_CONT
恢复进程,则分离工作正常,但在这种情况下,进程停止/无响应,这在我的项目中是不可接受的。测试Arch& Ubuntu 12.04 LTS具有相同的结果。
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
pid_t pid = 21000;
if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) == -1) {
perror("PTRACE_ATTACH");
return 1;
}
printf("attached\n");
waitpid(pid, NULL, WUNTRACED);
if (ptrace(PTRACE_CONT, pid, NULL, NULL) == -1) {
perror("PTRACE_CONT");
return 1;
}
printf("continued\n");
if (ptrace(PTRACE_DETACH, pid, NULL, NULL) == -1) {
perror("PTRACE_DETACH");
return 1;
}
printf("detached\n");
return 0;
}
输出:
attached
continued
PTRACE_DETACH: No such process
答案 0 :(得分:5)
根据ptrace
手册页,在尝试从中删除之前应该停止该过程:
通过以下方式执行tracee的分离:
ptrace(PTRACE_DETACH,pid,0,sig);
PTRACE_DETACH是一个重启动作;因此它需要 追踪到了ptrace-stop。如果迹象是信号传递 - 停止,可以注入信号。否则,sig参数可能是 默默地忽略了。 如果跟踪器在跟踪器想要分离时运行,则 通常的解决方案是发送SIGSTOP(使用tgkill(2),以确保它 转到正确的线程),等待tracee停止信号 - SIGSTOP的交付停止然后分离它(抑制SIGSTOP 注射)。一个设计错误是它可以与并发竞争 SIGSTOPs。另一个复杂因素是,tracee可能会进入其他 ptrace-stops并需要重新启动并再次等待,直到 看到SIGSTOP。另一个复杂因素是确保 tracee尚未停止,因为没有信号传递 它发生的时候 - 甚至不是SIGSTOP。
在您的示例代码中,实际上无需调用ptrace(PTRACE_CONT, ...)
。你可以脱离这个过程。如果该代码属于更大的代码段,那么您可以使用tgkill()
(如果您不使用线程,则只需kill
):
ptrace(PTRACE_CONT, ...);
kill(pid, SIGSTOP);
waitpid(pid, NULL, 0);
ptrace(PTRACE_DETACH, ...);