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
- Drop root:
su -
cd /usr/src
apt-get source ${source_package_name}
- Example:
apt-get source qtbase-opensource-src
- The source package is downloaded, unzipped/untarred, and patched into a new directory.
- Example:
/usr/src/qtbase-opensource-src-5.3.2+dfsg/
- Remove the downloaded TAR ball and other files (maybe
.dsc
).
rm *.tar.* *.dsc
- 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.
cd /usr/src/qtbase-opensource-src/src
- Find list of source subdirectories:
find $(pwd) -mindepth 1 -maxdepth 1 -type d
- Example:
/usr/src/qtbase-opensource-src/src/corelib ...
- 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 ...
- 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.
gdb ${program_name}
- Start the program and break at
main()
automatically: start
- 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'
- Continue to hit the new breakpoint:
c
or continue
- When the library breakpoint is hit, GDB will find and display the source code.
qtbase5-dbg
does not exist outside Ubuntu 16 :/ – xeruf Aug 30 '20 at 16:35