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