Messages in this thread | | | Date | Thu, 18 Dec 1997 07:36:21 -0500 | From | Jim Nance <> | Subject | Problems with gdb and 2.0.32 |
| |
Hi All, I was playing around last night and found several annoying problems with gdb. I was running the 2.0.32 kernel with Cyrix patches. I have not tried under any other Linux kernel. I have tried the same program under Digital Unix, and things seem to behave much better. The program I am working on forks off a copy of gdb and talks to it through a pipe (ie its a gdb front end). While trying to debug this, I noticed several problems:
1) If gdb attaches to a process and dies while the process is stopped, the process is left in a T state. It can not be killed or suspended with ^C or ^Z from its controlling terminal. It can be killed with the kill command.
2) If a program does a pipe(); fork(); and then the processes try to talk to each other via the pipe, the writter will get a SIGPIPE if the program is running in the debugger. It works fine if the program is not in in the debugger.
3) If a program does a fork(); execv(); The execv will recieve a SIGTRAP and dump core. This is with either the execv() happening in the child or the parrent. The debugger is always attached to the parrent. This also works w/o problem if I am not running in the debugger.
Unfortunatly I did not make snapshots of these problem as I encountered them. At the time I was trying to work around them, and only this morning did it occur to me that I should report this behavior. I am including the program in its present form so that anyone interested in these problems can make sure its not an error on my part.
Thanks,
Jim
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <signal.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/stat.h> #include <errno.h>
#define Write(x,y) write(x, y, strlen(y))
int parseCmdLine(int ac, char **av, pid_t *pid, char **fname) { if(ac!=4) {return 1;} if(strcmp(av[1],"-pid")) {return 2;}
*pid = strtol(av[2], NULL, 0); *fname = av[3]; return 0; }
int waitforstr(char *str, char *buff, size_t max, int fd) { size_t len = strlen(str); size_t pos, i;
/* This is not really necessary, but it makes debugging more pleasant */ memset(buff, 0, max);
for(pos=0; pos<max-1; pos++) { int rc; do { rc=read(fd, &buff[pos], 1); } while(rc==-1 && errno==EINTR); if(rc!=1) { --pos; break; } if(pos>=len-1) { int OK=1; for(i=0; i<len; i++) { if(str[i]!=buff[pos-len+1+i]) { OK=0; break; } } if(OK==1) { break; } } } buff[pos+1]=0; return pos+1; }
int main(int ac, char **av) { struct stat buff; pid_t pid; char *fname; char rbuff[8192]; int pipefd[2]; int gin[2]; int gout[2]; int nchr;
if(parseCmdLine(ac, av, &pid, &fname)) { fprintf(stderr,"Bad command line\n"); return 1; }
if(kill(pid, 0)) { fprintf(stderr,"Can not attach to process %d\n", pid); return 2; }
if(stat(fname, &buff)) { fprintf(stderr, "Can not access %s\n", fname); return 3; }
/* if(socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd)<0) {*/ /* perror("socketpair:");*/ /* return 4;*/ /* }*/
pipe(gin); pipe(gout); fflush(stdout); if(!fork()) { static char cmd[1024]; static char *argv[] = {"/bin/sh","-c",cmd,0}; sprintf(cmd,"exec gdb %s %d", fname, pid); close(0); close(1); close(gin[1]); close(gout[0]); dup2(gin[0], 0); dup2(gout[1], 1); #if 0 Write(1,"xyz\n"); Write(1,"(gdb) "); do { Write(1,"# fun1 \n"); Write(1,"# main \n"); Write(1,"(gdb) "); } while(1); #endif execv(argv[0],argv); exit(-1); }
close(gin[0]); close(gout[1]); waitforstr("(gdb) ", rbuff, sizeof(rbuff), gout[0]);
Write(gin[1], "bt\n");
while(1) { waitforstr("\n", rbuff, sizeof(rbuff), gout[0]); sleep(0); } }
-- ---------------------------------------------------------------------------- Jim Nance Avant! Corporation (919) 941-6655 Do you have sweet iced tea? jim_nance@avanticorp.com No, but theres sugar on the table.
| |