2009-04-07 12 views
8

Z tego co wiem, pdb nie rozpoznaje, kiedy kod źródłowy zmienił się pomiędzy "uruchomieniami". Oznacza to, że jeśli debuguję, zauważ błąd, napraw błąd i uruchom program w pdb (tzn. Bez wychodzenia z pdb), pdb nie przekompiluje kodu. Nadal będę debugować starą wersję kodu, nawet jeśli pdb zawiera nowy kod źródłowy.Jak uczynić pdb rozpoznać, że źródło zmieniło się między biegami?

Czy pdb nie aktualizuje skompilowanego kodu jako zmiany źródła? Jeśli nie, czy istnieje sposób, aby to zrobić? Chciałbym móc pozostać w pojedynczej sesji pdb, aby zachować moje punkty przerwania i takie.

FWIW, gdb zauważy, że program, pod którym debuguje zmiany, jest pod nim, ale tylko po ponownym uruchomieniu tego programu. To jest zachowanie, które próbuję replikować w pdb.

Odpowiedz

2

Co masz na myśli przez "ponowne uruchomienie programu w pdb?" Jeśli moduł został zaimportowany, Python nie będzie go ponownie czytać, chyba że wyraźnie poprosisz o to, to jest z reload(module). Jednakże, reload jest daleki od kuloodporności (zobacz xreload dla innej strategii).

Istnieje wiele pułapek w przeładowywaniu kodu Pythona. Aby bardziej skutecznie rozwiązać problem, można owinąć pdb klasą, która na przykład zapisuje informacje o punkcie przerwania w pliku na dysku i odtwarza je z powrotem.

(Niestety, zignorować pierwszą wersję tej odpowiedzi, że jest wcześnie i nie przeczytałem pytanie dość ostrożnie.)

+0

Co mam na myśli przez "powtórka" jest pojęciowo, co mam na myśli przez ponowne uruchomienie programu z Pythona wiersz poleceń. pdb wyraźnie rozumie pojęcie mojego programu, więc zastanawiam się, kiedy uruchomi mój program po raz drugi, jeśli uda mi się go skompilować w razie potrzeby. – user88028

+0

Możesz spróbować użyć 'reload' z wewnątrz pdb przed ponownym uruchomieniem, ale znowu, w zależności od struktury twojego programu, może on nie być niezawodny. (FWIW, uważam to za największą porażkę Pythona jako języka, pochodzącego ze środowisk takich jak Smalltalk i Lisp, to po prostu przygnębiające.) –

+0

@NicholasRiley Chciałbym włączyć xreload jako polecenie w pythonowych debuggerach (trepan3k https: //pypi.python.org/pypi/trepan3k i trepan2 https://pypi.python.org/pypi/trepan2). Są to GPL3. Czy to w porządku? Czy jesteś autorem? – rocky

3

Poniżej mini-moduł może pomóc. Jeśli importujesz go w sesji WPB, następnie można użyć:

pdb> pdbs.r() 

w dowolnym momencie, aby wymusić-przeładować wszystkie moduły non-system oprócz głównej. Kod pomija to, ponieważ powoduje zgłoszenie wyjątku ImportError ("Nie można ponownie zainicjować wewnętrznego modułu main").

# pdbs.py - PDB support 

from __future__ import print_function 

def r(): 
    """Reload all non-system modules, so a pdb restart 
    will reload anything new 
    """ 
    import sys 
    # This is likely to be OS-specific 
    SYS_PREFIX = '/usr/lib' 

    for k, v in sys.modules.items(): 
     if not hasattr(v, '__file__'): 
      continue 
     if v.__file__.startswith(SYS_PREFIX): 
      continue 
     if k == '__main__': 
      continue 
     print('reloading %s [%s]' % (k, v.__file__)) 
     reload(v) 
+0

Po uruchomieniu pdb.r() otrzymuję: *** AttributeError: obiekt 'dict' nie ma atrybutu 'iteritems' – Chelmite

+0

Moje przeprosiny - .iteritems() nie jest kompatybilny z Pythonem 3.x. Zmodyfikowałem kod, aby działał. – pourhaus

Powiązane problemy