Messages in this thread | | | Date | Fri, 17 Mar 2000 18:00:06 -0600 (CST) | From | Victor Zandy <> | Subject | Stopping ptraced processes |
| |
On x86 Linux 2.2.12, I can't figure out a reliable way to keep a process stopped after ptrace operations.
For example, after this sequence
ptrace(PTRACE_ATTACH, pid, 0, 0); waitpid(pid, NULL, 0); ptrace(PTRACE_DETACH, pid, 0, SIGSTOP);
the process (pid) is not stopped. So this does not help me.
After this sequence
ptrace(PTRACE_ATTACH, pid, 0, 0); (Sequence 1) waitpid(pid, NULL, 0); kill(pid, SIGSTOP); ptrace(PTRACE_DETACH, pid, 0, 0);
the process is stopped. However, following it with this sequence
ptrace(PTRACE_ATTACH, pid, 0, 0); waitpid(pid, NULL, 0); ptrace(PTRACE_DETACH, pid, 0, 0);
causes it to run again. On the other hand, following Sequence 1 with this sequence (prefacing the above sequence with a sleep)
sleep(1); ptrace(PTRACE_ATTACH, pid, 0, 0); waitpid(pid, NULL, 0); ptrace(PTRACE_DETACH, pid, 0, 0);
causes the process to remain stopped.
I've been trying to understand this behavior from kernel sources, but I can't figure it out -- can anyone help me?
The program copied below demonstrates the behavior I describe. My questions in terms of this program are
- why does the child stop for arg==2, but not arg==1? - why does the child stop for arg==4, but not arg==3?
My real problem is I need a way to keep a process stopped across multiple ptrace attach/detach operations. Does anyone have a reliable technique?
Thanks, Vic Zandy
#include <sys/ptrace.h> #include <signal.h> #include <unistd.h>
int main(int argc, char *argv[]) { int arg, pid;
arg = atoi(argv[1]);
pid = fork(); if (pid == 0) while (1) { sleep(1); printf("I'm running\n"); }
if (arg == 1) { ptrace(PTRACE_ATTACH, pid, 0, 0); waitpid(pid, NULL, 0); ptrace(PTRACE_DETACH, pid, 0, SIGSTOP); /* child is left RUNNING */ } else if (arg == 2) { ptrace(PTRACE_ATTACH, pid, 0, 0); waitpid(pid, NULL, 0); kill(pid, SIGSTOP); ptrace(PTRACE_DETACH, pid, 0, 0); /* child is left STOPPED */ } else if (arg == 3) { ptrace(PTRACE_ATTACH, pid, 0, 0); waitpid(pid, NULL, 0); kill(pid, SIGSTOP); ptrace(PTRACE_DETACH, pid, 0, 0);
ptrace(PTRACE_ATTACH, pid, 0, 0); waitpid(pid, NULL, 0); ptrace(PTRACE_DETACH, pid, 0, 0); /* child is left RUNNING */ } else if (arg == 4) { ptrace(PTRACE_ATTACH, pid, 0, 0); waitpid(pid, NULL, 0); kill(pid, SIGSTOP); ptrace(PTRACE_DETACH, pid, 0, 0); sleep(1); ptrace(PTRACE_ATTACH, pid, 0, 0); waitpid(pid, NULL, 0); ptrace(PTRACE_DETACH, pid, 0, 0); /* child is left STOPPED */ }
while (1) ; return 0; }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |