python2.7 使用调试的行为与没有调试的不同
Posted
技术标签:
【中文标题】python2.7 使用调试的行为与没有调试的不同【英文标题】:python2.7 using debug behave different then without debug 【发布时间】:2014-08-19 08:53:52 【问题描述】:我的程序中有一个错误,想使用调试来检查它。在我的 IDE (WingIDE) 中,我有一个调试功能。但我不能使用从 shell 调用程序的方法。所以我使用 Python 模块 pdb。我的应用程序是单线程的。
我研究过Code is behaving differently in Release vs Debug Mode,但这对我来说似乎有些不同。
我将其限制在以下代码中。
我做了什么:
我创建了一个简短的方法,只有在不使用 IDE 时才会调用它。
def set_pdb_trace():
run_in_ide = not sys.stdin.isatty()
if not run_in_ide:
import pdb; pdb.set_trace() # use only in python interpreter
这很好,我在很多情况下都使用过。
我想调试以下方法:
import sys
import os
import subprocess32
def call_backported():
command = 'lsb_release -r'
timeout1 = 0.001 # make value too short, so time-out will enforced
try:
p = subprocess32.Popen(command, shell=True,
stdout=subprocess32.PIPE,
stderr=subprocess32.STDOUT)
set_pdb_trace()
tuple1 = p.communicate(input=b'exit %errorlevel%\r\n', timeout=timeout1)
print('No time out')
value = tuple1[0].decode('utf-8').strip()
print('Value : '+ value)
except subprocess32.TimeoutExpired, e:
print('TimeoutExpired')
解释。 我想用超时调用子进程。对于 Python 3.3+,它是内置的,但我的应用程序也可以使用 Python2.7 运行。所以我使用https://pypi.python.org/pypi/subprocess32/3.2.6 作为后向端口。 要读取我使用的返回值How to retrieve useful result from subprocess? 没有超时,将超时设置为 f.e. 1秒该方法按预期工作。打印结果值和“没有超时”。
我想强制超时,所以我将超时时间设置得很短 0.001 。所以现在应该只打印“TimeoutExpired”。
我要执行的是shell。 如果第一个注释掉行 #set_pdb_trace() 'TimeoutExpired' 被打印,那么预期的行为。
现在我取消注释 set_pdb_trace() 并在 shell 中执行。
调试器显示,我按“c”(继续)和“无超时”并打印结果。这个结果与没有调试的情况不同。生成的输出是:
bernard@bernard-vbox2:~/clones/it-should-work/unit_test$ python test_subprocess32.py
--Return--
> /home/bernard/clones/it-should-work/unit_test/test_subprocess32.py(22)set_pdb_trace()->None
-> import pdb; pdb.set_trace() # use only in python interpreter
(Pdb) c
No time out
Value : Release: 13.10
bernard@bernard-vbox2:~/clones/it-should-work/unit_test$
这怎么可能?又该如何解决?
【问题讨论】:
@martijn-pieters No on Ubuntu ,Release: 13.10 输入c
时是打印什么?当你命中断点时,你能在终端中包含一个输出吗?
@martijn-pieters 我在原始问题中添加了这个。
【参考方案1】:
您在打开子进程和写入它之间引入了延迟。
当您创建Popen()
对象时,子进程会立即启动。然后,当您调用 p.communicate()
并尝试对其进行写入时,该进程尚未准备好接收输入,并且该延迟以及读取进程输出所需的时间比您的 0.0.1 超时更长。
当您插入断点时,进程就有机会启动; lsb_release
命令不等待输入并立即产生其输出。在调用p.communicate()
时,无需再等待管道,立即生成输出。
如果您将断点放在Popen()
调用之前,然后点击c
,您将再次看到超时触发器。
【讨论】:
就是这样。 Popen 和 p.communicate 是相关的。这意味着我必须小心将调试语句放在哪里。这种行为与我的 IDE 中的行为相同。所以调试和不调试之间没有真正的区别。谢谢马丁。以上是关于python2.7 使用调试的行为与没有调试的不同的主要内容,如果未能解决你的问题,请参考以下文章
在模拟器/设备上/使用或不使用 Chrome 调试时反应本机行为不同