A lot of people frequently have questions about debugging GCC. In particular, how to debug the compiler itself, instead of the driver.
Here is a quick rundown:
Assuming you've produced preprocessed source (see the bug reporting directions for how to do this), and have a debuggable compiler built somewhere, you can simply do
gdb --args <location of cc1, cc1plus, or whatever compiler for the language the preprocessed source file is in> <flags passed to compiler>
This will enable you to debug the compiler itself, instead of the driver.
You can also use the driver's -### option which writes the commands that the driver would execute. For example,
gdb --args $(./xgcc -### <parameters to the driver> 2>&1 | fgrep cc1)
There are scripts that automate all of this for you here that make debugging a front-end much simpler.
While stepping through a front-end within a debugger, you can use the debug_tree() and debug_rtx() functions to print out the structure of a tree node or RTL expression respectively.
GCC itself is normally compiled at -O2 which makes stepping through code a bit difficult. You should use GDB 6.3 (or a newer version), which can work properly with location lists generated by newer GCCs that help in debugging in such cases. Another useful trick is to only compile the particular module you are interested in at a lower optimisation level. For example, if you are debugging parse.y in the Java front-end, you can use:
$ touch $GCC_SRC_DIR/gcc/java/parse.y $ make BOOT_CFLAGS='-O0 -g3'
If you use GDB to debug GCC and you run the debugger from within the $GCC_BUILD_DIR/gcc folder, you get to automatically use the .gdbinit file created there by the build process. It defines a few handy macros to help debug GCC. See the file $GCC_SRC_DIR/gcc/gdbinit.in for details.
Building a Debuggable Compiler
To build a debuggable compiler, configure the compiler normally and then
make STAGE1_CFLAGS="-g -O0" all-stage1
Some people like to add CFLAGS=-g3 which makes macros debuggable:
make STAGE1_CFLAGS="-g3 -O0" all-stage1
By default stage1 only includes the C compiler. If you need to work on a different frontend, you can configured with --enable-stage1-languages=LANGUAGES to build other languages as part of stage1.
If you have a release source and you want to enable internal checking, configure the compiler with --enable-checking (this option is already enabled if you downloaded the source from SVN). See Installing GCC: Configuration for description of available types of checks.
Randomization
You may want to read up on Randomization and disable it if you would like reproducible results.
Debugging within (x)emacs
Basically you're editing one of the files of the compiler, say tree-foo.c, when suddenly you want to debug its code. The following commands should get it right:
C-x 2 M-x gdb ../../objdir/gcc/cc1 C-x o C-x <space> C-x o (gdb) run -O2 -ftree-foo ~~/foo.i
First, you split the window, then run the debugger on the compiler cc1. The C-x <space> sets a breakpoint at the cursor. Finally you run the compiler with the usual options on the preprocessed file foo.i.
Dumping the Intermediate Representation
Read http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html for all the debugging options from -d* to -fdump-tree-*.
Debugging the Ada Compiler
If you run the debugger on ../../objdir/gnat1, you get an error message:
fatal error, run-time library not installed correctly cannot locate file system.ads compilation abandoned
For correcting this error, simply invoke the following command at the gdb prompt:
(gdb) set env ADA_INCLUDE_PATH path_to_objdir/gcc/ada/rts
If you have a testsuite failure, in the logfile testsuite/gcc/ada/acats/acats.log you can find lines like
gnatmake --GCC="/abuild/rguenther/obj2/gcc/xgcc -B/abuild/rguenther/obj2/gcc/" -gnatws -O2 -I/abuild/rguenther/obj2/gcc/testsuite/ada/acats/support ca11c01.adb -largs --GCC="/abuild/rguenther/obj2/gcc/xgcc -B/abuild/rguenther/obj2/gcc/"
that you can nearly literaly use to re-generate the testcase binary. Use find to find the ca11c01.adb source file and use the gnatmake built in the gcc/ directory. For the gnatmake command to function properly you need to set the following environment variables:
export ADA_INCLUDE_PATH=/abuild/rguenther/obj2/gcc/ada/rts export ADA_OBJECTS_PATH=/abuild/rguenther/obj2/gcc/ada/rts
Additional tips on Linux
Most linux systems (with a 2.6 kernel) have address space randomization, and you'll better disable it to have more reproducible runs (i.e. get the same pointer addresses from one run to the next). To disable it globally, do
echo 0 > /proc/sys/kernel/randomize_va_space
as root. Better yet, disable it in your shell with
setarch -R
Don't forget that disabling address space randomization may open some security issues.
Debugging LTO
See this thread