A Sample DDD Session

You can use this manual at your leisure to read all about DDD. However, a handful of features are enough to get started using the debugger. This chapter illustrates those features.

The sample program sample.c (see Sample Program) exhibits the following bug. Normally, sample should sort and print its arguments numerically, as in the following example:

     $ 

**Illegal HTML tag removed :** ./sample 8 7 5 4 1 3

     1 3 4 5 7 8
     $ _
     

However, with certain arguments, this goes wrong:

     $ 

**Illegal HTML tag removed :** ./sample 8000 7000 5000 1000 4000

     1000 1913 4000 5000 7000
     $ _
     

Although the output is sorted and contains the right number of arguments, some arguments are missing and replaced by bogus numbers; here, 8000 is missing and replaced by 1913.3

Let us use DDD to see what is going on. First, you must compile sample.c for debugging (see Compiling for Debugging), giving the -g flag while compiling:

     $ 

**Illegal HTML tag removed :** gcc -g -o sample sample.c

     $ _
     
  • Sample Program: Source sample.c

Now, you can invoke DDD (see Invocation) on the sample executable:

     $ 

**Illegal HTML tag removed :** ddd sample

     

After a few seconds, DDD comes up. The Illegal HTML tag removed : Source Window contains the source of your debugged program; use the Illegal HTML tag removed : Scroll Bar to scroll through the file.

PICS/tut-invoke.jpg

The Illegal HTML tag removed : Debugger Console (at the bottom) contains DDD version information as well as a GDB prompt.4

     GNU DDD Version 3.3.9, by Dorothea L�tkehaus and Andreas Zeller.
     Copyright © 1995-1999 Technische Universit�t Braunschweig, Germany.
     Copyright © 1999-2001 Universit�t Passau, Germany.
     Copyright © 2001-2004 Universit�t des Saarlandes, Germany.
     Reading symbols from sample...done.
     (gdb) _
     

The first thing to do now is to place a Illegal HTML tag removed : Breakpoint (see Breakpoints), making sample stop at a location you are interested in. Click on the blank space left to the initialization of a. The Illegal HTML tag removed : Argument field (): now contains the location (sample.c:31). Now, click on Break to create a breakpoint at the location in (). You see a little red stop sign appear in line 31.

The next thing to do is to actually Illegal HTML tag removed : execute the program, such that you can examine its behavior (see Running). Select Program => Run to execute the program; the Run Program dialog appears.

PICS/tut-run.jpg

In Run with Arguments, you can now enter arguments for the sample program. Enter the arguments resulting in erroneous behavior here--that is, 8000 7000 5000 1000 4000. Click on Run to start execution with the arguments you just entered.

GDB now starts sample. Execution stops after a few moments as the breakpoint is reached. This is reported in the debugger console.

     (gdb) break sample.c:31
     Breakpoint 1 at 0x8048666: file sample.c, line 31.
     (gdb) run 8000 7000 5000 1000 4000
     Starting program: sample 8000 7000 5000 1000 4000

     Breakpoint 1, main (argc=6, argv=0xbffff918) at sample.c:31
     (gdb) _
     

The current execution line is indicated by a green arrow.

     => a = (int *)malloc((argc - 1) * sizeof(int));
     

You can now examine the variable values. To examine a simple variable, you can simply move the mouse pointer on its name and leave it there. After a second, a small window with the variable value pops up (see Value Tips). Try this with argc to see its value (6). The local variable a is not yet initialized; you'll probably see 0x0 or some other invalid pointer value.

To execute the current line, click on the Next button on the command tool. The arrow advances to the following line. Now, point again on a to see that the value has changed and that a has actually been initialized.

PICS/tut-value.jpg

To examine the individual values of the a array, enter a[0] in the argument field (you can clear it beforehand by clicking on ():) and then click on the Print button. This prints the current value of () in the debugger console (see Printing Values). In our case, you'll get

     (gdb) print a[0]
     $1 = 0
     (gdb) _
     

or some other value (note that a has only been allocated, but the contents have not yet been initialized).

To see all members of a at once, you must use a special GDB operator. Since a has been allocated dynamically, GDB does not know its size; you must specify it explicitly using the @ operator (see Array Slices). Enter a[0]@(argc - 1) in the argument field and click on the Print button. You get the first argc - 1 elements of a, or

     (gdb) print a[0]@(argc - 1)
     $2 = {0, 0, 0, 0, 0}
     (gdb) _
     

