Подтвердить что ты не робот

Есть ли способ подключить отладчик к многопоточному процессу Python?

Я пытаюсь отладить тупик в многопоточном приложении Python после его блокировки. Есть ли способ подключить отладчик для проверки состояния процесса?

Изменить: я пытаюсь это сделать в Linux, но было бы замечательно, если бы было кросс-платформенное решение. Это Python в конце концов:)

4b9b3361

Ответ 1

Да, gdb хорош для отладки более низкого уровня.

Вы можете изменить потоки с помощью команды потока.

например

(gdb) thr 2
[Switching to thread 2 (process 6159 thread 0x3f1b)]
(gdb) backtrace
....

Вы также можете проверить специфичные для Python отладчики, такие как Winpdb или pydb. Обе платформы независимы.

Ответ 2

Используйте Winpdb. Это независимый от независимый от платформы графический отладчик GPL Python с поддержкой удаленной отладки по сети, несколько потоков, изменение пространства имен, встроенная отладка, зашифрованная связь и до 20 раз быстрее, чем pdb.

Особенности:

  • Лицензия GPL. Winpdb - бесплатное программное обеспечение.
  • Совместимость с CPython с 2.3 по 2.6 и Python 3000
  • Совместимость с wxPython 2.6 - 2.8
  • Независимая платформа и протестирована на Ubuntu Gutsy и Windows XP.
  • Пользовательские интерфейсы: rpdb2 основан на консоли, а для winpdb требуется wxPython 2.6 или новее.

Снимок экрана http://winpdb.org/images/screenshot_winpdb_small.jpg

Ответ 3

Вы можете присоединить отладчик к многопоточному процессу Python, но вам нужно сделать это на уровне C. Чтобы понять, что происходит, вам нужно, чтобы интерпретатор Python был скомпилирован с символами. Если у вас его нет, вам нужно загрузить исходный код с python.org и самостоятельно его создать:

./configure --prefix=/usr/local/pydbg
make OPT=-g
sudo make install
sudo ln -s /usr/local/pydbg/bin/python /usr/local/bin/dbgpy

Убедитесь, что ваша рабочая нагрузка запущена на этой версии интерпретатора. Затем вы можете подключиться к нему с помощью GDB в любое время. Люди Python включили образец ".gdbinit" в свой каталог Misc, в котором есть несколько полезных макросов. Однако он не работает для многопоточной отладки (!). Вам нужно заменить строки следующим образом

while $pc < Py_Main || $pc > Py_GetArgcArgv

со следующим:

while ($pc < Py_Main || $pc > Py_GetArgcArgv) && ($pc < t_bootstrap || $pc > thread_PyThread_start_new_thread)

В противном случае команды типа pystack не будут завершаться нитями, отличными от основного потока. С помощью этого материала вы можете делать такие вещи, как

gdb> attach <PID>
gdb> info threads
gdb> thread <N>
gdb> bt
gdb> pystack
gdb> detach

и посмотреть, что происходит. Вид.

Вы можете разобрать, что объекты с макросом "pyo". У Криса есть несколько примеров в его блоге.

Удачи.

(Shoutout для Dan blog для получения какой-то ключевой информации для меня, в частности, для исправления резьбы!)

Ответ 4

Если вы имеете в виду pydb, нет способа сделать это. В этом направлении были предприняты определенные усилия: см. svn commit, но он был оставлен. Предположительно winpdb поддерживает его.

Ответ 5

Мой опыт отладки многопоточных программ в PyDev (Eclipse в Windows XP) заключается в том, что потоки, созданные с помощью thread.start_new_thread, не могут быть подключены, но поток создан с помощью threading.Thread может быть подключен. Надеюсь, что информация будет полезной.

Ответ 6

На какой платформе вы пытаетесь это сделать? Большинство отладчиков позволяют подключаться к запущенному процессу с помощью идентификатора процесса. Вы можете либо вывести идентификатор процесса через ведение журнала, либо использовать что-то вроде диспетчера задач. Как только это будет достигнуто, можно будет проверить отдельные потоки и их столы вызовов.

EDIT: у меня нет никакого опыта работы с GNU Debugger (GDB), который является кросс-платформой, однако я нашел ссылку и он может начать вас по правильному пути. В нем объясняется, как добавлять символы отладки (удобные для чтения стеков стека) и как поручить gdb подключаться к запущенному процессу python.

Ответ 7

pdbinject позволяет вам вводить pdb в уже запущенный процесс python.

Исполняемый файл pdbinject работает только под python2, но может также вводить в python3 тоже отлично.