Subject: bug#78046: GDB does not find debug information with some Guix packages (e.g., `coreutils` vs. `grep`)

From: Atte Torri <[email-masked]>
Date: Thu, 24 Apr 2025 17:03:13 +0000

Hello everyone,

I'm encountering an issue with debugging packages using GDB in a Guix shell. For some packages (which seem to be those *without* a defined `debug` output), GDB is able to locate and use debug information when the package is built with `--with-debug-info=package`. However, for other packages (which seem to be those *with* a defined `debug` output and debug info stripped from the executable in the build phase), this approach does not work — neither `--with-debug-info=package` nor adding `package:debug` to the environment helps, unless the debug info is manually loaded into GDB.

As concrete examples, I've observed this behavior with `grep` (has no debug output) and `coreutils` (has a debug output), though a similar behavior appears with other packages as well.

Case of `grep` without debug info - no debug information found, as expected.
```
$ guix shell --pure gdb coreutils bash binutils gcc-toolchain sed grep
$ gdb grep
[...]
Reading symbols from grep...
(No debugging symbols found in grep)
(gdb) b main
Function "main" not defined.
Make breakpoint pending on future shared library load? (y or [n]) n
```

Case of `grep` with debug info - debug information is found, as expected.
```
$ guix shell --pure gdb coreutils bash binutils gcc-toolchain sed grep --with-debug-info=grep
$ gdb grep
[...]
Reading symbols from grep...
(gdb) b main
Breakpoint 1 at 0x403860: file grep.c, line 2465.
(gdb) r
[...]
```

Case of `coreutils` with debug info built in using `--with-debug-info=coreutils` - no debug information found.
```
$ guix shell --pure gdb coreutils bash binutils gcc-toolchain sed grep --with-debug-info=coreutils
$ gdb ls
[...]
Reading symbols from ls...
(No debugging symbols found in ls)
(gdb) b main
Function "main" not defined.
```

Case of `coreutils` with debug info built in auxiliary package using `coreutils:debug` - no debug information found.
```
$ guix shell --pure gdb coreutils bash binutils gcc-toolchain sed grep coreutils:debug
$ gdb ls
[...]
Reading symbols from ls...
(No debugging symbols found in ls)
(gdb) b main
Function "main" not defined.
```

In this case the only way is to use `coreutils:debug` and manually direct gdb to the location of the debug information files.
```
(gdb) add-symbol-file /gnu/store/vaj4jmwa2js930ab876ad2jji9mb1xf6-profile/lib/debug/gnu/store/mppp9hwxizx9g9pikwcvvshb2ffxyq7p-coreutils-9.1/bin/ls.debug
add symbol table from file "/gnu/store/vaj4jmwa2js930ab876ad2jji9mb1xf6-profile/lib/debug/gnu/store/mppp9hwxizx9g9pikwcvvshb2ffxyq7p-coreutils-9.1/bin/ls.debug"
(y or n) y
Reading symbols from /gnu/store/vaj4jmwa2js930ab876ad2jji9mb1xf6-profile/lib/debug/gnu/store/mppp9hwxizx9g9pikwcvvshb2ffxyq7p-coreutils-9.1/bin/ls.debug...
(gdb) b main
Breakpoint 1 at 0x403760: file src/ls.c, line 1652.
(gdb) r
[...]
Breakpoint 1, main (argc=1, argv=0x7fffffffe8d8) at src/ls.c:1652
warning: 1652     src/ls.c: No such file or directory
```

Exploring further, it would seem that the `—with-debug-info=package` does not affect the build of `coreutils` as it's hash does not change.
```
$ guix shell --pure gdb coreutils bash binutils gcc-toolchain sed grep which
$ ls -l $(which ls)
lrwxrwxrwx 1 root root 64 Jan  1  1970 /gnu/store/jhfpg9rh5f8bnb6l7m78hp2kdsrrfs1x-profile/bin/ls -> /gnu/store/mppp9hwxizx9g9pikwcvvshb2ffxyq7p-coreutils-9.1/bin/ls
$ ls -l $(which grep)
lrwxrwxrwx 1 root root 61 Jan  1  1970 /gnu/store/jhfpg9rh5f8bnb6l7m78hp2kdsrrfs1x-profile/bin/grep -> /gnu/store/4r58qp27c4cclyviax8dyma30y5f1mb9-grep-3.8/bin/grep
$ guix shell --pure gdb coreutils bash binutils gcc-toolchain sed grep which --with-debug-info=coreutils --with-debug-info=grep
$ ls -l $(which ls)
lrwxrwxrwx 1 root root 64 Jan  1  1970 /gnu/store/490h1m9pav5bb54a8hs373i56qnbq443-profile/bin/ls -> /gnu/store/mppp9hwxizx9g9pikwcvvshb2ffxyq7p-coreutils-9.1/bin/ls
$ ls -l $(which grep)
lrwxrwxrwx 1 root root 61 Jan  1  1970 /gnu/store/490h1m9pav5bb54a8hs373i56qnbq443-profile/bin/grep -> /gnu/store/yhnx9dcsk1jg9zyg64l8c9x15p509fj2-grep-3.8/bin/grep
```

On another note (maybe more relevant to guix-devel), one might expect there to be some setup in Guix for gdb to load debug information from the auxiliary debug packages created when using `package:debug` (in my experimentation using `set debug-file-directory $GUIX_ENVIRONMENT/lib/debug` or similar does not work, only manually loading the symbol files works).

Moreover (again might be more relevant to guix-devel), since `—with-debug-info=package` does not add the sources for the packages to the store, and thus `tui enable` and `list` do not work correctly in GDB. For this currently the only solution seems to be to specify source location manually to GDB. In the debug info section of the executables with non-stripped debug info or the auxiliary debug packages, the source directory is specified as something in `/tmp`, where guix actually builds packages:
```
$ readelf --debug-dump=info /gnu/store/yhnx9dcsk1jg9zyg64l8c9x15p509fj2-grep-3.8/bin/grep | head -n 20
Contents of the .debug_info section:
[...]
    <12>   DW_AT_name        : (indirect line string, offset: 0x0): dfasearch.c
    <16>   DW_AT_comp_dir    : (indirect line string, offset: 0xc): /tmp/guix-build-grep-3.8.drv-0/grep-3.8/src
[...]
$ readelf --debug-dump=info /gnu/store/x2lnb77pv0qnivl3alwmzagm55j6h4s5-profile/lib/debug/gnu/store/mppp9hwxizx9g9pikwcvvshb2ffxyq7p-coreutils-9.1/bin/ls.debug | head -n 20
readelf: Error: Unable to find program interpreter name
Contents of the .debug_info section:
[...]
    <12>   DW_AT_name        : (indirect line string, offset: 0x0): src/ls.c
    <16>   DW_AT_comp_dir    : (indirect line string, offset: 0x9): /tmp/guix-build-coreutils-9.1.drv-0/coreutils-9.1
[...]
```
Thus, in GDB it is possible to point to the source files with `set substitute-path /tmp/guix-build-coreutils-9.1.drv-0/coreutils-9.1 /path/to/coreutils`, or something similar. I think that Guix could place the sources in the `/gnu/store` for packages when using `--with-debug-info=package` similarly to `guix build --sources package`, and ensure that the directory path in the debug info is patched with the actual path to the sources in the store. This could work nicely at least for packages that do not create new source files during compilation.

Best,
Atte TORRI