DETATCH,pid,NULL,NULL) is called on a dead pid?
I am trying to capture the command line arguments of all running processes. Some of these processes have command lines that exceed the 4096 character limit of /proc/${pid}/cmdline, so reading that procfs file does not meet my requirement. The processes that interest me can be transient, so I need to be able to read their command line arguments from the stack in /proc/${pid}/mem as soon as I become aware of their pids. This requires attaching to them with ptrace in my C code.
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.
}
Sometimes the PTRACE_ATTACH call returns -1. This usually occurs when pipes are invoked, and I can accept that the command line arguments are lost to history by the time I call ptrace in this case. However, in other cases, ptrace attaches ok, but I cannot detach because the process finishes while I am waiting for the kernel mutex to be released by the call with PTRACE_CONT. That is, the call with PTRACE_DETATCH returns -1 if intStatus is set to 0 by the call with PTRACE_CONT. After a few minutes of running this I can't see the memory associated with pids. Sometimes my access to the listing of /proc seems to be denied. In other cases I just get empty results. I suspect that there is a table of ptrace attachments that is not getting sufficiently cleared because ptrace is being called with PTRACE_DETACH on dead pids. Is this the case? if so, how can I clear the dangling attachments manually? If not, what might ptrace doing that would interfere with my access to /proc? I have verified that the other summarized parts of the program work individually when ptrace is not involved. I know that this is a somewhat unorthodox use of ptrace; any thoughts would be appreciated
You have multiple issues, I'll point them out on your code with comments:
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.
}
From your question it's not clean what the problem is, but I'm pretty sure if you apply the above changes you'd probably get better results.
链接地址: http://www.djcxy.com/p/66382.html