2014-11-24 19 views
1

我想在异常期间找出所有“调用”堆栈帧中的所有活动变量。在异常期间检索所有堆栈帧中的所有活动变量

例如,请考虑下面的例子来说明异常渗出高达callClient场景

import time 

def mainFunc(): 
    now = time.time() 
    author = "me" 
    callClient() 

def callClient(): 
    message = "Hello, World!" 
    to = "stackoverflow.com" 
    callNoOp() 
    callException() 

def callNoOp(): 
    subject = "Question in stack trace" 
    print "No-op" 

def callException(): 
    question = "What do I do?" 
    raise Exception("Vishwanathan, vellai vendum!") 

mainFunc() 

。我想看看那个时候所有的活动变量。 locals()会帮助我这种要求。

我还想知道的是messageto在​​3210的值。而异常发生时的值为question

我已经通过了traceback module docs。它似乎打印堆栈跟踪,但不是在这些堆栈帧中激活的变量。

+0

你为什么要调用一个函数来引发异常?如果你从'callClient'提出它,你就可以很容易地在追踪中包含'to'和'message'。你能否提供一个你想要做的不太抽象的例子? – jonrsharpe 2014-11-24 09:31:08

+0

我试图说明我最近面临的情况。最近继承了一个代码,没有在多个地方失败的文档。我没有授权对代码进行大的修改,以免在这个高流量的季节变得不稳定。我只依靠日志。我想用更多的数据填充日志,这可以帮助我进行调试。乔恩,你会考虑取消倒票吗? – Sriram 2014-11-24 09:42:25

+1

@jonrsharpe:可能会产生一个示例回溯。 – 2014-11-24 09:43:04

回答

1

我已经能够找到暂时的解决方法,它看起来像这样。

def mainFunc(): 
    now = time.time() 
    author = "me" 
    try: 
     callClient() 
    except: 
     tb = sys.exc_info()[2] 
     while tb: 
      print tb.tb_lineno, "@", tb.tb_frame.f_locals 
      tb = tb.tb_next 
2

回溯包含一个对象链,通过tb_next属性链接在一起。每个追溯对象还通过tb_frame链接到该帧,并且每个帧都有一个f_locals属性。

给出一个回溯的对象,就可以打印所有当地人沿链:

current = traceback 
while current is not None: 
    print current.tb_frame.f_locals 
    current = current.tb_next 

见Python的数据模型的Standard type hierarchy section(向下滚动到回溯对象)。

你也可以看看的inspect.trace() utility function,其中解包链到一个名为元组序列:

import inspect 

for frame_info in inspect.trace(): 
    print frame_info[0].f_locals 

一定要确保你清楚地回溯明确的任何引用;因为回溯包含对当前名称空间的引用,所以在此处创建循环引用几乎是微不足道的。最好的做法是延迟清除这些引用,最糟糕的情况是一个带有__del__方法的对象参与了这个循环,然后垃圾收集永远不会破坏那个循环,并且你有内存泄漏。

+0

非常感谢Martijn。我在黑暗中射箭,能够找到类似于你的解决方案的东西(我也在下面发布了我的发现)。我打算提高你的答案。 – Sriram 2014-11-24 09:45:52