【问题标题】:Python debugging, stop at particular outputPython 调试,在特定输出处停止
【发布时间】:2013-12-20 12:34:35
【问题描述】:

我有一个复杂的 python 项目,其中包含许多模块、记录器、扭曲的延迟和其他东西。

在代码中的某处,某行被打印到日志中,我想找出在哪里。通常我只是在代码库中搜索该字符串,但现在该字符串是动态生成的,因此不可搜索。

如果有什么方法可以在某种调试模式下运行 python,我会徘徊,并告诉它在 sdout 中出现某些模式时停止,然后在停止的代码中打印位置?

【问题讨论】:

    标签: python debugging logging


    【解决方案1】:

    替换sys.stdout怎么样?

    例如:

    import sys
    import traceback
    
    
    class StacktraceOnPrint:
    
        def __init__(self, orig_stdout, substring):
            self.orig_stdout = orig_stdout
            self.substring = substring
    
        def write(self, txt):
            if self.substring in txt:
                traceback.print_stack() # OR  import pdb; pdb.set_trace()
            self.orig_stdout.write(txt)
    
    
    sys.stdout = StacktraceOnPrint(sys.stdout, 'blah')
    print 'test ...'
    print 'Hello blah.'
    print 'test ...'
    

    注意 traceback.print_stack 使用 sys.stderr。如果您想捕捉sys.stderr,请使用不同的功能(如traceback.format_stack)。否则它会永远递归;导致RuntimeError: maximum recursion depth exceeded ..

    【讨论】:

      【解决方案2】:

      您可以使用pdb module。 这将使您能够在运行时以交互方式调试代码。 您可能可以编写一个脚本来“逐步”运行您的程序,直到您在日志文件中读取该行。

      【讨论】:

      • 试了试,调试了第三个小时就放弃了。 :( 开个玩笑。在我的项目中可能需要数年时间才能以这种方式找到那条线。
      • 您不必“手动”操作。编写一个脚本来为你做这件事。
      【解决方案3】:

      您可以通过设置格式化程序为每个日志记录包含路径名、模块、funcName、行号

      formatter = logging.Formatter('[%(asctime)s] p%(process)s {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s','%m-%d %H:%M:%S')
      

      【讨论】:

      • 做到了,但该输出可能不是来自记录器。
      • 如果输出来自打印语句,请尝试this
      • 但是你需要知道在哪一行插入那个调用,它告诉它是在哪一行被调用的。真是个悖论。 :)
      【解决方案4】:

      看起来你正在使用扭曲。您可以在pdb 下启动您的扭曲程序。检查twistd --help

      ...
      -b, --debug            run the application in the Python Debugger (implies
                             nodaemon), sending SIGUSR2 will drop into debugger
      ...
      

      pdb 下启动程序后,你可以在你喜欢的地方设置断点。您还可以指定要执行断点的条件:

      (Pdb) b myfunc, somecondition
      

      但在您的特定情况下,似乎很难检测到破坏程序的地方。

      所以你可以考虑另一种方法。例如,您可以将日志重定向到某些脚本的标准输入。此脚本监视特定的日志行。当它检测到有问题的行时,脚本会将SIGUSR2 发送到扭曲的程序,然后它会进入调试器。之后,只需使用 pdb 检查您的程序。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-28
        • 1970-01-01
        • 2023-04-03
        • 1970-01-01
        相关资源
        最近更新 更多