2011-12-15 31 views
10

在gdb中是否有相当于disp的pdb?Python的pdb(调试器)disp等效?

例如当我用gdb调试C我可以通过键入印有通过代码的每个“步骤”变量:

disp var 

当我使用PDB我想类似的功能调试Python,但disp似乎并不在那里,python pdb文档似乎没有提供一个替代方案 - 但它看起来像是一个奇怪的遗漏?

+0

也许IPDB具有一定的替代性功能 – bph 2011-12-19 14:52:37

+0

作为替代方案,如果你喜欢一个漂亮的UI,你可能需要使用[ pudb](https://pypi.python.org/pypi/pudb)。 – 2014-08-05 19:25:38

回答

1

在pdb调试期间,您可以输入正常的python代码,超出一个字母命令 - 所以只需使用print var应该适合您。

3

下面的代码使用Python内省功能向PDB模块添加两个新命令0 只需将给定的函数及其调用放在单独的模块中,并在开始调试之前导入此模块 - 您应该拥有“disp '和'undisp'命令会将手表添加到变量并将其撤回。

它通过monkeypatching Python的pdb模块,它是用纯python编写的。

# -*- coding: utf-8 -*- 

def patch_pdb(): 
    import pdb 

    def wrap(func): 
     def new_postcmd(self, *args, **kw): 
      result = func(self, *args, **kw) 
      if hasattr(self, "curframe") and self.curframe and hasattr(self, "watch_list"): 
       for arg in self.watch_list: 
        try: 
         print >> self.stdout, "%s: %s"% (arg, self._getval(arg)) + ", ", 
        except: 
         pass 
       self.stdout.write("\n") 
      return result #func(self, *args, **kw) 

     return new_postcmd 

    pdb.Pdb.postcmd = wrap(pdb.Pdb.postcmd) 

    def do_disp(self, arg): 
     if not hasattr(self, "watch_list"): 
      self.watch_list = [] 
     self.watch_list.append(arg) 

    pdb.Pdb.do_disp = do_disp 

    def do_undisp(self, arg): 
     if hasattr(self, "watch_list"): 
      try: 
       self.watch_list.remove(arg) 
      except: 
       pass 

    pdb.Pdb.do_undisp = do_undisp 

patch_pdb() 

if __name__ == "__main__": 
    # for testing 
    import pdb; pdb.set_trace() 
    a = 0 
    for i in range(10): 
     print i 
     a += 2 

不幸的是,我只能让它显示变量的状态,因为他们以前执行最后一个命令。 (我尝试了一下,但monkypatching bdb模块,这是Pdb的基础似乎也没有工作)。您可以尝试更改由wrap修饰的pdb.Pdb,bdb.Bdb或cmd.Cmd中的方法,以找到调试帧状态更改后调用的方法。

3

您可以设置一些别名,会为你做到这一点:

alias n next;; p var 
alias s step;; p var 

打印变量名称的整个列表作为练习留给读者。不幸的是,这样做意味着当您向调试器发送空行时,它执行的“最后一个命令”是p var,而不是例如n。如果要解决这个问题,那么你就可以在PDB命令,而不是使用这个有点哈克集:

!global __stack; from inspect import stack as __stack 
!global __Pdb; from pdb import Pdb as __Pdb 
!global __pdb; __pdb = [__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self") for __framerec in __stack() if (__framerec[0].f_locals.get("pdb") or __framerec[0].f_locals.get("self")).__class__ == __Pdb][-1] 

alias s step;; p var;; !__pdb.lastcmd = "!__pdb.cmdqueue.append('s')" 
alias n next;; p var;; !__pdb.lastcmd = "!__pdb.cmdqueue.append('n')" 
相关问题