Nixos: Как мне получить питон с отладочной информацией, включенной в пакеты?

Я пытаюсь выполнить отладку Cython на NixOS. Я могу легко установить 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-оболочку из простого python и смотрим, какую версию python мы получим.

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

Все хорошо - в обоих случаях получаем питон без отладки. И если мы его 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.

Когда мы используем enableDebugging на самом Python, мы получаем разные результаты. $ 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.

Проблемы возникают, когда мы пытаемся сделать это с включенным 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.


person Henry Crutcher    schedule 13.07.2018    source источник


Ответы (2)


Решение

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, которую также необходимо обновить.

person FRidh    schedule 19.07.2018
comment
В чем разница между enableDebugging и separateDebugInfo? - person CMCDragonkai; 22.10.2018
comment
Это не работает с with python.pkgs и только с withPackages? - person CMCDragonkai; 22.10.2018
comment
Да, есть, но важная часть let self = enableDebugging python; в python.override {наследовать себя;} - person FRidh; 22.10.2018
comment
Пока это работает, я все еще получаю такие сообщения: Python/ceval.c: No such file or directory.. В основном это, вероятно, требует распаковки исходного кода. У нас должна быть дополнительная информация об этом позже. - person CMCDragonkai; 22.10.2018

Для ответа @fridh требуется дополнительный небольшой код, чтобы его можно было использовать.

В основном вам нужен 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. Это не включает расширения python для gdb, позволяющие отлаживать код Python на уровне приложения.

enableDebugging также не распространяется на зависимости. Для каждой зависимости потребуются свои собственные enableDebugging, если вы хотите, чтобы эти символы отладки были включены. Должна ли быть функция для рекурсивной отладки?

person CMCDragonkai    schedule 22.10.2018