Can't figure out how to get python debug symbols


I’m currently trying to debug python using gdb. In order to ease reproducibility, I’ve created a minimal shell.nix and

with import <nixpkgs> {};

  pythonDbg = enableDebugging python37;
  mkShell {
    buildInputs = [
# Just some nested function calls so we get a nice stacktrace
import time

def test1():

def test2():

def test3():

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 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”.

What am I doing wrong?

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> {};

  # hello does not by default build with separateDebugInfo
  helloDbg = enableDebugging (hello.overrideAttrs (_: { separateDebugInfo = true; }));
mkShell {
  buildInputs = [

  NIX_DEBUG_INFO_DIRS = "${helloDbg.debug}/lib/debug";
[nix-shell:~]$ echo $NIX_DEBUG_INFO_DIRS 

[nix-shell:~]$ gdb hello
GNU gdb (GDB) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <>
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:
Find the GDB manual and other documentation resources online at:

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?

I just noticed that the above doesn’t seem to work when using the withPackages function.

In the repl I can see that no debug symbols seem to be created

nix-repl> pythondbg = pkgs.enableDebugging (pkgs.python37.overrideAttrs (_: { separateDebugInfo = true; }))
nix-repl> pythonenv = :b (pythondbg.withPackages (p: [ p.poetry ]))
nix-repl> :b pythonenv

this derivation produced the following outputs:
    -> out: /nix/store/<binhash>-python3-3.7.9-env

Is there a way to make this work?