Есть ли способ подключить отладчик к многопоточному процессу Python?
Вопрос
Я пытаюсь устранить взаимоблокировку в многопоточном приложении Python после его блокировки.Есть ли способ подключить отладчик для проверки состояния процесса?
Редактировать:Я пытаюсь сделать это в Linux, но было бы здорово, если бы существовало кроссплатформенное решение.В конце концов, это Питон :)
Другие советы
Использовать Винпдб.Это независимая платформа графический отладчик Python под лицензией GPL с поддержкой удаленной отладки по сети, нескольких потоков, модификации пространства имен, встроенной отладки, зашифрованной связи и работает до 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 или новее.
(источник: winpdb.org)
Вы можете подключить отладчик к многопоточному процессу 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 включили в свой каталог Misc образец «.gdbinit», в котором есть несколько полезных макросов.Однако он не поддерживает многопоточную отладку (!).Вам нужно заменить такие строки
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». У Криса есть несколько примеров в его блоге.
Удачи.
(Привет за Блог Дэна для получения некоторой ключевой для меня информации, в частности, исправления потоков!)
Если вы имеете в виду pydb, то сделать это невозможно.В этом направлении предпринимались некоторые усилия:см. коммит svn, но оно было заброшено.Предположительно winpdb поддерживает это.
Мой опыт отладки многопоточных программ в PyDev (Eclipse в Windows XP) показывает, что потоки, созданные с использованием thread.start_new_thread, не могут быть перехвачены, но поток, созданный с использованием threading.Thread, может быть перехвачен.Надеюсь, информация окажется полезной.
На какой платформе вы пытаетесь это сделать?Большинство отладчиков позволяют подключаться к работающему процессу, используя идентификатор процесса.Вы можете вывести идентификатор процесса через журналирование или с помощью чего-то вроде диспетчера задач.Как только это будет достигнуто, появится возможность проверять отдельные потоки и их стеки вызовов.
РЕДАКТИРОВАТЬ:У меня нет опыта работы с кроссплатформенным отладчиком GNU Debugger (GDB), однако я нашел это связь и это может направить вас на правильный путь.В нем объясняется, как добавлять символы отладки (удобно для чтения трассировок стека) и как дать команду gdb подключиться к работающему процессу Python.
pdbinject позволяет вам внедрить pdb в уже запущенный процесс Python.
Исполняемый файл pdbinject работает только под Python2, но может прекрасно внедряться и в Python3.
PyCharm IDE позволяет подключаться к работающему процессу Python, начиная с версии 4.0.
Здесь описано, как это сделать.