Skip to content

Debugging with GDB

A debugger can be used to inspect the state of an application in the event of a crash.

Compile Debug Build

How to make a debug build depends on the build system used:

  • For Linux/macOS set: CMAKE_BUILD_TYPE=Debug in CMakeCache.txt
  • For Visual Studio, set the Release Configuration to Debug

Run GDB

Start GDB by changing the working directory to the location of your new debug build and typing one of the following, depending on the platform:

gdb blender.exe
gdb ./blender

Then to start Blender, type:

run

Now make Blender crash. Blender will freeze, so switch to the GDB prompt. Get a backtrace by typing:

bt

A more complete backtrace can be printed using:

thread apply all bt full

For more information, see this guide: How to Get a Backtrace.

Run Immediately

Blender can be made to run immediately:

gdb ./blender --ex=run --args ./blender

Run With Environment Variables Set

Blender can be run with environment variables using env.

These options disable some ASAN checks can interfere with debugging:

gdb ./blender --ex=run --args env ASAN_OPTIONS=check_initialization_order=0:leak_check_at_exit=0 ./blender

Pretty Printing

By default, GDB does not know how to print many Blender core types such as blender::Vector in a good way. The Blender source code contains a bunch of pretty printers that can be registered in GDB which simplify debugging.

To register those pretty printers add the following line to a ~/.gdbinit file. Everything in this file is run by GDB when it is started. Make to use the correct file path if the source code is elsewhere.

source ~/blender-git/blender/tools/debug/gdb/blender_gdb_extension.py

The following steps can check if the registration was successfull.

  1. Start gdb.
  2. Run info pretty-printer in GDB and check for blender-pretty-printers.

This also registers other utilities for GDB like frame filters. See blender_gdb_extension.py for details.

As an example, this is how a blender::Vector<int> with three elements is printed with and without pretty printers.

# Without
p vec
$1 = {begin_ = 0x7fffffffdaf8, end_ = 0x7fffffffdb04, capacity_end_ = 0x7fffffffdb08, allocator_ = {<No data fields>}, inline_buffer_ = {buffer_ = {buffer_ = {buffer_ = {4, 0, 0, 0, 7, 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0}}}}, debug_size_ = 3}

# With
p vec
$1 = Size: 3 = {4, 7, 6}