Path: utzoo!mnetor!uunet!husc6!bbn!gatech!stratus!strick From: strick@stratus.UUCP (henry strickland) Newsgroups: comp.lang.c++ Subject: Re: C++ debugging? Message-ID: <1037@stratus.UUCP> Date: 12 Feb 88 19:45:16 GMT References: <41938@ti-csl.CSNET> <10053@ulysses.homer.nj.att.com> Reply-To: strick@stratus.UUCP (henry strickland) Organization: the clouds project -- computer science -- georgia tech Lines: 190 In article <41938@ti-csl.CSNET> ramey@ti-csl.UUCP (Joe Ramey) writes: >(I'm sure this question has been asked before, so perhaps someone with >a summary could forward it to me.) How well does dbx debug C++ code? I'm answering a different question: How do I use dbx to debug C++ code? (using AT&T's current release of C++, i.e. CC, cfront and munch): My preference is to keep the C intermediate file (*..c), and debug with respect to it. I prefer to have the line numbers used by dbx be the C line numbers. The C intermediate will then tell what line of the C++ source generated it. With X windows, I can keep 1) the C++ sources, 2) the C intermediates, and 3) my dbx session all on the screen. Without a native C++ debugger, the C intermediate is a necessary evil because of the modified variable names, baroque-looking (but beautifully straightforward in execution) code generated by inlines, etc. To do this, I edit the "CC" shell script to send the output of "cfront", which is the C intermediate, through a filter to convert the #line "filename" lineno lines into C comments /* #line "filename" lineno */ so that dbx will refer to the raw intermediate-C line number, yet in these comments I can find the corresponding C++ line numbers. The following lex script will do this: ( however, "sed" is too dangerous -- it mangles long lines. ) ================================================================== %% ^[#].*$ printf("\t\t/* %s */", yytext ); ================================================================== However, while I'm at it, I'll tell you what I really do. I name my C++ sources ".x", a contraction of the proposed ".cxx". I name my C intermediates ".i", a convention the sun C compiler understands. Now nothing interferes with normal ".c" files. Then I put the following rules in my makefile, and avoid the expense of running the CC script. Don't forget to "ld" with "-lC". ================================================================== .SUFFIXES: .o .i .x .s .c CXXI=/usr/include/CC/ .x.i: /lib/cpp -C -I$(CXXI) $*.x | cfront | line2com $*.i .x.o: /lib/cpp -C -I$(CXXI) $*.x | cfront | line2com $*.i /bin/cc $(CFLAGS) -c $*.i ================================================================== The following C program is used for "line2com", rather than the lex script I presented above. It does basically the same thing, but it is a bit more robust, in that it removes the $*.i file in the case that "cfront" terminates with a nonzero status, or in the case that it dies from a signal (such as the user's SIGINT). This is necessary so that "make" knows it must recompile. ================================================================== /* * line2com: change "#" lines into C comments * * Henry Strickland -- Georgia Tech Computer Science (clouds project) * * (known to work on a sun3 (4.2BSD) ) * * 9jan87 -- rather nasty code for such a simple concept * * usage: line2com [outname] * * reads standard input, makes "#line" lines into comments, * and writes to [outname] or to standard output. * * waits on any children (preprocessors, such as cfront, * in a pipe chain) and exits bad if any of them * exit bad. If we exit bad, we also unlink [outname], * if any. THIS IS IMPORTANT IF ONE USES PIPES. */ #include #include #define BIG 50000 char buf[BIG]; int p; /* process id returned from wait() */ union wait s; int stati; /* nonzero if any status nonzero */ int retval; /* exit value */ FILE *output; char *filename; char *cmdname; handler() { if (filename) unlink(filename); fprintf(stderr, "%s: KILLED!\n", cmdname ); exit(250); }; main(argc,argv) char *argv[]; { int i; /* figure out with what name we were invoked */ cmdname= argc>0? argv[0] : "line2com"; /* remove [outfile] if we are killed */ for ( i=1; i<16; i++) signal(i,handler); /* open the [outfile] or use stdout */ if ( argc>1 ) { filename= argv[1]; output= fopen( filename, "w" ); if ( !output ) { fprintf(stderr, "%d: ERR: cannot creat: "); perror( filename ); exit(1); } } else { output= stdout; } /* filter stdin to stdout */ while ( fgets(buf, BIG, stdin ) ) { if ( buf[0]=='#' ) { /* comment out all # lines */ fputs( "\t\t\t/*", output); buf[strlen(buf)-1]='\0'; /* remove \n */ fputs( buf, output); fputs( "*/\n", output); } else { /* copy all other lines verbatim */ fputs( buf, output); } } /* wait for any children. this _seems_ to work. */ do { extern errno; s.w_status=0; p=wait(&s); stati |= s.w_status; /* collect all stati */ /* fprintf(stderr,"%s: WAIT p%d s%08x e%d\n", cmdname, p, s.w_status, errno ); */ } while ( p>0 ); if ( stati ) { /* if any one of them had nonzero status */ /* try to find a decent exit() value */ retval= 255&( stati + (stati>>8) ); if (retval==0) retval=255; fprintf(stderr,"%s: EXIT(%d) (stati=%08x)\n", cmdname, retval, stati); /* remove [outfile] on errors */ if ( argc>1 ) unlink( filename ); exit(retval); } else { /* fprintf(stderr,"%s: EXIT GOOD\n", cmdname); */ exit(0); } }; ================================================================== Henry Strickland gatech!strick 404-676-1313 -- Henry Strickland gatech!strick 404-676-1313