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.
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.
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.
@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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With