我有一个Python应用程序,它不时卡住,我不知道在哪里。
是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?
某种飞行中的堆叠痕迹?
相关问题:
从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪
我有一个Python应用程序,它不时卡住,我不知道在哪里。
是否有任何方法向Python解释器发出信号,以显示正在运行的确切代码?
某种飞行中的堆叠痕迹?
相关问题:
从Python代码中的方法打印当前调用堆栈 检查正在运行的进程正在做什么:打印未检测的Python程序的堆栈跟踪
当前回答
我是GDB阵营的python扩展。关注https://wiki.python.org/moin/DebuggingWithGdb,这意味着
DNF install GDB python-debuginfo或sudo apt-get install GDB python2.7-dbg GDB python <运行进程>的pid py-bt
同时考虑info threads和thread apply all py-bt。
其他回答
Pydb值得一看,它是“松散地基于gdb命令集的Python调试器的扩展版本”。它包括信号管理器,可以在发送指定信号时启动调试器。
2006年的“代码之夏”项目研究了在名为mpdb的模块中向pydb添加远程调试功能。
从Austin 3.3开始,您可以使用-w/——where选项来发出当前堆栈跟踪。参见https://stackoverflow.com/a/70905181/1838793
如果您想查看正在运行的Python应用程序,以类似top的方式查看“活动”调用堆栈,可以使用austin-tui (https://github.com/p403n1x87/austin-tui)。你可以从PyPI安装它。
pipx install austin-tui
请注意,它需要austin二进制文件才能工作(https://github.com/p403n1x87/austin),但随后您可以使用
austin-tui -p <pid>
用优秀的间谍技术就能做到。它是Python程序的抽样分析器,因此它的工作是附加到Python进程并对其调用堆栈进行抽样。因此,py-spy dump——pid $SOME_PID是转储$SOME_PID进程中所有线程调用堆栈所需要做的全部工作。通常它需要升级的特权(读取目标进程的内存)。
下面是一个线程Python应用程序的示例。
$ sudo py-spy dump --pid 31080
Process 31080: python3.7 -m chronologer -e production serve -u www-data -m
Python v3.7.1 (/usr/local/bin/python3.7)
Thread 0x7FEF5E410400 (active): "MainThread"
_wait (cherrypy/process/wspbus.py:370)
wait (cherrypy/process/wspbus.py:384)
block (cherrypy/process/wspbus.py:321)
start (cherrypy/daemon.py:72)
serve (chronologer/cli.py:27)
main (chronologer/cli.py:84)
<module> (chronologer/__main__.py:5)
_run_code (runpy.py:85)
_run_module_as_main (runpy.py:193)
Thread 0x7FEF55636700 (active): "_TimeoutMonitor"
run (cherrypy/process/plugins.py:518)
_bootstrap_inner (threading.py:917)
_bootstrap (threading.py:885)
Thread 0x7FEF54B35700 (active): "HTTPServer Thread-2"
accept (socket.py:212)
tick (cherrypy/wsgiserver/__init__.py:2075)
start (cherrypy/wsgiserver/__init__.py:2021)
_start_http_thread (cherrypy/process/servers.py:217)
run (threading.py:865)
_bootstrap_inner (threading.py:917)
_bootstrap (threading.py:885)
...
Thread 0x7FEF2BFFF700 (idle): "CP Server Thread-10"
wait (threading.py:296)
get (queue.py:170)
run (cherrypy/wsgiserver/__init__.py:1586)
_bootstrap_inner (threading.py:917)
_bootstrap (threading.py:885)
使用inspect模块。
进口检查 帮助(inspect.stack) 模块检查中的函数堆栈帮助:
堆栈(上下文= 1) 返回调用者帧上面堆栈的记录列表。
我发现它确实很有帮助。
我几乎总是处理多线程,主线程通常不做太多,所以最有趣的是转储所有堆栈(这更像Java的转储)。下面是一个基于这个博客的实现:
import threading, sys, traceback
def dumpstacks(signal, frame):
id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
code = []
for threadId, stack in sys._current_frames().items():
code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""), threadId))
for filename, lineno, name, line in traceback.extract_stack(stack):
code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
if line:
code.append(" %s" % (line.strip()))
print("\n".join(code))
import signal
signal.signal(signal.SIGQUIT, dumpstacks)