8

WinPDB を使用して Python をデバッグしようとしていますが、threading.Thread を使用して複数のスレッドがあります。スレッドを個別に制御することは決してできないようです。実行を中断すると、スクリプト全体が中断します。1 つのスレッドのソース コードをステップ実行すると、他のすべてのスレッドは引き続きインターリーブされ、一部の実行が継続されます。これは、シンクロニシティがオンまたはオフの場合に当てはまります。他のスレッドをブレークポイントに保ちながら、スレッドを個別にステップスルーする方法はありませんか?

WinPDB はこれに使用するのに不適切なツールですか? 何を使えばいいのかわからない。Eclipse PyDev は、複数のスレッドを開始するときにデバッガー自体が競合エラーを発生するように見えるため、ほとんど機能しません。

マルチスレッドの Python プログラムを実際に堅牢にデバッグするツールは何ですか?

ありがとうございました。

4

1 に答える 1

1

私は同様の問題を抱えていました。これは最も理想的な答えではありませんが、あなたのために説明します。

私は多かれ少なかれミニデバッガーを書きました。Udp クライアント/サーバーと、グローバル ロックを取得し、0.1 秒スリープしてから解放するだけの関数。この関数は各スレッドに渡されます。次に、デバッグしたい重要な領域の間にこの関数を呼び出しました。プログラムを開始した後、udp サーバーはクライアントをリッスンし、「一時停止」と入力すると、共有関数で使用されているのと同じグローバル ロックを取得し、クライアントで「再生」と入力するまでそれを放棄しませんでした。これを行うと、アプリケーションによっては、かなりタイトなストップを得ることができます。

お役に立てば幸いです...以下の小さなスニペット。私のアプリケーションはテスト プラットフォーム用だったので、基本クラス コンストラクターに関数ポインターを追加し、time.sleep() の代わりにこれを使用して、軽度のデバッグ機能を提供しました。できることは、これを各スレッドに渡し、関数の最初と最後に一時停止関数への呼び出しを追加することです。これにより、ブレークなどが可能になります。いくつかのコマンドを削除しましたが、これができることがわかります必要なだけ拡張できます。

PAUSE_NOW     = thread.allocate_lock()
def pause(s):
'''
    FUNCTION: testStatus

    DESCRIPTION: function passed to all test objects

    INPUTS: none

    RETURNS: none
'''
    global Pause_NOW
    PAUSE_NOW.acquire()
    time.sleep(s)
    PAUSE_NOW.release()

`

def server():
    '''
        \r\n
        FUNCTION: server

        DESCRIPTION: UDP server that launches a UDP client. The client it
                     starts can issue commands defined in cmdlineop. Most
                     functions return a status, but some are meant to block
                     the main thread as a means of pausing a test, in which case
                     a default response is returned.

        INPUTS: none

        RETURNS: none
    '''
    global EXIT
    global Pause_NOW

    host = "localhost"
    port = 21567
    buf  = 1024
    addr = (host,port)

    UDPSock = socket(AF_INET,SOCK_DGRAM)
    UDPSock.bind(addr)
    sleep(1)
    os.startfile('client.py')
    #os.system('start python client.py')
    cmdlineop   =   {
                    'pausenow' : "PAUSE_NOW.acquire()",
                    'playnow'  : "PAUSE_NOW.release()",
                }
    while 1:
        output = 'RECEIVED CMD'
        # if EXIT: break
        data,addr = UDPSock.recvfrom(buf)
        if not data:
            break
        else:
            if cmdlineop.has_key(data.split()[0]):
                exec(cmdlineop[(data.split()[0])])
                UDPSock.sendto(('\n'+output+'\n'),addr)
                data = ''
            else:
                UDPSock.sendto('INVALID CMD',addr)
    UDPSock.close()
于 2010-08-09T04:20:27.727 に答える