【问题标题】:What happens when ptrace(PTRACE_DETATCH,pid,NULL,NULL) is called on a dead pid?在死 pid 上调用 ptrace(PTRACE_DETATCH,pid,NULL,NULL) 会发生什么?
【发布时间】:2018-04-05 19:38:01
【问题描述】:

我正在尝试捕获所有正在运行的进程的命令行参数。其中一些进程的命令行超过了 /proc/${pid}/cmdline 的 4096 个字符限制,因此读取该 procfs 文件不符合我的要求。我感兴趣的进程可能是瞬态的,所以我需要能够在知道它们的 pid 后立即从 /proc/${pid}/mem 的堆栈中读取它们的命令行参数。这需要在我的 C 代码中使用 ptrace 附加到它们。

while (pid >= 0){
    intPtraceReturnValue = ptrace(PTRACE_ATTACH,pid,NULL,NULL);
    if(intPtraceReturnValue != -1){
        wait(&intStatus);
        readFromProcMem(pid); // function that handles /proc/${pid}/mem reading
        intPtraceReturnValue = ptrace(PTRACE_CONT,pid,NULL,NULL);
        wait(&intStatus);
        intPtraceReturnValue = ptrace(PTRACE_DETATCH,pid,NULL,NULL);
        printFoundCommandLineArgs(); // prints results.
    }
    pid = getNextPid(); // function that interrogates /proc for the next running pid.
} 

有时 PTRACE_ATTACH 调用会返回 -1。这通常发生在调用管道时,并且我可以接受在这种情况下调用 ptrace 时命令行参数已丢失到历史记录中。但是,在其他情况下,ptrace 连接正常,但我无法分离,因为进程在我等待 PTRACE_CONT 调用释放内核互斥锁时完成。也就是说,如果使用 PTRACE_CONT 的调用将 intStatus 设置为 0,则使用 PTRACE_DETATCH 的调用将返回 -1。运行几分钟后,我看不到与 pid 相关的内存。有时我对 /proc 列表的访问似乎被拒绝了。在其他情况下,我只会得到空的结果。我怀疑有一个 ptrace 附件表没有被充分清除,因为 ptrace 是在死 pid 上使用 PTRACE_DETACH 调用的。是这样吗?如果是这样,我怎样才能手动清除悬空的附件?如果不是,那么 ptrace 会干扰我对 /proc 的访问吗?我已经证实,当不涉及 ptrace 时,程序的其他总结部分可以单独工作。我知道这是 ptrace 的一种非正统用法。任何想法将不胜感激

【问题讨论】:

  • 顺便说一下,我正在使用 gcc 4.4.7(根据要求)并且我在 Lunix Kernel 2.6.32-696.3.2.el6.x86_64 上运行

标签: c linux process command-line-arguments ptrace


【解决方案1】:

你有多个问题,我会用 cmets 在你的代码中指出它们:

while (pid >= 0){
    intPtraceReturnValue = ptrace(PTRACE_ATTACH,pid,NULL,NULL);
    // here you should call ptrace(PTRACE_INTERRUPT, pid, NULL, NULL) to stop the tracee 
    if(intPtraceReturnValue != -1){
        wait(&intStatus);
        readFromProcMem(pid); // function that handles /proc/${pid}/mem reading
        // the PTRACE_CONT and wait are unnecessary
        // intPtraceReturnValue = ptrace(PTRACE_CONT,pid,NULL,NULL);
        // wait(&intStatus);
        // the PTRACE_DETACH is enough to trigger the process to continue running
        intPtraceReturnValue = ptrace(PTRACE_DETATCH,pid,NULL,NULL);
        printFoundCommandLineArgs(); // prints results.
    }
    pid = getNextPid(); // function that interrogates /proc for the next running pid.
} 

从您的问题来看,问题所在并不明确,但我很确定如果您应用上述更改,您可能会得到更好的结果。

【讨论】:

  • 您是否包含与 gcc 的 ptrace.h 不同的头文件?
  • PTRACE_INTERRUPT 是新功能吗?我根据您的建议添加了它,但我的代码没有编译。看到类似的问题,我添加了一些关于我在原始问题中需要使用的编译器和 Linux 内核的信息。谢谢你的想法。
  • PTRACE_INTERRUPT 从 linux 3.4 开始
猜你喜欢
  • 1970-01-01
  • 2016-01-04
  • 1970-01-01
  • 2013-04-01
  • 1970-01-01
  • 2014-03-27
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
相关资源
最近更新 更多