Noeud:The Fourth Bug, Noeud « Next »:, Noeud « Previous »:Success! ...or is it?, Noeud « Up »:An example debugging session using gdb



The Fourth Bug

Let's fire up gdb and see what's going on.

     bash$ gdb ecount4
     (gdb) list 30
     25
     26	  strcpy( buf, argv[1] );
     27
     28	  /* print it out to show we received it correctly
     29
     30	  printf( "The word is '%s'\n", buf );
     31
     32	  /* Now step through counting letter 'e's */
     33
     34	  for( i=0; i<strlen(buf); ++i )
     (gdb) b 30
     

We've started gdb, looked at the lines around line 30 and seen nothing obviously wrong. Notice we have given the list command a line number to work with - it will display lines centred on the supplied line number.

Then we've set a breakpoint on line 30, using b 30. Many gdb commands can be abbreviated to their shortest unique abbreviation.

The next step is to run the program. It should stop on the line which seems not to be being executed.

     Breakpoint 1 at 0x80484d8: file ecount4.c, line 30.
     (gdb) run example
     Starting program: /home/paul/gnuprog2/src/debugging/ecount4 example
     
     Breakpoint 1, main (argc=2, argv=0xbffff914) at ecount4.c:34
     34	  for( i=0; i<strlen(buf); ++i )
     

Well it *should* have stopped on line 30, but it has actually stopped at line 34, at the start of the counting loop. Let's stop the program in mid-execution and put a breakpoint earlier, so we can see what happens.

     (gdb) kill
     Kill the program being debugged? (y or n) y
     (gdb) b 26
     Breakpoint 2 at 0x80484c0: file ecount4.c, line 26.
     (gdb) run
     Starting program: /home/paul/gnuprog2/src/debugging/ecount4 example
     
     Breakpoint 2, main (argc=2, argv=0xbffff914) at ecount4.c:26
     26	  strcpy( buf, argv[1] );
     (gdb) n
     
     Breakpoint 1, main (argc=2, argv=0xbffff914) at ecount4.c:34
     34	  for( i=0; i<strlen(buf); ++i )
     

kill will stop the program being run, taking it back to the state it was in when gdb first started up. All breakpoints, displays etc. will remain set up, so this is useful for cases like this where we want to keep going over the same part of a program without exiting and re-entering gdb and setting up all the breakpoints again.

When we run it again, we see that it definitely goes from line 26 (strcpy()) to line 34 (for() loop). There is no doubt in gdb's mind that line 30 is just not there. The only way this could happen is if it was removed by the preprocessor, either by a macro substitution or a comment.

Closer examination reveals that the comment on line 28 is not closed - so the preprocessor will have just carried on reading and throwing lines of code away until it came to a comment closing sequence - '*/'. This is on line 32, which explains why line 30 was being missed out.