Mam moduł, którego używam do takich sytuacji - gdzie proces będzie działał przez długi czas, ale czasami utknie z nieznanych i nieodwracalnych powodów. Jest nieco zhackowany i działa tylko na Uniksie (wymaga sygnałów):
import code, traceback, signal
def debug(sig, frame):
"""Interrupt running process, and provide a python prompt for
interactive debugging."""
d={'_frame':frame} # Allow access to frame object.
d.update(frame.f_globals) # Unless shadowed by global
d.update(frame.f_locals)
i = code.InteractiveConsole(d)
message = "Signal received : entering python shell.\nTraceback:\n"
message += ''.join(traceback.format_stack(frame))
i.interact(message)
def listen():
signal.signal(signal.SIGUSR1, debug) # Register handler
Aby użyć, po prostu wywołaj funkcję Listen () w pewnym momencie, gdy program się uruchamia (możesz nawet umieścić go w site.py, aby wszystkie programy python go używały) i pozwolić mu działać. W dowolnym momencie wyślij procesowi sygnał SIGUSR1, używając kill lub w pythonie:
os.kill(pid, signal.SIGUSR1)
Spowoduje to, że program przejdzie do konsoli Pythona w punkcie, w którym się aktualnie znajduje, pokazując ślad stosu i umożliwiając manipulowanie zmiennymi. Użyj control-d (EOF), aby kontynuować działanie (choć zauważ, że prawdopodobnie przerwiesz każde wejście / wyjście itp. W miejscu, w którym zasygnalizujesz, więc nie jest to w pełni nieinwazyjne.
Mam inny skrypt, który robi to samo, tyle że komunikuje się z uruchomionym procesem za pomocą potoku (aby umożliwić debugowanie procesów w tle itp.). Jest tu trochę za dużo, ale dodałem go jako przepis na książkę kucharską w języku Python .