Rather than using Print at each stop to see the current value of a, you can also Illegal HTML tag removed : display a, such that its is automatically displayed. With a[0]@(argc - 1) still being shown in the argument field, click on Display. The contents of a are now shown in a new window, the Illegal HTML tag removed : Data Window. Click on Rotate to rotate the array horizontally.

PICS/tut-display.jpg

Now comes the assignment of a's members:

     =>  for (i = 0; i < argc - 1; i++)
             a[i] = atoi(argv[i + 1]);
     

You can now click on Next and Next again to see how the individual members of a are being assigned. Changed members are highlighted.

To resume execution of the loop, use the Until button. This makes GDB execute the program until a line greater than the current is reached. Click on Until until you end at the call of shell_sort in

     =>  shell_sort(a, argc);
     

At this point, a's contents should be 8000 7000 5000 1000 4000. Click again on Next to step over the call to shell_sort. DDD ends in

     =>  for (i = 0; i < argc - 1; i++)
             printf("%d ", a[i]);
     

and you see that after shell_sort has finished, the contents of a are 1000, 1913, 4000, 5000, 7000--that is, shell_sort has somehow garbled the contents of a.

To find out what has happened, execute the program once again. This time, you do not skip through the initialization, but jump directly into the shell_sort call. Delete the old breakpoint by selecting it and clicking on Clear. Then, create a new breakpoint in line 35 before the call to shell_sort. To execute the program once again, select Program =&gt; Run Again.

Once more, DDD ends up before the call to shell_sort:

     =>  shell_sort(a, argc);
     

This time, you want to examine closer what shell_sort is doing. Click on Step to step into the call to shell_sort. This leaves your program in the first executable line, or

     => int h = 1;
     

while the debugger console tells us the function just entered:

     (gdb) step
     shell_sort (a=0x8049878, size=6) at sample.c:9
     (gdb) _
     

This output that shows the function where sample is now suspended (and its arguments) is called a Illegal HTML tag removed : stack frame display. It shows a summary of the stack. You can use Status =&gt; Backtrace to see where you are in the stack as a whole; selecting a line (or clicking on Up and Down) will let you move through the stack. Note how the a display disappears when its frame is left.

PICS/tut-backtrace.jpg

Let us now check whether shell_sort's arguments are correct. After returning to the lowest frame, enter a[0]@size in the argument field and click on Print:

     (gdb) print a[0] @ size
     $4 = {8000, 7000, 5000, 1000, 4000, 1913}
     (gdb) _
     

Surprise! Where does this additional value 1913 come from? The answer is simple: The array size as passed in size to shell_sort is too large by one--1913 is a bogus value which happens to reside in memory after a. And this last value is being sorted in as well.

To see whether this is actually the problem cause, you can now assign the correct value to size (see Assignment). Select size in the source code and click on Set. A dialog pops up where you can edit the variable value.

PICS/tut-set.jpg

Change the value of size to 5 and click on OK. Then, click on Finish to resume execution of the shell_sort function:

     (gdb) set variable size = 5
     (gdb) finish
     Run till exit from #0  shell_sort (a=0x8049878, size=5) at sample.c:9
     0x80486ed in main (argc=6, argv=0xbffff918) at sample.c:35
     (gdb) _
     

Success! The a display now contains the correct values 1000, 4000, 5000, 7000, 8000.

PICS/tut-finish.jpg

You can verify that these values are actually printed to standard output by further executing the program. Click on Cont to continue execution.

     (gdb) cont
     1000 4000 5000 7000 8000

     Program exited normally.
     (gdb) _
     

The message Program exited normally. is from GDB; it indicates that the sample program has finished executing.

Having found the problem cause, you can now fix the source code. Click on Edit to edit sample.c, and change the line

     shell_sort(a, argc);
     

to the correct invocation

     shell_sort(a, argc - 1);
     

You can now recompile sample

     $ 

**Illegal HTML tag removed :** gcc -g -o sample sample.c

     $ _
     

and verify (via Program =&gt; Run Again) that sample works fine now.

     (gdb) run
     `sample' has changed; re-reading symbols.
     Reading in symbols...done.
     Starting program: sample 8000 7000 5000 1000 4000
     1000 4000 5000 7000 8000

     Program exited normally.
     (gdb) _
     

All is done; the program works fine now. You can end this DDD session with Program =&gt; Exit or Illegal HTML tag removed : Ctrl+Q.

Node:Sample Program, Up:Sample Session

results matching ""

    No results matching ""