11

I try to watch how programs work by running them by the 'Qt Creator' debugger. For better orientation I'd like to see also the system (core) utilities fully in the call stack window as I am used from the MS Visual Studio 6.0, not only to see their assembly code. For the utilities, the 'Qt Creator' debugger displays only that their debug symbols are not available. (Sometimes, the system generates bug reports for its developers; the bug report dialog has requested installing such symbols only for a particular program.) How can I get the core debug symbols? (Without translating the whole Ubuntu version. I use the 'Update Manager' to install updates regularly. My

/sys/kernel/debug/x86
directory contains only one empty file. I have not found it in the 'Ubuntu software center' nor do I see if some of the packages at the http://packages.ubuntu.com/precise/x11/ is what I seek.) Thanks!
Braiam
  • 67,791
  • 32
  • 179
  • 269
Tomáš Pečený
  • 1,407
  • 7
  • 19
  • 45

4 Answers4

14

Packages in Ubuntu have their debugging symbols stored in a separate repo. To download these debugging symbols, run (copy and paste):

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

to add the repo links into /etc/apt/sources.list.d/ddebs.list (This makes it easier to remove the repo). Alternatively, you can also copy each of the deb links into Software Sources and add them from there (Note that you'll likely need to replace $(lsb_release -cs) with the Ubuntu release that you're running).

Then, for Ubuntu 18.04 or later, you need to execute a keyring installation command:

sudo apt install ubuntu-dbgsym-keyring

Then, for any Ubuntu, run:

sudo apt update

To download the debugging symbols for package, you can just install package-dbgsym or, in some cases, package-dbg. Note that packages from a PPA don't have debugging symbols available from repos, and that it's the maintainer's responsibility to provide a package that contains the debugging symbols, usually in a package named package-dbg.

Debugging symbols are installed in /usr/lib/debug, although gdb automatically reads in debugging symbols if available and that you don't manually need to specify a location to look in. Depending on the Debhelper Compatibility version of the package, debugging symbols may either be located in a folder with the name of the build ID located inside .build-id (>= 9), or may be located relative to where the executable would be installed (< 9). For example, if you were looking for the location of the debugging symbols for /usr/bin/zip, and the version is less than 9, it would be in /usr/lib/debug/usr/bin/zip.

To remove all debugging symbols and the repo, run sudo apt-get remove \.*-dbgsym to remove all -dbgsym packages, and sudo rm /etc/apt/sources.list.d/ddebs.list to remove the debugging symbols repo.

saiarcot895
  • 10,757
  • 2
  • 36
  • 39
9

Adding to Evans answer: On Ubuntu 18.04 and later you use the command

sudo apt install ubuntu-dbgsym-keyring

to install the GPG keys. (According to https://wiki.ubuntu.com/Debug%20Symbol%20Packages )

pt1
  • 93
  • 1
  • 4
5

Adding to saircot859's answer. You also have to install the GPG key for the repositories as described here: https://wiki.ubuntu.com/Debug%20Symbol%20Packages

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 428D7C01 C8CAB6595FDFF622
Evan
  • 218
  • Linked wiki page was updated. On Ubuntu 18.04 LTS and newer, use sudo apt install ubuntu-dbgsym-keyring. – user7610 May 09 '20 at 19:30
1

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