How to debug an installed Qt5 library with GDB

debuggingqt

Background: I am programming with Qt5 and want to debug the core Qt5 libraries on Debian using GDB.

I have installed all the necessary -dev and -dbg packages. When I try to debug, GDB complains that the source code is not found.

How to install source code and use within GDB?

Best Answer

I am answering my own question. This was harder than I expected, and I want to gather all the information in one convenient place.

Install Binary, Development, and Debug Packages

This can be done using apt (or aptitude).

Example for Qt5:

  • Compiled libraries: qt5-default
  • Development package (headers): qtbase5-dev
  • Debugging symbols: qtbase5-dbg

Find Source Package Name

You can find it using aptitude or the Debian package search tool: https://www.debian.org/distrib/packages#search_packages

Example: Searching for qtbase5-dbg will find: https://packages.debian.org/jessie/qtbase5-dbg

The top of each binary package page has a link to the source package.

Example: qtbase-opensource-src

Install Source Package

If necessary, first configure your apt source package repositories by reading this answer: https://unix.stackexchange.com/a/121042/29414

  1. Drop root: su -
  2. cd /usr/src
  3. apt-get source ${source_package_name}
    • Example: apt-get source qtbase-opensource-src
  4. The source package is downloaded, unzipped/untarred, and patched into a new directory.
    • Example: /usr/src/qtbase-opensource-src-5.3.2+dfsg/
  5. Remove the downloaded TAR ball and other files (maybe .dsc).
    rm *.tar.* *.dsc
  6. Create a symbolic link: ln -s qtbase-opensource-src-5.3.2+dfsg qtbase-opensource-src

Configure GDB

(This section can be completed using your non-root / regular account.)

GDB needs configuration to know where source code can be found.

Each source package is a little different, so I will use Qt5 as an example.

  1. cd /usr/src/qtbase-opensource-src/src
  2. Find list of source subdirectories:
    find $(pwd) -mindepth 1 -maxdepth 1 -type d
    • Example: /usr/src/qtbase-opensource-src/src/corelib ...
  3. Reformat the find output to create GDB commands:
    find $(pwd) -mindepth 1 -maxdepth 1 -type d | sort | xargs -l -i printf -- 'directory %s\n' "{}"
    • Example: directory /usr/src/qtbase-opensource-src/src/3rdparty ...
  4. Insert GDB commands into your ~/.gdbinit for convenience.

Sample ~/.gdbinit:

set auto-load safe-path /
set history save
set history filename ~/.gdb_history

directory /usr/src/qtbase-opensource-src/src/3rdparty
directory /usr/src/qtbase-opensource-src/src/android
directory /usr/src/qtbase-opensource-src/src/angle
directory /usr/src/qtbase-opensource-src/src/concurrent
directory /usr/src/qtbase-opensource-src/src/corelib
directory /usr/src/qtbase-opensource-src/src/dbus
directory /usr/src/qtbase-opensource-src/src/gui
directory /usr/src/qtbase-opensource-src/src/network
directory /usr/src/qtbase-opensource-src/src/opengl
directory /usr/src/qtbase-opensource-src/src/openglextensions
directory /usr/src/qtbase-opensource-src/src/platformsupport
directory /usr/src/qtbase-opensource-src/src/plugins
directory /usr/src/qtbase-opensource-src/src/printsupport
directory /usr/src/qtbase-opensource-src/src/sql
directory /usr/src/qtbase-opensource-src/src/testlib
directory /usr/src/qtbase-opensource-src/src/tools
directory /usr/src/qtbase-opensource-src/src/widgets
directory /usr/src/qtbase-opensource-src/src/winmain
directory /usr/src/qtbase-opensource-src/src/xml
show directories

Run GDB

This section assumes you already have a program compiled with debugging symbols linked to the library of interest, e.g., Qt5.

  1. gdb ${program_name}
  2. Start the program and break at main() automatically: start
  3. Set a breakpoint in a library function: b '${function_signature}'
    Command b(reakpoint) with single quotes supports (very impressive!) tab completion.
    • Example: b 'QStyled<tab>
      -> b 'QStyledItemDelegate
      -> ::paint(<tab>
      -> b 'QStyledItemDelegate::paint(QPainter*, QStyleOptionViewItem const&, QModelIndex const&) const'
  4. Continue to hit the new breakpoint: c or continue
  5. When the library breakpoint is hit, GDB will find and display the source code.
Related Question