lkml.org 
[lkml]   [2000]   [Mar]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectStopping 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/

\
 
 \ /
  Last update: 2005-03-22 13:57    [W:0.033 / U:0.456 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site