Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nixos: How do I get get a python with debug info included with packages?

I'm trying to do cython debugging on NixOS. I can easily install cython in a nix-shell (chosen for simplicity of example), like this:

$ nix-shell -p 'python27.withPackages( p: [ p.cython ])'

$ cat /nix/store/s0w3phb2saixi0a9bzk8pjbczjaz8d7r-python-2.7.14-env/bin/python
#! /nix/store/jgw8hxx7wzkyhb2dr9hwsd9h2caaasdc-bash-4.4-p12/bin/bash -e
export PYTHONHOME="/nix/store/s0w3phb2saixi0a9bzk8pjbczjaz8d7r-python-2.7.14-env"
export PYTHONNOUSERSITE="true"
exec "/nix/store/i3bx1iw2d0i3vh9sa1nf92ynlrw324w8-python-2.7.14/bin/python"  "${extraFlagsArray[@]}" "$@"

Then we do a normal nix-shell of just python and see what version of python we get.

[henry@bollum:~/Projects/eyeserver/nixshell]$ nix-shell -p 'python27'
$ which python
/nix/store/i3bx1iw2d0i3vh9sa1nf92ynlrw324w8-python-2.7.14/bin/python
#          ^^^^^^^
#          non-debug

All is well -- we get a non-debug python in both cases. And if we gdb it, we get (no debugging symbols found). See the last line.

$ gdb 
/nix/store/i3bx1iw2d0i3vh9sa1nf92ynlrw324w8-python-2.7.14/bin/python
GNU gdb (GDB) 8.0.1
Copyright (C) 2017 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 /nix/store/i3bx1iw2d0i3vh9sa1nf92ynlrw324w8-python-2.7.14/bin/python...(no debugging symbols found)...done.

When we use enableDebugging, on python by itself, we get different results. $ nix-shell -p 'enableDebugging python27'

$ which python
/nix/store/a4wd8mcpqr54hmw0x95fw8fhvk8avh5a-python-2.7.14/bin/python
#          ^^^^^^
#          debug

$ gdb 
/nix/store/a4wd8mcpqr54hmw0x95fw8fhvk8avh5a-python-2.7.14/bin/python
GNU gdb (GDB) 8.0.1
...
Reading symbols from /nix/store/a4wd8mcpqr54hmw0x95fw8fhvk8avh5a-python-2.7.14/bin/python...done.

The problems come when we try to do this with cython (or any other package) included.
$ nix-shell -p '(enableDebugging python27).withPackages( p: [ p.cython ])'

$ cat `which python`
#! /nix/store/jgw8hxx7wzkyhb2dr9hwsd9h2caaasdc-bash-4.4-p12/bin/bash -e
export PYTHONHOME="/nix/store/s0w3phb2saixi0a9bzk8pjbczjaz8d7r-python-2.7.14-env"
export PYTHONNOUSERSITE="true"
exec "/nix/store/i3bx1iw2d0i3vh9sa1nf92ynlrw324w8-python-2.7.14/bin/python"  "${extraFlagsArray[@]}" "$@"
#                ^^^^^^^
#                non-debug
$ gdb /nix/store/i3bx1iw2d0i3vh9sa1nf92ynlrw324w8-python-2.7.14/bin/python
GNU gdb (GDB) 8.0.1
...
Reading symbols from /nix/store/i3bx1iw2d0i3vh9sa1nf92ynlrw324w8-python-2.7.14/bin/python...(no debugging symbols found)...done.
(gdb) 
quit

The version of python in the environment is now non-debug, and attempting to debug it gets the dreaded (no debugging symbols found). This makes gdb much less useful for debugging cython programs.

like image 554
Henry Crutcher Avatar asked Jul 13 '18 21:07

Henry Crutcher


2 Answers

Solution

with import <nixpkgs> {};

let
   self = enableDebugging python;
in [ gdb ((python.override{inherit self;}).withPackages(ps: with ps; [ cython ])) ]

The executable referred to in the wrapper now has debug symbols.

Background

If we look in pkgs/all-packages.nix we see the implementation of the enableDebugging function:

enableDebugging = pkg: pkg.override { stdenv = stdenvAdapters.keepDebugInfo pkg.stdenv; };

It overrides a single derivation to use a different stdenv. In your case, you would like to override the Python interpreter, which is a dependency of the derivation obtained with python.withPackages.

Your attempt with enableDebugging python was in the right direction, however, python.withPackages uses a reference to python that needs to be updated as well.

like image 129
FRidh Avatar answered Sep 19 '22 10:09

FRidh


@fridh answer requires an extra little code to make this usable.

Basically you need a shell.nix with this:

with import <nixpkgs> {};

let
   python = enableDebugging pkgs.python;
in
  stdenv.mkDerivation {
    name = "test";
    buildInputs = [ python ];
  }

Then when you enter the nix-shell, you can run gdb -p <pid of python process>.

Note that this only debugs the Python interpreter itself. This does not enable the python extensions to gdb allowing you to debug application level python code.

The enableDebugging also does not propagate to dependencies. Each dependency will require its own enableDebugging if you want those debug symbols to be enabled. Should there be a function to enable debugging recursively?

like image 35
CMCDragonkai Avatar answered Sep 18 '22 10:09

CMCDragonkai