【问题标题】:PTRACE_DETACH fails after PTRACE_CONT with errno=ESRCHPTRACE_CONT 后 PTRACE_DETACH 失败,errno=ESRCH
【发布时间】:2013-12-11 04:07:12
【问题描述】:

在我的项目中,我需要附加到进程,恢复它们,然后使用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

【问题讨论】:

  • 执行这样一个过程需要多长时间?
  • 目标进程可以无限执行。我认为这可能是某种时间问题,但在 PTRACE_CONT 之后添加 sleep(10) 并不能解决失败的分离问题。

标签: c linux ptrace


【解决方案1】:

根据ptrace 手册页,该进程应在​​尝试与其分离之前停止:

被跟踪者的分离由以下人员执行:

ptrace(PTRACE_DETACH, pid, 0, sig);

PTRACE_DETACH 是一个重启操作;因此它需要 tracee 在 ptrace-stop 中。如果被跟踪者处于信号传递状态- 停止,可以注入信号。否则,sig 参数可能是 默默无视。 如果 tracee 在 tracee 想要分离它时正在运行,则 通常的解决方案是发送 SIGSTOP(使用 tgkill(2),以确保它 转到正确的线程),等待被跟踪者在信号中停止 - SIGSTOP 的交付停止,然后将其分离(抑制 SIGSTOP 注射)。一个设计错误是这可能与并发竞争 SIGSTOP。另一个复杂的问题是被跟踪者可能会进入其他 ptrace 停止,需要重新启动并再次等待,直到 看到 SIGSTOP。另一个复杂因素是要确保 tracee 尚未停止 ptrace,因为没有信号传递 在它存在的时候发生——甚至没有 SIGSTOP。

在您的示例代码中,实际上不需要调用ptrace(PTRACE_CONT, ...)。你可以从这个过程中分离出来。如果该代码属于较大的一段代码,那么您可以使用tgkill()(或者如果您不使用线程,则只需使用kill):

ptrace(PTRACE_CONT, ...);
kill(pid, SIGSTOP);
waitpid(pid, NULL, 0);
ptrace(PTRACE_DETACH, ...);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多