【发布时间】: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