Normally three debugging techniques which are popular:
- Non-interactive
- GNU gdb
- dbx
You can debug your code by placing #ifdef DEBUG and corresponding #endif statements around debug code. For example:
#ifdef DEBUG
PRINTF(("Variables Currently Contain: %d, %f, %s\n", *pi, *pf[1], str));
#endif
You can specify a DEBUG define at compile time by issuing gcc with the -DDEBUG command option.
Note: This can be even further simplified into a single command called DPRINTF, so you don't even have to write the #ifdef #endif directives!
Debugging Using GDB
gdb is a powerful program in tracking down Segmentation Faults and Core Dumps. It can be used for a variety of debugging purposes though.
First thing you must do is compile with the -g option and without any optimization (i.e. no -O2 flag).
Once you do that, you can run gdb . where is the name of the executable.
gdb should load with the executable to run on. Now you can create breakpoints where you want the the execution to stop. This can be specified with the line number in the corresponding c source file. For example: break 376 would instruct gdb to stop at line 376.
You can now run the program by issuing the run command. If your program requires command-line options or parameters, you can specify them with the run command. For example: run 4 -s Doc! where 4, -s, Doc! are the parameters.
The program should run until the breakpoint or exit on a failure. If it fails before the breakpoint you need to re-examine where you should specify the break. Repeat the breakpoint step and rerun. If your program stops and shows you the breakpoint line, then you can step into the function. To step into the function use the step command. NOTE: Do not step into system library calls (e.g. printf). You can use the command next over these types of calls or over local function calls you don't wish to step into. You can repeat the last command by simply pressing enter.
You can use the continue command to tell gdb to continue executing until the next breakpoint or it finishes the program.
If you want to peek at variables, you can issue the print command on the variable. For example: print mystruct->data.
You can also set variables using the set command. For example: set mystruct->data = 42.
The ptype command can tell you what type a particular variable is.
The commands instruction tells gdb to set a particular number of commands and to report them to you. For example, commands 1 will allow you to enter in a variable number of other commands (one per line, end it with "end"), and will report those commands to you once breakpoint 1 is hit.
The clear command tells gdb to clear a specified breakpoint.
The list command can tell you where you are at in the particular code block.
You can specify breakpoints not only with lines but with function names.
For more information on other commands, you can issue the help command inside gdb.
Debugging using DBX
dbx is a multi-threaded program debugger. This program is great for tracking down memory leaks. dbx is not found on linux machines (it can be found on Solaris or other *NIX machines).
Run dbx with the executable like gdb. Now you can set arguments with runargs.
After doing that, issue the check -memuse command. This will check for memory use. If you want to also check for access violations, you can use the check -all command.
Run the program using the run command. If you get any access violations or memory leaks, dbx will report them to you.
Run the help command if you need to understand other commands or similar gdb commands.