From owner-freebsd-hackers Thu Sep 28 6:27:57 2000 Delivered-To: freebsd-hackers@freebsd.org Received: from ellipse.mcs.drexel.edu (ellipse.mcs.drexel.edu [129.25.7.190]) by hub.freebsd.org (Postfix) with ESMTP id 74FA537B422 for ; Thu, 28 Sep 2000 06:27:32 -0700 (PDT) Received: from localhost (cosine@localhost) by ellipse.mcs.drexel.edu (8.11.0/8.9.3) with ESMTP id e8SDKf711257 for ; Thu, 28 Sep 2000 09:20:42 -0400 (EDT) (envelope-from cosine@ellipse.mcs.drexel.edu) Date: Thu, 28 Sep 2000 09:20:40 -0400 (EDT) From: Patrick Alken To: freebsd-hackers@freebsd.org Subject: ptrace question Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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 #include #include #include #include #include #include #include /* * 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-hackers" in the body of the message