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

Reply via email to