Also get the correct source code with apt source
In addition to the symbols, you will also to get the source with apt source
as mentioned at:
and then point GDB to them with substitute-path
as mentioned at: https://stackoverflow.com/questions/23868252/gdb-source-path
Some fully working commands on Ubuntu 22.04, e.g. to debug ls
from coreutils
follow.
First we ge the debug symbosls:
printf "deb http://ddebs.ubuntu.com %s main restricted universe multiverse\n" $(lsb_release -cs){,-updates,-security,-proposed} | \
sudo tee -a /etc/apt/sources.list.d/ddebs.list
sudo apt install ubuntu-dbgsym-keyring
sudo apt update
sudo apt install coreutils-dbgsym
Next we get the source code as per: Error :: You must put some 'source' URIs in your sources.list
sudo cp /etc/apt/sources.list /etc/apt/sources.list~
sudo sed -Ei 's/^# deb-src /deb-src /' /etc/apt/sources.list
sudo apt update
apt source coreutils
which produces a directory coreutils-8.32
.
Finally we run ls
pointing GDB to the downloaded source. On Ubuntu 22.04:
gdb -ex 'set substitute-path . coreutils-8.32' ls
On Ubuntu 23.10 I instead needed:
gdb -ex "set substitute-path /usr/src/coreutils-9.1-1ubuntu2 coreutils-9.1" ls
And now I see the source correctly as in:
(gdb) start
Temporary breakpoint 1 at 0x4d20: file src/ls.c, line 1622.
Starting program: /usr/bin/ls
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffce08) at src/ls.c:1622
warning: Source file is more recent than executable.
1622 {
(gdb) l
1617 signal_setup (false);
1618 }
1619
1620 int
1621 main (int argc, char *argv)
1622 {
1623 int i;
1624 struct pending thispend;
1625 int n_files;
1626
The choice of set substitute-path .
is because without substitute-path
it would fail with:
1622 src/ls.c: No such file or directory.
so we help GDB find the source by making it convert .
to coreutils-8.32/
where the src/
lives. And on Ubuntu 23.10 the error was instead:
Cannot display "/usr/src/coreutils-9.1-1ubuntu2/src/ls.c" ([Errno 2] No such file or directory: '/usr/src/coreutils-9.1-1ubuntu2/src/ls.c')
so now we want /usr/src/coreutils-9.1-1ubuntu2
to be replaced with coreutils-9.1
.
The /usr/src
path from Ubuntu 23.10 is quite nice actually, a sane setup would be to dump all sources there so we can avoid substitute-path
all the time. However, even if I cd/usr/src
first even that is still broken because of the -1ubuntu2
suffix, alas. But we could manually:
sudo cp -rv coreutils-9.1/ /usr/src/coreutils-9.1-1ubuntu2
which allows us to simply:
gdb ls
Unfortunately not all packages follow that /usr/src
convention, e.g. on Ubuntu 23.10 libx11-6-dbgsym
had prefix /build/libx11-9By7Fr/libx11-1.8.6/build/src/../../src/XlibInt.c
. One day we'll get there.
GDB step debug into glibc
The exact same procedure works for shared libraries. E.g. to GDB step debug glibc as asked at:
In that case, the debug symbols already appear to come preinstalled, otherwise we would need:
sudo apt install libc6-dbg
and then get source with:
apt source libc6
which produces directory: glibc-2.35
.
We then make a C hello world to test with:
main.c
#include <stdio.h>
int main(void) {
puts("hello");
}
If we try to compile, GDB and go into glibc
gcc -ggdb3 -O0 -std=c99 -Wall -Wextra -pedantic -o main.out main.c
gdb main.out
as:
(gdb) start
Temporary breakpoint 1 at 0x1151: file main.c, line 4.
Starting program: /home/ciro/tmp/main.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Temporary breakpoint 1, main () at main.c:4
4 puts("hello");
(gdb) s
__GI__IO_puts (str=0x555555556004 "hello") at ./libio/ioputs.c:33
33 ./libio/ioputs.c: No such file or directory.
(gdb)
we see that the library also searches for files under ./
, so once again we:
set substitute-path . glibc-2.35
and now we can see the source:
(gdb) l
28 #include <string.h>
29 #include <limits.h>
30
31 int
32 _IO_puts (const char *str)
33 {
34 int result = EOF;
35 size_t len = strlen (str);
36 _IO_acquire_lock (stdout);
37
Some other versions of Ubuntu had sources at an absolute location like:
/tmp/build138741687/
in which case you would instead want:
set substitute-path /tmp/build138741687/ glibc-2.35