Date: Wed, 27 Sep 2000 20:56:55 -0400 (EDT) From: Patrick Alken <cosine@ellipse.mcs.drexel.edu> To: freebsd-questions@freebsd.org Subject: ptrace question Message-ID: <Pine.BSF.4.21.0009272043090.9835-100000@ellipse.mcs.drexel.edu>
next in thread | raw e-mail | index | archive | help
Below I have provided a sample program to demonstrate the problem I am having. Basically, when I ptrace() an ncurses program (such has ncftp 2.4.3), I cannot do a PT_CONTINUE followed by a PT_STEP normally. To demonstrate, the program gets ncftp ready for ptracing and then calls ptrace() with PT_CONTINUE on it. This works perfectly, and if the program receives a signal, such as a SIGINT from a CTRL-C, I then attempt to use ptrace() with PT_STEP, to single-step the next instruction. This is where it fails. The wait() call after the ptrace(PT_STEP) call does not return until you hit the ENTER key, and I cannot figure out why. The first wait() call after the ptrace(PT_CONTINUE) returns normally, but when I use it after the singlestep call, it will not return normally unless I hit a key. As a side note, if I use ptrace(PT_CONTINUE) a second time (instead of PT_STEP), the wait() call will return normally without having to hit a key. Also, if I run a non-ncurses program through this same procedure, the wait() after the ptrace(PT_STEP) operates normally. I can only reproduce this problem under ncurses programs like ncftp v2.4.3 - but I did use tcgetattr() and tcsetattr() to reset the terminal settings, so I don't know why ncurses would be affecting it. If anyone knows what the problem could be, please let me know! ---- Cut here ---- /* * The goal of this program is to run an ncurses program normally * until a signal is caught, and then try to singlestep one * instruction. It should demonstrate that the wait() call after * the ptrace() singlestep call does not return as it should - * you need to hit the ENTER key for the wait() call to return. * * Compile: gcc -o ptest ptest.c * * Run: ./ptest, hit ^C and you will see that you must hit * a keystroke to get it to continue past the singlestep. */ #include <stdio.h> #include <sys/types.h> #include <sys/ptrace.h> #include <errno.h> #include <sys/wait.h> #include <signal.h> #include <termios.h> #include <unistd.h> /* * Location of an ncurses program (NcFTP v2.x.x) */ char filename[] = "/usr/local/bin/ncftp2"; int main() { int pid; /* child pid */ int waitval; int sig; struct termios SavedAttributes; signal(SIGINT, SIG_IGN); 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, so the parent can switch * to PT_STEP */ execl(filename, filename, NULL); break; } /* * Parent */ default: { /* * Wait for child to stop (execl) */ wait(&waitval); /* save attributes */ tcgetattr(STDIN_FILENO, &SavedAttributes); if (ptrace(PT_CONTINUE, pid, (caddr_t) 1, 0) != 0) perror("ptrace"); wait(&waitval); /* restore attributes */ tcsetattr(STDIN_FILENO, TCSANOW, &SavedAttributes); fprintf(stderr, "\nwaitval1 = %d\n", waitval); if (WIFSTOPPED(waitval)) { sig = WSTOPSIG(waitval); fprintf(stderr, "signal = %d\n", sig); /* * OK, they did the CONTROL-C, now try singlestepping the * next instruction. */ fprintf(stderr, "SINGLESTEPPING - here is where you have to hit ENTER but shouldn't need to\n"); if (ptrace(PT_STEP, pid, (caddr_t) 1, 0) != 0) perror("ptrace"); /* * Here is where you have to hit a key to get wait() to * return??? */ wait(&waitval); tcsetattr(STDIN_FILENO, TCSANOW, &SavedAttributes); fprintf(stderr, "DONE SINGLESTEP, waitval2 = %d\n", waitval); } } } return 0; } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-questions" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0009272043090.9835-100000>