Что нужно для поддержки gdb 7 для отладки программ Python?

Я бы хотел использовать поддержку gdb 7 для отладки "неполных процессов" Python.

Что мне нужно для этого?

Например:

  • С какими флагами должен работать исполняемый скрипт с низким уровнем Python?

  • Должен ли процесс уступать Python быть Python 2.7 или более новым (я вижу, что когда часть поддержки gdb для этого в исходном дереве Python была зафиксирована)? Или Python 2.7 нужен только самому процессу gdb?

  • Какие файлы необходимо установить, которые не могут быть упакованы всеми дистрибутивами? Например, на packages.ubuntu.com я не получаю никаких хитов для python-gdb.py, которые, я считаю, необходимы.

Было бы очень полезно узнать, что необходимо для конкретных распределений. Меня особенно интересует то, что нужно для Ubuntu и Centos.

Ответ 1

Кажется, что Python нужно скомпилировать с помощью --with-pydebug (на Ubuntu 12.04, пакет python-dbg содержит подходящий исполняемый файл Python, сам называемый python-dbg). Уступающий Python не должен быть Python 2.7 - 2.6 успешно загружает расширения 2.7 gdb (см. Сеанс отладки ниже). По крайней мере, на Ubuntu 12.04 файл, который устанавливается, который определяет расширения gdb, называется libpython.py, а не python-gdb.py (по какой-то причине, построение Python дает каталог сборки, содержащий оба этих файла - они идентичны).

Тем не менее, я не думаю, что в настоящее время можно отлаживать использование основных файлов ядра: похоже, что расширения gdb для более сложных процессов Python пытаются получить переменные, которые оптимизируются в производственном двоичном формате (например, переменная f в PyEval_EvalFrameEx). Похоже, Linux/gdb, и Python еще не достиг уровня удивительности, достигнутого для JavaScript на Illumos, о котором Bryan Cantrill сообщает здесь, что позволяет отлаживать производственные отвалы таким образом:

http://www.infoq.com/presentations/Debugging-Production-Systems

Здесь отладочный сеанс на Ubuntu 12.04, показывающий gdb, выполняющий процесс Python 2.6, чтобы отладить segfault, используя расширения Python 2.7 gdb. Сначала код, вызывающий segfault:

~/Downloads/Python-2.6.4$ cat ~/bin/dumpcore.py
class Foo:

    def bar(self):
        from ctypes import string_at
        string_at(0xDEADBEEF) # this code will cause Python to segfault


def main():
    f = Foo()
    f.someattr = 42
    f.someotherattr = {'one':1, 'two':2L, 'three':[(), (None,), (None, None)]}
    f.bar()


if __name__ == "__main__":
    main()

и сеанс отладки:

~/Downloads/Python-2.6.4$ gdb --args ./python ~/bin/dumpcore.py
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 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-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/john/Downloads/Python-2.6.4/python...done.
(gdb) run
Starting program: /home/john/Downloads/Python-2.6.4/python /home/john/bin/dumpcore.py
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
0x0000000000468d67 in PyString_FromString (str=0xdeadbeef <Address 0xdeadbeef out of bounds>) at Objects/stringobject.c:116
116             size = strlen(str);
(gdb) py-bt
Undefined command: "py-bt".  Try "help".
(gdb) python
>import sys
>sys.path.insert(0, "/home/john/Downloads/Python-2.7/Tools/gdb")
>import libpython
>(gdb) py-bt
#10 Frame 0x8f0f90, for file /home/john/Downloads/Python-2.6.4/Lib/ctypes/__init__.py, line 496, in string_at (ptr=3735928559, size=-1)
    return _string_at(ptr, size)
#14 Frame 0x8ebf90, for file /home/john/bin/dumpcore.py, line 5, in bar (self=<Foo(someattr=42, someotherattr={'three': [(), (None,), (None, None)], 'two': 2L, 'one': 1}) at remote 0x7ffff6e03240>, string_at=<function at remote 0x7ffff6e1c990>)
        string_at(0xDEADBEEF) # this code will cause Python to segfault
#17 Frame 0x8ebd80, for file /home/john/bin/dumpcore.py, line 12, in main (f=<Foo(someattr=42, someotherattr={'three': [(), (None,), (None, None)], 'two': 2L, 'one': 1}) at remote 0x7ffff6e03240>)
    f.bar()
#20 Frame 0x8eb680, for file /home/john/bin/dumpcore.py, line 16, in <module> ()
    main()
(gdb) 

Ответ 2

Для Centos 6 вам просто нужно сделать:

yum install gdb python-debuginfo
debuginfo-install python

Затем вы можете отлаживать запущенные процессы python, просто привязывая их к gdb:

gdb python [process id]

После подключения просто введите:

py-bt