Debugging C++

From Apertium
Jump to navigation Jump to search

Using gdb to debug lttoolbox/apertium

gdb is the GNU Project debugger, which lets you put breakpoints in C++ (and other languages), inspect local variables and so on. It is useful.

To start using gdb, you first have to recompile with the -g option sent to gcc:

$ sh autogen.sh  # ensure autotools are set up
$ make clean     # force a full recompile
 # these options turn gdb-support on and optimisation off for C, C++ and linking:
$ ./configure CFLAGS="-ggdb3 -O0" CXXFLAGS="-ggdb3 -O0" LDFLAGS="-ggdb3"
$ make

Most gdb-tutorials will tell you to start gdb like gdb path/to/binary. However, since apertium/lttoolbox uses libtool, files like trunk/lttoolbox/lttoolbox/lt-comp are actually not binaries, but wrapper scripts which ensure the correct libraries are loaded. Since gdb doesn't understand these wrapper scripts, we need to wrap the gdb call with libtool. If you want to debug lt-comp, you start gdb like this (assuming you are in trunk/lttoolbox):

$ libtool --mode=execute gdb lttoolbox/lt-comp

And it should give you some output and the (gdb) prompt:

Current directory is ~/src/apertium/trunk/lttoolbox/
GNU gdb (GDB) 7.5.1
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from ~/src/apertium/trunk/lttoolbox/lttoolbox/.libs/lt-lt-comp...done.
(gdb) 

Now you can pass command-line arguments, set a breakpoint and run the program:

(gdb) set args lr foo.dix foo.bin
(gdb) break lt_comp.cc:52
(gdb) run

In Emacs

GDB running in Emacs

Do M-x gdb and you'll be asked "Run gdb (like this):", change it to say libtool --mode=execute gdb -i=mi lttoolbox/lt-comp and press return. In the main menu, you can click Gud → GDB-MI and tick off Display Other Windows (or type M-x gdb-many-windows to toggle showing of the breakpoint list, local variables, stacktrace etc.

No line numbers in gdb?

See https://www.mail-archive.com/cygwin@cygwin.com/msg86175.html for some ways to debug the lack of debug info

Valgrind

Valgrind is another debugging tool that lets you profile programs, check for memory leaks, and much much much more.

As with gdb, use the libtool wrapper when running Valgrind:

$ libtool --mode=execute valgrind lttoolbox/lt-comp lr foo.dix foo.bin


Other C++ tips

faster re-compilation with ccache

ccache is a compiler cache – it detects when the same compilation is re-run, and re-uses the old results

On Ubuntu/Debian, first do

sudo apt install ccache

then in e.g. an autotools project, do

./configure CC="ccache gcc" CXX="ccache g++"
make

faster linking in autotools-projects with ld.gold

(e.g. in hfst) ld.gold is about 3x faster than the standard ld.bfd

binutils on Ubuntu/Debian includes ld.gold already

just do

export CXXFLAGS='-fuse-ld=gold'
export CFLAGS='-fuse-ld=gold'
./configure 
make -j4 

faster linking in cmake-projects with ld.lld

(e.g. in vislcg3) ld.lld is even faster than ld.gold

On Ubuntu/Debian, first do

sudo apt install lld-4.0
sudo ln -s /usr/bin/ld.lld-4.0 /usr/bin/ld.lld  # Why doesn't Debian put this in /etc/alternatives by default?

then in the cmake project, just

./cmake.sh -DCMAKE_C_FLAGS="-fuse-ld=lld" -DCMAKE_CXX_FLAGS="-fuse-ld=lld"
make -j4