Python pdb (debugger) disp эквивалентен?

Есть ли эквивалент pdb для disp в gdb?

например. когда я отлаживаю C использованием gdb, я могу иметь переменные, напечатанные на каждом шаге через код, набрав:

disp var

Когда я отлаживаю python с помощью pdb, мне нужна аналогичная функциональность, но disp, похоже, не существует, документация python pdb, похоже, не предлагает альтернативы - но это похоже на странное упущение?

Ответ 1

В приведенном ниже коде используются функции интроспекции Python для добавления двух новых команд в модуль PDB 0 просто поместите данную функцию и ее вызов в отдельный модуль и импортируйте этот модуль перед началом отладки - вам нужно, чтобы команды "disp" и "undisp" добавляли и оттягивали часы для переменных.

Он работает с помощью monkeypatching Python pdb module, который написан на чистом питоне.

# -*- 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

К сожалению, я мог только заставить отображать состояние переменных, как раньше, до выполнения последней команды. (Я попробовал немного, но monkeypatching модуль bdb, который является базой для Pdb, похоже, не работает). Вы можете попробовать и изменить методы в pdb.Pdb, bdb.Bdb или cmd.Cmd, которые украшены wrap, чтобы найти тот, который вызывается после изменения состояния отлаженного кадра.

Ответ 2

Вы можете настроить некоторые псевдонимы, которые сделают это для вас:

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')"

Ответ 3

Во время отладки pdb вы можете ввести обычный код python, за пределами команд с одной буквой, поэтому для вас следует использовать print var.