When you have finally gotten your program to compile and link without errors you can run it and see if it works. It probably won't. This is not me saying you are a bad programmer, this is me saying you are a human being. Programs of significant size never work right the first time. Some problems can be solved by familiarity with the code and watching the behavior of the program, or by looking through the source code. But there comes a time where you would like to see what the program is actually doing inside. This is what a debugger allows you to do. The debugger for the GNU compiler suite is called gdb.
Note: Although I discuss gdb here, I don't actually use it right now. For some reason all programs compiled with Mingw32 report a SIGSEGV when run under the version of gdb I am using. I am working on tracking down this problem (it might be a Windows 95/98 thing, as other people seem to be able to use gdb with Mingw32 programs).
In order to use a debugger first you have to compile with debugging information included. The option to do this with gcc is -g. At both the compiling and linking steps simply include the -g option like this:
gcc -g -c -o foo.o foo.c
gcc -g -c -o bar.o bar.c
gcc -g -o foobar.exe foo.o bar.o
To compile with debugging information using the Mingw32 version of Jam all you have to do is set the environment variable DEBUG to some value (e.g. 1) or run jam like this:
jam -s DEBUG=1
You can run the debugger like this:
gdb foobar.exe
This will set up gdb to debug the program foobar.exe and will give you the gdb prompt, from which you can run commands to debug the program. At the gdb prompt type the command help to get help.
The command list or l will list the next ten lines in the current source file. Using the command with a line number will list the lines around the given line in the current source file. Using l with a function name will list the lines around the beginning of that function.
To switch to a different source file use the following form.
list foo.c:1
This lists the first few lines of the file foo.c and sets the current source file to foo.c.
Generally you will not want to trace through the whole program, so you should set breakpoints at the functions you are interested in. This will cause the program to pause and allow you to use other gdb commands whenever the program hits the indicated point in the source code. The command for setting a breakpoint is b, like this:
b WinMain
That will set a breakpoint at the beginning of the function WinMain.
You can start the program running with the run or r command. You can type arguments to pass to the program after r just like you were running the program on the command line.
When the program is stopped at some point you can display the contents of variables using the print command:
print n
That prints the contents of the variable n. You can also print the contents of structures, C++ objects and arrays like that. gdb will try to figure out the correct type from context.
You can set the program running again after hitting a breakpoint by using the c command.
You can continue one step at a time through a program using the step or s and the next or n commands.
Type q to exit gdb. Generally it is best to do this only after the program being debugged has finished.