Проблема с Emacs pdb и точками останова в многопоточном коде Python - PullRequest
4 голосов
/ 06 октября 2010

Я запускаю Emacs 23.2 с python.el и отлаживаю некоторый код Python с pdb.

Мой код порождает одноуровневый поток с использованием модуля threading, и я устанавливаю точку останова в начале метода run(), но pdb разрыв никогда не обрабатывается, даже если код определенно выполняется и работает для всех намерения и цели.

У меня сложилось впечатление, что я могу использовать pdb для установки точек останова в любом потоке , хотя полная многопоточная отладка фактически не поддерживается.

Я ошибаюсь, предполагая, что pdb в M-x pdb вызове может прерваться в любом потоке? Если вы не верите мне, попробуйте этот минимальный пример для себя.

import threading

class ThreadTest(threading.Thread):
    def __init__(self,):
        threading.Thread.__init__(self)

    def run(self):
        print "Type M-x pdb, set a breakpoint here then type c <RET>..."
        print "As you can see it does not break!"

if __name__ == '__main__':
    tt = ThreadTest()

    tt.start()

Благодаря Пьеру и тексту книги, на которую он ссылается, я попытался включить pdb.set_trace() следующим образом:

def run(self):
    import pdb; pdb.set_trace()
    print "Set a breakpoint here then M-x pdb and type c..."

Но это только ломает и предлагает pdb элементы управления для step, затем продолжить и так далее, если оно выполняется из консоли и запускается непосредственно в интерпретаторе Python, и, что особенно важно, not через Mx pdb - по крайней мере, с моей конфигурацией Emacs и pdb.

Итак, мой первоначальный вопрос можно было бы перефразировать:

Есть ли способ вызвать программу на Python из Emacs, где эта программа использует встроенный вызов pdb (тем самым поддерживая разрывы в многопоточных приложениях) и для чего автоматически создается буфер управления коментариями pdb?

или

Если я запускаю свое приложение Python с использованием Mx pdb, и оно содержит встроенный вызов pdb, как лучше всего справиться с тем фактом, что это приводит к pdb-session-inside-a-pdb-session с соответствующей потерей контроля?

Ответы [ 2 ]

1 голос
/ 06 октября 2010

Используете ли вы по умолчанию python.el? Я отказался от этого и начал использовать python-mode.el. Затем введите M-x shell, из приглашения введите python myproblem.py (замените, конечно, на имя вашей программы), и оно остановится на строке set_trace. Он работает из коробки с интеграцией с PDB. (И это работает в вашей программе).

1 голос
/ 06 октября 2010

См. http://heather.cs.ucdavis.edu/~matloff/158/PLN/ParProcBook.pdf,, есть раздел о многопоточной отладке.

3.6.1 Using PDB to Debug Threaded Programs
Using PDB is a bit more complex when threads are involved. One cannot, for instance, simply do something
like this:
pdb.py buggyprog.py
because the child threads will not inherit the PDB process from the main thread. You can still run PDB in
the latter, but will not be able to set breakpoints in threads.
What you can do, though, is invoke PDB from within the function which is run by the thread, by calling
pdb.set trace() at one or more points within the code:
import pdb
pdb.set_trace()
In essence, those become breakpoints.
For example, in our program srvr.py in Section 3.1.1, we could add a PDB call at the beginning of the loop
in serveclient():
while 1:
import pdb
pdb.set_trace()
# receive letter from client, if it is still connected
k = c.recv(1)
if k == ’’: break
You then run the program directly through the Python interpreter as usual, NOT through PDB, but then the
program suddenly moves into debugging mode on its own. At that point, one can then step through the code
using the n or s commands, query the values of variables, etc.
PDB’s c (“continue”) command still works. Can one still use the b command to set additional breakpoints?
Yes, but it might be only on a one-time basis, depending on the context. A breakpoint might work only once,
due to a scope problem. Leaving the scope where we invoked PDB causes removal of the trace object. Thus
I suggested setting up the trace inside the loop above.
...