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 调试时反应本机行为不同

调试优化的构建会导致程序行为不同吗?

为啥发布和调试模式下的代码行为不同?

带有 javascript 调试的 Visual Studio 在直接运行和在调试模式下运行时显示不同的行为

Python3 在 Linux 中调用 Python2 多处理的行为与在 Windows 中不同