Python调试器步进和自由运行模式遵循不同的执行路径

时间:2014-10-15 16:04:19

标签: python debugging

如果我运行脚本

import sys
if sys.gettrace():
    print 'OK'
else:
    assert False, 'good grief'

......喜欢这个

% python -mpdb bugdemo.py

...(Python v.2.7.8)我首先看到这样的提示:

-> import sys
(Pdb)

如果此时我反复输入s来逐步完成脚本,我会看到类似的内容:

> <path-to-script>/bugdemo.py(2)<module>()
-> if sys.gettrace():
(Pdb) s
> <path-to-script>/bugdemo.py(3)<module>()
-> print "OK"
(Pdb) s
OK
--Return--
> <path-to-script>/bugdemo.py(3)<module>()->None
-> print "OK"
(Pdb)

但是,如果不是单步执行代码,而是在第一个调试器提示符处输入ccont的缩写,即继续), < em>代码的执行遵循不同的路径

% python -mpdb bugdemo.py
> <path-to-script>/bugdemo.py(1)<module>()
-> import sys
(Pdb) c
Traceback (most recent call last):
  File "/Users/yt/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py", line 1314, in main
    pdb._runscript(mainpyfile)
  File "/Users/yt/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pdb.py", line 1233, in _runscript
    self.run(statement)
  File "/Users/yt/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bdb.py", line 387, in run
    exec cmd in globals, locals
  File "<string>", line 1, in <module>
  File "bugdemo.py", line 1, in <module>
    import sys
AssertionError: good grief
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> <path-to-script>/bugdemo.py(1)<module>()
-> import sys
(Pdb)

有谁知道这里发生了什么?这是我应该报告的错误 1 吗?还是有办法让它合理化吗?


1 如果这是一个错误,那么是一个错误的:一个调试器,它在步进和自由运行中遵循不同的执行路径比没用还差。

2 个答案:

答案 0 :(得分:5)

lib\bdb.py:227

def set_continue(self):
    # Don't stop except at breakpoints or when finished
    self._set_stopinfo(self.botframe, None, -1)
    if not self.breaks:
        # no breakpoints; run without debugger overhead
        sys.settrace(None)
        frame = sys._getframe().f_back
        while frame and frame is not self.botframe:
            del frame.f_trace
            frame = frame.f_back

即。 pdb在某些情况下删除跟踪功能,这是其私有业务。你试图通过检查它的存在来超越它,从而射击自己的脚。祝贺你。

答案 1 :(得分:2)

documentation for settrace and gettrace非常清楚地表明它们旨在用于实现调试器。假设pdb正在使用settrace,并且当pdb没有预先运行时,我会假设gettrace返回None。

你期待发生什么?那个pdb会设置一个环境,可以完全隐藏调试器在那里的事实,即使你明确地使用了作为调试器挂钩的函数?我真的不认为这是一个错误。上面链接的文档甚至说:(强调我的)

  

CPython实现细节:settrace()函数仅用于实现调试器,分析器,覆盖工具等。它的行为是实现平台的一部分,而不是语言定义的一部分,因此可能无法在所有Python实现中使用。

gettrace和settrace是用于&#34; magic&#34;的语言的奇怪小角落。像调试器一样使用。如果你不知道他们做了什么,就不要打电话给他们。