pdb 调试异常退出问题

2013-02-28 16:54:15 +08:00
 lvii
各位兄台,今天学习 pdb 调试程序遇到一个异常退出的问题,不知道是哪里的问题

$ cat debug_test.py

#!/usr/bin/python2
# coding=utf8

hello='string: hello'
world='string: world'

def foo():
text = "hello world"
return text

import pdb
pdb.set_trace()

ret=foo()
print ret

这断代码,执行进入 pdb 后

1. 输入 'n' 单步调试,调试到结束后,会异常退出

$ python debug_test.py
> /home/i/me/debug_test.py(14)<module>()
-> ret=foo()
(Pdb) n
> /home/i/me/debug_test.py(15)<module>()
-> print ret
(Pdb) n
hello world
--Return--
> /home/i/me/debug_test.py(15)<module>()->None
-> print ret
(Pdb) n
Exception AttributeError: "'NoneType' object has no attribute 'path'" in <function _remove at 0x13a9668> ignored

2. 输入 'q' 退出,会抛出异常,而不是正常退出

$ python debug_test.py
> /home/i/me/debug_test.py(14)<module>()
-> ret=foo()
(Pdb) q
Traceback (most recent call last):
File "debug_test.py", line 14, in <module>
ret=foo()
File "debug_test.py", line 14, in <module>
ret=foo()
File "/usr/lib/python2.7/bdb.py", line 49, in trace_dispatch
return self.dispatch_line(frame)
File "/usr/lib/python2.7/bdb.py", line 68, in dispatch_line
if self.quitting: raise BdbQuit
bdb.BdbQuit

3. 用 python2 -m pdb debug_test.py 这种调试方法

a. 按 'n' 调试到脚本最后,可以继续从头再调试一次,而不是异常退出
b. 按 'q' 退出是正常

但命令行参数调试方式,是从 *第一行* 开始的,不能像 pdb.set_trace() 可以在脚本中指定调试位置灵活

请各位兄台,帮忙诊断一下,问题在哪里?谢谢 :)
7939 次点击
所在节点    Python
9 条回复
xsaps
2013-03-01 14:43:22 +08:00
应该是pdb.set_trace()调用的问题
这样有同样的问题
<pre>
import pdb

pdb.set_trace()
print 'hello'
</pre>
这样next就没有异常
<pre>
import pdb
def foo():
pdb.set_trace()
print 'hello'

pdb.run('foo()')
</pre>
lvii
2013-03-05 11:35:33 +08:00
https://gist.github.com/lvii/5087791

@xsaps 兄,我试了 pdb.run('foo()') 调试到后面

16 -> pdb.run('foo()')
17
[EOF]
(Pdb) n
> <string>(1)<module>()
(Pdb) l
[EOF]
(Pdb) n
--Return--
> <string>(1)<module>()->None
(Pdb) l
[EOF]
(Pdb) n
## 退出,无异常

但是,如果按 'q' 退出,还是会有异常的。pdb.run(...) 是在交互式 shell 中启用 pdb 貌似
对你的回复,原理还不识很明白,还请继续抛玉 :)
lvii
2013-03-05 11:45:56 +08:00
lvii
2013-03-05 11:46:44 +08:00
<script src="http://gist.github.com/lvii/5087791"> </script>
lvii
2013-03-05 11:49:52 +08:00
lvii
2013-03-05 11:51:31 +08:00
lvii
2013-03-05 11:52:23 +08:00
怎么插入 gist 代码呢 …… 测试了几个,咋都不行 ……
xsaps
2013-03-05 22:28:33 +08:00
@lvii 哎呀我也是Python新手, 个人觉得这是个BUG, 而且感觉是个坑, 而且我太懒了, 不想深入研究...你懂的. 有几个问题
1. 看gist你用的是Linux环境? 我用的是Windows, python 2.7.3, 可能有所不同, 我这里放到pdb.run里面后, 按'q'退出没有异常. 不放到pdb.run()里, 按'q'退出异常, 但是用python -m pdb同样按'q'退出也没有异常.
2. 我看gist里提到的issue16446里的patch, 做的事大概是保存了一个trace前的frame, 退出调试的时候还原那个frame, 所以我猜测set_trace调用的时候是会改动程序执行上下文的一些东东的, 退出的时候没还原, 就异常了. 但是放到pdb.run里面, 可能run函数会做一些清理(或者说把异常捕捉并处理了?), 具体我就不清楚了...
3. 我还遇到一个类似的问题, 就是不论用不用pdb.run(), 进入pdb交互状态后, 执行run命令重新调试程序, 会抛出一个Restart异常. 但是用python -m pdb就没这个问题. 具体原因就没有深究了...
如果有啥新发现欢迎分享.
binux
2013-03-05 22:34:10 +08:00
按c

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/61574

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX