Date: Mon, 18 Sep 2000 14:52:14 -0400 (EDT) From: Patrick Alken <cosine@ellipse.mcs.drexel.edu> To: freebsd-hackers@freebsd.org Subject: ptrace help Message-ID: <Pine.BSF.4.21.0009181424210.50782-200000@ellipse.mcs.drexel.edu>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
I am experiencing problems with ptrace() under FreeBSD. I made a simple
example program to demonstrate. All it does is fork a child process to
execl() a simple "hello world" program and ptrace() it with PT_CONTINUE.
The first time around, everything is as it should be - the program is
executed and traced perfectly. However, when I attempt to repeat the whole
process, first by forking a completely new child to execute the helloworld
program again, I start getting ptrace() errors such as "Operation not
permitted" and "Device busy".
Now the weird thing is, after the first trace, the program terminates
normally, and I print out the pid of the child process which should no
longer be running at this point. ptrace(PT_KILL) verifies this by
returning "No such process". However, during the pause between the first
and second ptrace, if I do a ps and search for the pid, it shows up in
memory as running in the background, although ptrace(PT_KILL) claims it
does not exist. Then my sample program attempts to trace the same
helloworld program again, and gets "Operation not permitted" - even though
an entirely new child is fork()'d with an entirely new pid - so it should
have absolutely no connection at all to the first trace. Does anyone know
why I can't ptrace() the same helloworld program a second time?
I have attached my sample ptrace() program to this message. Thanks in
advance for any help
Patrick Alken
[-- Attachment #2 --]
/*
* To run this, make a prog.c which contains:
* int main() { printf("hello world\n"); }
* and compile it into the file "prog".
*
* Then, simply: gcc -o myptrace myptrace.c
* and ./myptrace
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <errno.h>
#include <sys/wait.h>
#include <machine/reg.h>
#include <unistd.h>
#include <string.h>
/*
DoTrace() - begin to trace a process
*/
int
DoTrace()
{
int pid; /* child pid */
int waitval;
struct reg regs;
pid = fork();
switch (pid)
{
case -1:
{
perror("fork");
break;
}
/*
* Child
*/
case 0:
{
/*
* Allow parent to trace this child process
*/
ptrace(PT_TRACE_ME, 0, 0, 0);
/*
* Execute program to be debugged and cause child to
* send a signal to parent
*/
execl("./prog", "prog", NULL);
exit(0);
}
/*
* Parent
*/
default:
{
int pret;
/*
* Wait for child to stop (execl)
*/
wait(&waitval);
printf("waitval = %d\n", waitval);
/*
* Continue exection of process
*/
pret = ptrace(PT_CONTINUE, pid, (caddr_t) 1, 0);
if (pret != 0)
{
/*
* This is where it fails the second time with an
* errno of 1 (EPERM), even though we are tracing
* a completely new pid.
*/
perror("ptrace");
}
wait(&waitval);
pret = ptrace(PT_KILL, pid, 0, 0);
if (pret == 0)
{
printf("Kill successful\n");
wait(&waitval);
}
else
printf("Kill unsuccessful, errno = %s\n", strerror(errno));
}
}
return (pid);
} /* DoTrace() */
int
main()
{
int pid;
char buf[512];
/*
* Trace through the process
*/
pid = DoTrace();
printf("Pid1 = %d\n", pid);
fgets(buf, 512, stdin);
/*
* Trace through again (this is where it fails)
*/
pid = DoTrace();
printf("Pid2 = %d\n", pid);
return 0;
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0009181424210.50782-200000>
