Могу ли я поставить точки останова на фоновые потоки в Python?

Я использую плагин PyDev для Eclipse и пытаюсь установить точку останова в некотором коде, который запускается в фоновом потоке. Точка останова никогда не срабатывает, даже если код выполняется. Вот небольшой пример:

import thread

def go(count):
    print 'count is %d.' % count # set break point here

print 'calling from main thread:'
go(13)
print 'calling from bg thread:'
thread.start_new_thread(go, (23,))

raw_input('press enter to quit.')

Точка останова в этом примере срабатывает при вызове в основном потоке, но не при вызове из фонового потока. Что я могу сделать, или это ограничение отладчика PyDev?

Обновлять

Спасибо за обход. Я отправил запрос функции PyDev, и он был выполнен. Он должен быть выпущен с версией 1.6.0. Спасибо, команда PyDev!


person Don Kirkby    schedule 24.06.2010    source источник


Ответы (4)


Проблема в том, что в модуле потока нет API, который бы знал, когда начинается поток.

Что вы можете сделать в своем примере, так это установить функцию трассировки отладчика самостоятельно (как указал Алекс), как в приведенном ниже коде (если вы не находитесь в удаленном отладчике, в настоящее время требуется pydevd.connected = True - я изменю pydev, так что это больше не нужно). Вы можете добавить try..except ImportError для импорта pydevd (что не удастся, если вы не работаете в отладчике)

деф идти (количество):

   import pydevd
   pydevd.connected = True
   pydevd.settrace(suspend=False)
   print 'count is %d.' % count # set break point here

Теперь, если подумать, я думаю, что pydev может заменить метод start_new_thread в модуле потока, предоставляя свою собственную функцию, которая настроит отладчик, а затем вызовет исходную функцию (только что сделал это, и, похоже, работает, поэтому, если вы используйте nightly, который будет доступен через несколько часов, который станет будущим 1.6.0, он должен работать без каких-либо специальных действий).

person Fabio Zadrozny    schedule 14.07.2010
comment
Эй, это отличная новость! Спасибо за новую функцию. - person Don Kirkby; 15.07.2010
comment
как ни странно, у меня такая же проблема в pydev 2.6. У меня есть приложение с графическим интерфейсом, в котором класс A запускает класс B (QtCore.QThread), а отладчик не останавливается в методах B, пока код выполняется. Если я пытаюсь перейти к вызову b.start(), отладчик отправляет меня в конец конструкции main - person Eugene Sajine; 28.08.2012
comment
я не могу разрешить pydevd (python 2.7), поэтому этот обходной путь не для меня - person Eugene Sajine; 19.10.2012
comment
pydevd находится по адресу eclipse/plugins/org.python.pydev_XXX/pysrc. Вы должны добавить его в свой путь к python. В последних версиях PyDev есть шаблон «pydevd», который добавит его в ваш путь, а также выполнит settrace. - person Fabio Zadrozny; 19.10.2012
comment
@Fabio, я использую PyDev 3.9 и не вижу точек останова в фоновых потоках, созданных с помощью потоков. Мне все еще нужно использовать pydevd.settrace(suspend=False), чтобы заставить работать. Должно ли ваше исправление также охватывать потоки, созданные с помощью многопоточности (по сравнению с потоком)? - person studgeek; 06.05.2016

Основная проблема связана с sys.settrace, низкоуровневая функция Python, используемая для выполнения всей трассировки и отладки — как говорится в документации,

Функция зависит от потока; чтобы отладчик поддерживал несколько потоков, он должен быть зарегистрирован с помощью settrace() для каждого отлаживаемого потока.

Я считаю, что когда вы устанавливаете точку останова в PyDev, результирующий вызов settrace всегда происходит в основном потоке (в последнее время я не смотрел PyDev, поэтому они, возможно, добавили какой-то способ обойти это, но я не помню ни одного из них). время, когда я смотрел).

Обходной путь, который вы можете реализовать самостоятельно, заключается в том, чтобы в основном потоке после установки точки останова использовать sys.gettrace, чтобы получить функцию трассировки PyDev, сохранить ее в глобальной переменной и убедиться, что во всех интересующих потоках вызывается sys.settrace с этой глобальной переменной в качестве аргумента — немного громоздко (тем более для потоков, которые уже существуют на момент установки точки останова!), но я не могу придумать более простой альтернативы.

person Alex Martelli    schedule 25.06.2010
comment
Иногда это работает. Похоже, мне нужно вызвать sys.settrace() в другом кадре стека, где находится точка останова. Я не исследовал полностью, но это работает достаточно хорошо для меня. Спасибо. - person Don Kirkby; 25.06.2010
comment
@ Дон, не за что - я думаю, функция трассировки PyDev должна каким-то образом отвечать за эту проблему с другим фреймом (хотя неясно, как именно - есть некоторые возможности, но даже обнаружение, вероятно, не поможет исправить), но в любом случае, я рад, что это может сработать для вас. Обязательно добавьте запрос функции для перерыва в любом потоке в трекере PyDev, чтобы они знали, что это желательно! - person Alex Martelli; 25.06.2010

На этот вопрос я нашел способ запуска отладчика командной строки:

import pdb; pdb.set_trace()

Его не так просто использовать, как отладчик Eclipse, но это лучше, чем ничего.

person Don Kirkby    schedule 25.06.2010

Для меня это сработало в соответствии с одним из сообщений Фабио после установки трассировки с помощью setTrace("000.000.000.000") # где 0 - это IP-адрес вашего компьютера, на котором работает Eclipse/PyDev.

threading.settrace(pydevd.GetGlobalDebugger().trace_dispatch)
person Kevin Parker    schedule 13.11.2013
comment
Оно работает !! Спасибо, я действительно удивлен небольшим количеством сообщений на pydevd. - person Michael Dussere; 27.05.2019