代码之家  ›  专栏  ›  技术社区  ›  Henry Crutcher

尼克斯:如何获得包含调试信息的python包?

  •  7
  • Henry Crutcher  · 技术社区  · 6 年前

    我在试着在尼克松上调试赛通。我可以很容易地将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[@]}" "$@"
    

    然后我们做一个普通的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上单独使用启用调试时,会得到不同的结果。 $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.
    

    当我们尝试使用赛通(或任何其他包装)时,问题就出现了。
    $nix shell-p'(启用调试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程序的用处大大降低。

    2 回复  |  直到 6 年前
        1
  •  4
  •   FRidh    6 年前

    解决方案

    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 这也需要更新。

        2
  •  1
  •   CMCDragonkai    6 年前

    @弗里德的答案需要一个额外的小代码才能使这个有用。

    基本上你需要一个 shell.nix 有了这个:

    with import <nixpkgs> {};
    
    let
       python = enableDebugging pkgs.python;
    in
      stdenv.mkDerivation {
        name = "test";
        buildInputs = [ python ];
      }
    

    然后当你进入 nix-shell ,你可以跑步 gdb -p <pid of python process> .

    注意,这只会调试Python解释器本身。这不会使gdb的python扩展允许您调试应用程序级python代码。

    这个 enableDebugging 也不会传播到依赖项。每个依赖项都需要自己的 启用调试 如果希望启用这些调试符号。是否应该有一个函数来启用递归调试?