栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用pdb附加进程

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用pdb附加进程

目前, pdb 无法停止并在正在运行的程序上开始调试。您还有其他选择:

广东发展银行

您可以使用GDB在C级别进行调试。这有点抽象,因为您是在研究Python的C源代码,而不是实际的Python脚本,但是在某些情况下它可能很有用。指令在这里:https
:
//wiki.python.org/moin/DebuggingWithGdb。他们太累了,无法在此处进行总结。

第三方扩展和模块

只是为了“PDB连接过程”谷歌搜索揭示了几个项目给予PDB这种能力:
Pyringe:https://github.com/google/pyringe
Pycharm:https://blog.jetbrains.com/pycharm/2015/02/ feature-spotlight-python-
debugger-and-attach-to-process
/
Python
Wiki的此页面具有多种替代方法:https :
//wiki.python.org/moin/PythonDebuggingTools


对于您的特定用例,我有一些解决方法的想法:

讯号

如果你是在UNIX上,可以使用的信号在像这样的博客文章,试图制止并连接到正在运行的脚本。

此引用块直接从链接的博客文章中复制:

当然,pdb已经具有在程序中间启动调试器的功能,其中最著名的是pdb.set_trace()。但是,这需要您知道要在哪里开始调试,这也意味着您不能将其留在生产代码中。

但是我一直羡慕我可以用GDB做什么:只是中断正在运行的程序,然后开始使用调试器进行调试。在某些情况下这可能很方便,例如,您陷入了困境并想进行调查。今天我突然想到:注册一个设置跟踪功能的信号处理程序!这里是概念证明代码:

import osimport signalimport sysimport timedef handle_pdb(sig, frame):    import pdb    pdb.Pdb().set_trace(frame)def loop():    while True:        x = 'foo'        time.sleep(0.2)if __name__ == '__main__':    signal.signal(signal.SIGUSR1, handle_pdb)    print(os.getpid())    loop()

现在,我可以将SIGUSR1发送到正在运行的应用程序并获取调试器。可爱!

我想您可以通过使用Winpdb允许远程调试来解决这个问题,以防您的应用程序不再连接到终端。上面代码的另一个问题是,调用pdb后似乎无法恢复程序,退出pdb后您仅获得了一个追溯并完成了(但是由于这只是bdb引发了bdb.BdbQuit异常,我猜这可以通过几种方式解决)。最后一个紧迫的问题是在Windows上运行此程序,我对Windows不太了解,但是我知道它们没有信号,所以我不确定在该怎么做。

条件断点和循环

如果没有可用的信号,将锁或信号量获取包装在增加计数器的循环中,并且仅在计数达到可笑的数量时才停止,您仍然可以使用PDB。例如,假设您有一个锁,怀疑是死锁的一部分:

lock.acquire() # some lock or semaphore from threading or multiprocessing

这样重写:

count = 0while not lock.acquire(False): # Start a loop that will be infinite if deadlocked    count += 1    continue # now set a conditional breakpoint here in PDB that will only trigger when  # count is a ridiculously large number:  # pdb> <filename:linenumber>, count=9999999999

当计数非常大时(希望)指示在那里发生了死锁,应该触发断点。如果您发现在锁定对象似乎未显示死锁时触发该事件,那么您可能需要在循环中插入一小段时间延迟,以免其增加得不那么快。您可能还需要处理断点的触发阈值,以使其在正确的时间触发。在我的示例中,该数字是任意的。

另一个变体是不使用PDB,而是在计数器变大时有意引发异常,而不是触发断点。如果编写自己的异常类,则可以使用它来捆绑异常中的所有本地信号量/锁定状态,然后在退出脚本之前将其捕获到脚本的顶层以将其打印出来。

文件指示器

在不依赖正确计数器的情况下使用死锁循环的另一种方法是改为写入文件:

import timewhile not lock.acquire(False): # Start a loop that will be infinite if deadlocked    with open('checkpoint_a.txt', 'a') as fo: # open a unique filename        fo.write("nHit") # write indicator to file        time.sleep(3)     # pause for a moment so the file size doesn't explode

现在,让您的程序运行一两分钟。杀死程序并浏览那些“检查点”文件。如果死锁是造成停滞程序的原因,则在其中多次写入“ hit”一词的文件会多次表明导致死锁的锁。

您可以通过循环打印变量或其他状态信息而不只是常量来扩展此功能。例如,您说您怀疑死锁是在循环中发生的,但不知道它正在进行什么迭代。让此锁定循环转储循环的控制变量或其他状态信息,以标识发生死锁的迭代。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/651613.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号