Skip to article frontmatterSkip to article content

Debugging C++ with GDB

Authors: Tiago P. Peixoto1, Lena Mangold1
Affiliations: 1Inverse Complexity Lab
License: CC-BY

GDB stands for GNU Debugger, and it provides a more robust debugging infrastructure than using print statements in your code.

A simple introduction to using GDB can be read here. Please take a look there.

To debug some C++ code that is called from python, you should call gdb with the python interpreter:

$ gdb `which python`
GNU gdb (GDB) 16.3
Copyright (C) 2024 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-pc-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /sbin/python...
Downloading separate debug info for /usr/bin/python3.13
Reading symbols from /home/count0/.cache/debuginfod_client/76195980c4ccf58a63406c313d47a475eabc0bbe/debuginfo...
(gdb)

You can then load your script my_script.py with:

(gdb) set args ./my_script.py
(gdb) run

Recompile with debug symbols

GDB works best when debug symbols are included during compilation. This can be done using the -g flag during compilation.

It is also possible to include a DEBUG flag in the Makefile, as is shown in the following example. Compiling in debug mode will then include debug symbols (-g), disable optimisation (-00), and enable assert() by omitting -DNDEBUG.

CXX=g++

DEBUG ?= 0

ifeq ($(DEBUG), 1)
    CXXFLAGS=-g -O0 -fopenmp -std=gnu++17 -Wall -fPIC -DPIC `pkg-config --cflags graph-tool-py` -DBOOST_ALLOW_DEPRECATED_HEADERS
else
    CXXFLAGS=-O3 -fopenmp -std=gnu++17 -Wall -fPIC -DPIC `pkg-config --cflags graph-tool-py` -DBOOST_ALLOW_DEPRECATED_HEADERS -DNDEBUG
endif

LDFLAGS=`pkg-config --libs graph-tool-py` -shared

SOURCES=$(shell echo *.cc)
HEADERS=$(shell echo *.hh)
OBJECTS=$(SOURCES:.cc=.o)

TARGET=libexample.so

all: $(TARGET)

clean:
	rm -f $(OBJECTS) $(TARGET)

$(OBJECTS): %.o: %.cc %.hh example.hh
	$(CXX) $(CXXFLAGS) -c $< -o $@

$(TARGET): $(OBJECTS)
	$(CXX) $(CXXFLAGS) $(OBJECTS) -o $@ $(LDFLAGS)

To recompile in debug mode, run

make clean
make DEBUG=1

Useful GDB commands

CommandDescription
run (r)Run the program until it finishes, crashes, or hits a breakpoint
startRun and pause at the first line of main()
next (n)Execute the next line (step over function calls)
step (s)Execute the next line (step into function calls)
continue (c)Resume execution until the next breakpoint or crash
break file.hh:N or b file.hh:NSet a breakpoint at line N in file.hh
break funcSet a breakpoint at function func()
deleteRemove all breakpoints
print var or p varPrint the value of variable var
list (l)Show source code around current line
info localsShow all local variables
quit (q)Exit GDB

Workflow Example (for C++ code called from Python)

If the Makefile includes the DEBUG flag and the make clean command as in the example Makefile above, the following is an example workflow for debugging C++ code that is called from Python.

make clean                       # Delete compiled .o files and output .so files
make DEBUG=1                     # Compile with debug flag
gdb `which python`               # Start GDB
(gdb) set args ./my_script.py    # Load your script
(gdb) break headerfile.hh:N      # Set a breakpoint in line N in headerfile.hh
(gdb) run                        # Run and pause at breakpoint
(gdb) info locals                # Show local variables
(gdb) next                       # Step over some line
(gdb) print alpha                # Check value of variable alpha
(gdb) continue                   # Resume until crash or breakpoint
(gdb) quit                       # Exit