I’m currently trying to debug python using gdb. In order to ease reproducibility, I’ve created a minimal shell.nix and test.py.
with import <nixpkgs> {};
let
pythonDbg = enableDebugging python37;
in
mkShell {
buildInputs = [
gdb
pythonDbg
];
}
# Just some nested function calls so we get a nice stacktrace
import time
def test1():
print("test1")
test2()
def test2():
print("test2")
test3()
def test3():
print("test3")
time.sleep(30)
By running :b (enableDebugging pkgs.python37) in the repl, I get the following output:
this derivation produced the following outputs:
debug -> /nix/store/<debughash>-python3-3.7.9-debug
out -> /nix/store/<binhash>-python3-3.7.9
The .debug file at the <debughash>/lib/debug/python3.7 link has a name which corresponds to the build id of <binhash>/bin/python3.7, so this part looks fine. However, the size of the debug file is only 4kb and strings shows almost no content.
After entering the nix-shell and starting the python script, I attach to it with gdb. In the startup message I can see that gdb was unable to find any debug symbols for <binhash>/bin/python3.7. I source the libpython.py script and run set debug-file-directory <debughash>/lib/debug. At this point gdb should be able to read the python frame information but it isn’t. py-bt returns “unable to read python frame information”.
I used hello because I can’t be bothered to wait for Python to compile, but this works for me:
(see also Debug Symbols - NixOS Wiki)
with import <nixpkgs> {};
let
# hello does not by default build with separateDebugInfo
helloDbg = enableDebugging (hello.overrideAttrs (_: { separateDebugInfo = true; }));
in
mkShell {
buildInputs = [
gdb
helloDbg
];
NIX_DEBUG_INFO_DIRS = "${helloDbg.debug}/lib/debug";
}
[nix-shell:~]$ echo $NIX_DEBUG_INFO_DIRS
/nix/store/zf4r8acjf23zsg400qjhk3x016rxy0c3-hello-2.10-debug/lib/debug
[nix-shell:~]$ gdb hello
GNU gdb (GDB) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from hello...
Reading symbols from /nix/store/zf4r8acjf23zsg400qjhk3x016rxy0c3-hello-2.10-debug/lib/debug/.build-id/95/35f4056eca473a910446841d9a30d0cfa270b8.debug...
(gdb) start
Temporary breakpoint 1 at 0x40259f: file src/hello.c, line 41.
Starting program: /nix/store/lh2w1nlh2qgnkiacmycsf87k4zc0fn2y-hello-2.10/bin/hello
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffb798) at src/hello.c:41
41 src/hello.c: No such file or directory.
@hmenke I have to admit that I was sceptical when I first read your solution, since I had actually tried setting separateDebugInfo = true before. However, it worked like a charm! Interestingly, when I tried to remove NIX_DEBUG_INFO_DIRS and manually set it from within gdb via set debug-file-directory, it didn’t work again. Can you explain why this doesn’t work?