【问题标题】:Remote hotplug Python debugger远程热插拔 Python 调试器
【发布时间】:2017-03-14 19:52:40
【问题描述】:

如何使用 Python IDE 集成设置可热插拔的远程调试器?例如使用 PyCharm。所谓热插拔,我的意思是:可以即时连接和断开与开发服务器的连接。

我在云中有开发服务器(django、nginx、uwsgi、postgres、debian),并使用 PyCharm 作为主要 IDE(但如果您有任何其他 IDE 的解决方案,请提供)。

有时,我需要在不停止/重新启动开发服务器的情况下连接和调试脚本。使用 PyCharm 的调试器 (pydevd),如果调试器服务器 (Connection refused) 没有工作,开发服务器将无法启动,如果我在开发服务器运行时停止远程调试器,它会崩溃,例如

An existing connection was forcibly closed by the remote host

我找到了 pdg/epdg,但它们没有与 PyCharm 集成。 PyCharm 还有一个很好的特性:“附加到进程”,但它只适用于本地进程。

【问题讨论】:

    标签: python debugging pycharm uwsgi


    【解决方案1】:

    可能可行的基本方法是为要调试的程序设置信号处理程序以加载到调试器中。然后向进程发送一个调试信号(通过kill 命令),您就可以远程附加。

    您可以通过python trepan debuggers 执行此操作

    import signal
    
    def signal_handler(num, f):
        from trepan.interfaces import server as Mserver
        from trepan.api import debug
        connection_opts={'IO': 'TCP', 'PORT': 1955}
        intf = Mserver.ServerInterface(connection_opts=connection_opts)
        dbg_opts = {'interface': intf}
        print('Starting TCP server listening on port 1955.')
        debug(dbg_opts=dbg_opts)
        return
    
    signal.signal(signal.SIGUSR1, signal_handler)
    # Go about your business...
    
    import time
    import os
    print(os.getpid())
    for i in range(10000):
        time.sleep(0.2)
    

    现在运行:

    $ python /tmp/foo.py
    8530
    

    从上面的输出中,我们列出了我们要调试的 Python 进程的 pid。

    现在在 shell 中,我们发送一个信号来告诉进程进入在信号处理程序中设置的调试器。您将不得不调整 进程 ID。

    $ kill -USR1 8530   # Adjust the pid to what you see above
    

    在我们运行 /tmp/foo.py 的 shell 中,您现在应该看到 新输出:

    $ python /tmp/foo.py
    8530
    Starting TCP server listening on port 1955. # This is new
    

    回到我们发出kill -USR1 的shell,我们现在将已停止的进程附加到调试器中:

    $ trepan2 --client --port 1955
    Connected.
    (/tmp/foo.py:11 @101): signal_handler
    -- 11     return
    (trepan2*) list
      6         connection_opts={'IO': 'TCP', 'PORT': 1955}
      7         intf = Mserver.ServerInterface(connection_opts=connection_opts)
      8         dbg_opts = {'interface': intf}
      9         print('Starting TCP server listening on port 1955.')
     10         debug(dbg_opts=dbg_opts)
     11  ->     return
     12
     13     signal.signal(signal.SIGUSR1, signal_handler)
     14     # Go about your business...
     (trepan2*) backtrace
     ->   0 signal_handler(num=10, f=<frame object at 0x7f9036796050>)
          called from file '/tmp/foo.py' at line 11
     ##   1 <module> file '/tmp/foo.py' at line 20
    

    【讨论】:

    • 感谢您的精彩回答!
    猜你喜欢
    • 1970-01-01
    • 2011-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-26
    • 2014-11-06
    • 1970-01-01
    相关资源
    最近更新 更多