Chapter P5. The debugging of C programs

Goals for this chapter:
  • gdb (gdb)
  • make (make)
  • cc (cc)
  • strip (binutils)
  • touch (fileutils)
  • xxgdb (xxgd)
  • ddd (ddd)
Don't interrupt me while I'm interrupting.
Winston S. Churchill.

"Given enough eyeballs, all bugs are shallow."
Eric S. Raymond

What is a debugger ?

This is the chapter about debuggers. The debug or debugger is the name that US programmers assign to a program, the debug capable to trace the program execution step-by-step following the original source(s).

The word "debug" means no bugs, following the common name "bug", used to understand the small misfunctions inside the code.

The "gdb" debugger

In Linux, an OpenSource GNU based Operating System, the normal debug is the "gdb", GNU debugger. Of course because GNU supports C, C++, Fortran, Java and also Ada, the debuggers must also support the debugging of these languages.

To compile a program that we plan to debug we need to compile it with the "-g" flag. Otherwise the symbolic information will not be included.

[root@ftosx1 Chap4]# gcc -g malloc.c -o malloc

Then, we can launch the debugger with the binary that we will debug, as a parameter.

[root@ftosx1 Chap4]# gdb malloc
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-COL-linux"...
(gdb) list
15      #define MAX_DB 100
16
17      static student *db[MAX_DB];
18
19      main ()
20      {
21              FILE *fp;
22              student john;
23          char line[BUFSIZ], * tmp ;
24              int i = 0;
(gdb)

and we are get started to debug our source!

Have no sense repeat the steps from the text based and the graphical. We prefer to describe the debugging in "ddd". Of course, this assumption suppose that all the programmers have only a graphical display, that generally, have sense in these days.

The graphical interface for gdb: "xxgdb"

The fist implementation for a graphical debugger was the "xxgdb". The original edition comes from Sun Microsystem graphical front-end.




To fix breakpoints, remove it, run the program, re-run the program, display (that is visualize all the variables with a trace),

This debugger also uses its own ".gdbinit" file, where we can load a specific set of debugger commands.

"xxgdb" is the classical debugger. I use for the first time in 1989 on a Sun Sparcstation 1+.
 

The Data Display Debugger "ddd"

A modern graphical front-end for the gdb is the "ddd" that stand for Data Display debugger.
 
 



While "xxgbd" uses Xt libraries, "ddd" used Gtk libraries supporting also Themes and other features. Both "xxgdb" and "ddd" are equivalent, probably "xxgdb" will be more classical and need less memory because based on X11 basic library, Xt, instead of Gtk.
 

A debugging session

Now, we will present a simple step-by-step example.

To start we need to compile the program with "-g" and then execute the debugger with the program as a parameter.
 

[root@ftosx1 Chap4]# xxgdb malloc

We present here the masks:
 

Here we move with the mouse or the arrow key and then click "break" Then, we need to run the program, and therefore click "run".

So, we get the previous screen.

Now, we hit "next" to proceed with the next program step. Now, we display a variable "tmp".

Note the command: display next.

The program output is displayed in the same zone. We can also print a specific variable with 
print *db[i]

Here we list a table about the debugger commands:

Tracing the execution of a program

As we note before to trace a program we need to press or write "step" in the debugger prompt. However, there are another command called "next" that execute the entire function.

We can also use "up" and "down" to back up or back down in the functions stack: main(), func1(), ...

We can also continue or interrupt a cycle.

For example, we can ask what are we located in the code:

(xxgdb) info stack
#0  main () at malloc.c:61
#1  0x4003d1fa in __libc_start_main () from /lib/libc.so.6
(xxgdb)

Or we may ask, what type is the following variable:

(xxgdb) whatis db[i]
type = student *
(xxgdb)

Or where is used:

(xxgdb) where db[i]
#0  main () at malloc.c:61
#1  0x4003d1fa in __libc_start_main () from /lib/libc.so.6
(xxgdb)

How to set up breakpoints

To set breakpoint is quite simple. We simply need to go to the code and fix a breakpoint pressing the button "break".
 

How to print data in the debugger

There are two basic: "xxgdb" supports also the possibility to select a variable and then print the relative button.
 

Some hints to debug graphical programs.

Debug a text based program is quite simple but debug a graphical programs is another thing. For example, in 1989 to debug Microsoft Windows 2.11 applications was necessary to use two monitors, one of the debugger and one to display the program.

In UNIX and Linux, this is generally never was necessary. To debug a text-based program like "mc" Midnight Commander or other we need simply a good debugger. Also to debug a graphical C application, in Motif generally we need to know only some debugger techniques as we introduce here.

However, to debug a C++ based graphical application, like a Qt application, generally is necessary to use a MessageBox. Qt for example includes the QtMessageBox. For debugging purpose is just perfect.

C++ debugging is more complex, but not impossible. It is simply a little more complicated, basically in the sense that C is compared with C++.
 

Exercises

  1. Download a C source and try to understand the C Data Declaration and the logical operators


Test

  1. What is a debugger ?
  2. Why was invented ?
  3. Any compiled program would be debuggable ?
  4. Would be necessary to add some special flag at compilation time to debug the program ?
  5. Would be possible to install themes with "ddd" ?
  6. What are "ddd" and "xxgdb" program about the gdb ?
  7. Would be possible to restart the debugging process after we start ?
  8. Is possible to print a structure using a debugger ?
  9. What is the core file ?
  10. List seven common buttons or instructions in debugger ?
  11. Describe a common debugging session.
  12. What is the difference between "step" and "next" ?
  13. What does "down" and "up" commands ?
  14. What does the "display" debugger command ?
  15. Where we get the program output ?
  16. How we can add arguments when we debug a program ?
  17. Is possible to know the data type from the debugger ?
  18. What does the "stack" command, inside a debugger session ?
  19. Is possible to edit the source from the debugger ?
  20. Is possible to modify and recompile the source from the debugger ?
  21. What results we will get ... if we are compiling a binary and debuggin the same binary? It is possible ?
  22. What is the Linux command that set the filesize for a core ?
  23. What company or organization develop the "gdb" ?
  24. What happens if we built a binary with a "i386-redhat-linux" compiler and try to debug with a "i386-ftosx-linux" compiler ? What is the relevant element in the discussion ?
  25. How is the normal mode to debug a graphical application ?
  26. Is possible to debug a Tcl source ?
Consult the answers

Check the Interactive Exam Cram Programming: Try the interactive cram ...

Internet Resources for this Chapter.