我正在 try catch 所有正在运行的进程的命令行参数。其中一些进程的命令行超过了/proc/${pid}/cmdline 的 4096 个字符限制,因此读取该 procfs 文件不符合我的要求。我感兴趣的进程可能是 transient 的,因此我需要能够在知道它们的 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。运行几分钟后,我看不到与 pids 关联的内存。有时我访问/proc 列表的权限似乎被拒绝了。在其他情况下,我只会得到空结果。我怀疑有一个 ptrace 附件表没有得到充分清除,因为 ptrace 是在死的 pid 上用 PTRACE_DETACH 调用的。是这样吗?如果是这样,我如何手动清除悬挂附件?如果不是,那么 ptrace 做什么会干扰我对/proc 的访问?当不涉及 ptrace 时,我已经验证了程序的其他总结部分单独工作。我知道这是对 ptrace 的一种非正统使用;任何想法将不胜感激
最佳答案
您有多个问题,我会在您的代码中通过评论指出它们:
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.
}
从你的问题来看,问题是什么并不明确,但我很确定如果你应用上述更改,你可能会得到更好的结果。
关于c - 当在死 pid 上调用 ptrace(PTRACE_DETATCH,pid,NULL,NULL) 时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46920132/