首页 > 解决方案 > Nixos:我如何获得一个包含调试信息的 python?

问题描述

我正在尝试在 NixOS 上进行 cython 调试。我可以轻松地将 cython 安装在 nix-shell 中(为简单起见而选择),如下所示:

$ 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[@]}" "$@"

然后我们做一个普通的仅 python 的 nix-shell 并查看我们得到的 python 版本。

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

一切都很好——我们在这两种情况下都得到了一个非调试 python。如果我们 gdb 它,我们会得到(没有找到调试符号)。见最后一行。

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

当我们单独在 python 上使用 enableDebugging 时,我们会得到不同的结果。$ nix-shell -p '启用调试 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.

当我们尝试使用包含的 cython(或任何其他软件包)来执行此操作时,问题就来了。
$ 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

环境中的 python 版本现在是非调试的,并且尝试调试它会变得可怕(没有找到调试符号)。这使得 gdb 对于调试 cython 程序的用处大大降低。

标签: pythongdbcythonnixnixos

解决方案


解决方案

with import <nixpkgs> {};

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

包装器中引用的可执行文件现在具有调试符号。

背景

如果我们看一下,pkgs/all-packages.nix我们会看到enableDebugging函数的实现:

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

它覆盖单个派生以使用不同的stdenv. 在您的情况下,您想覆盖 Python 解释器,它是使用python.withPackages.

但是,您的尝试enableDebugging python是在正确的方向上,但是python.withPackages使用了对python也需要更新的引用。


推荐阅读