Debugging with GDB

Loading the program

To load a program for debugging simply pass it to gdb

gdb <executable>

Or with command line argumetns

gdb --args <executable> -e foo -l bar

Debugging programs using libtool

To execute gdb for a program using libtool from it's build directory you can use:

libtool --mode=execute gdb <executable>

this makes sure LD_LIBRARY_PATH etc. is setup correctly.

Breaking

Once the program is loaded we can start to examin it. To stop program execution at a certain position we can use a breakpoint. Once the program hits the breakpoint you can step through the code. First set a breakpoint

break <file>:<function>
break <file>:<linenumeber>

Stepping

Once you broke out of program execution you can step through the code. To show the source code around the current execution point:

list

Step to the next statement in the current function:

next

Step to the next statement following function calls:

step

Other useful commands:

  • finish: run until the function exits and print it's return value
  • print: print the value of a variable
  • directory: specify source code location
  • set substitute-path: define a source path substitution to look for the source at a different location
  • watch a location being written to:

    watch -l self->pointer
    

Backtrace

The current stacktrace can be inspected using bt. bt full additionally includes the values of local variables. In threaded programs use thread apply all bt to see all threads.

Calling functions

To call functions use:

call g_hash_table_lookup (priv->sockets_by_msg, msg)

Configuration

Add this to ~/.gdbinit

# save all history into one file
set history filename ~/.gdb_history
# save history
set history save on

Miscelanous

Generating a core file

On some systems the limit for core files size is 0, change that to unlimited to make the system generate core files on e.g. SEGV:

ulimit -c unlimited

On systemd bases systems use coredumpctl.

Aborting on GTK warnings

To abort on the first encountered glib/GTK+ warning use:

<program> --g-fatal-warnings

or

G_DEBUG=fatal-warnings <program>

Printing Glib messages

Print all messages:

G_MESSAGES_DEBUG=all <program> 

See the Glib manual for details.

Debugging Wayland and OpenGL

  • Wayland protocoll calls: export WAYLAND_DEBUG=1
  • EGL: export EGL_LOG_LEVEL=debug
  • Log GL errors (if application does not call glGetError): export MESA_DEBUG=1

See https://www.mesa3d.org/egl.html

Other tools

  • valgrind
  • strace, ltrace, bpftrace
  • sysprof
  • eBPF

Packages

Debugging things in a vm is useful if you don't want to hose your production system. This needs the following packages in the guest:

apt -y install vim-nox gdb gdb-doc build-essential exuberant-ctags libc6-dbg git git-buildpackage ccache strace valgrind

And when debugging GTK/GLib related problems:

apt -y libglib2.0-0-dbgsym libgtk-4-1-dbgsym vim-syntax-gtk