114 lines
2.7 KiB
Python
114 lines
2.7 KiB
Python
|
import sys
|
||
|
|
||
|
# Some cruft to deal with the Pythonwin GUI booting up from a non GUI app.
|
||
|
def _MakeDebuggerGUI():
|
||
|
app.InitInstance()
|
||
|
|
||
|
isInprocApp = -1
|
||
|
def _CheckNeedGUI():
|
||
|
global isInprocApp
|
||
|
if isInprocApp==-1:
|
||
|
import win32ui
|
||
|
isInprocApp = win32ui.GetApp().IsInproc()
|
||
|
if isInprocApp:
|
||
|
# MAY Need it - may already have one
|
||
|
need = "pywin.debugger.dbgpyapp" not in sys.modules
|
||
|
else:
|
||
|
need = 0
|
||
|
if need:
|
||
|
import pywin.framework.app
|
||
|
from . import dbgpyapp
|
||
|
pywin.framework.app.CreateDefaultGUI(dbgpyapp.DebuggerPythonApp)
|
||
|
|
||
|
else:
|
||
|
# Check we have the appropriate editor
|
||
|
# No longer necessary!
|
||
|
pass
|
||
|
return need
|
||
|
|
||
|
# Inject some methods in the top level name-space.
|
||
|
currentDebugger = None # Wipe out any old one on reload.
|
||
|
|
||
|
def _GetCurrentDebugger():
|
||
|
global currentDebugger
|
||
|
if currentDebugger is None:
|
||
|
_CheckNeedGUI()
|
||
|
from . import debugger
|
||
|
currentDebugger = debugger.Debugger()
|
||
|
return currentDebugger
|
||
|
|
||
|
def GetDebugger():
|
||
|
# An error here is not nice - as we are probably trying to
|
||
|
# break into the debugger on a Python error, any
|
||
|
# error raised by this is usually silent, and causes
|
||
|
# big problems later!
|
||
|
try:
|
||
|
rc = _GetCurrentDebugger()
|
||
|
rc.GUICheckInit()
|
||
|
return rc
|
||
|
except:
|
||
|
print("Could not create the debugger!")
|
||
|
import traceback
|
||
|
traceback.print_exc()
|
||
|
return None
|
||
|
|
||
|
def close():
|
||
|
if currentDebugger is not None:
|
||
|
currentDebugger.close()
|
||
|
|
||
|
def run(cmd,globals=None, locals=None, start_stepping = 1):
|
||
|
_GetCurrentDebugger().run(cmd, globals,locals, start_stepping)
|
||
|
|
||
|
def runeval(expression, globals=None, locals=None):
|
||
|
return _GetCurrentDebugger().runeval(expression, globals, locals)
|
||
|
|
||
|
def runcall(*args):
|
||
|
return _GetCurrentDebugger().runcall(*args)
|
||
|
|
||
|
def set_trace():
|
||
|
import sys
|
||
|
d = _GetCurrentDebugger()
|
||
|
|
||
|
if d.frameShutdown: return # App closing
|
||
|
|
||
|
if d.stopframe != d.botframe:
|
||
|
# If im not "running"
|
||
|
return
|
||
|
|
||
|
sys.settrace(None) # May be hooked
|
||
|
d.reset()
|
||
|
d.set_trace()
|
||
|
|
||
|
# "brk" is an alias for "set_trace" ("break" is a reserved word :-(
|
||
|
brk = set_trace
|
||
|
|
||
|
# Post-Mortem interface
|
||
|
|
||
|
def post_mortem(t=None):
|
||
|
if t is None:
|
||
|
t = sys.exc_info()[2] # Will be valid if we are called from an except handler.
|
||
|
if t is None:
|
||
|
try:
|
||
|
t = sys.last_traceback
|
||
|
except AttributeError:
|
||
|
print("No traceback can be found from which to perform post-mortem debugging!")
|
||
|
print("No debugging can continue")
|
||
|
return
|
||
|
p = _GetCurrentDebugger()
|
||
|
if p.frameShutdown: return # App closing
|
||
|
# No idea why I need to settrace to None - it should have been reset by now?
|
||
|
sys.settrace(None)
|
||
|
p.reset()
|
||
|
while t.tb_next != None: t = t.tb_next
|
||
|
p.bAtPostMortem = 1
|
||
|
p.prep_run(None)
|
||
|
try:
|
||
|
p.interaction(t.tb_frame, t)
|
||
|
finally:
|
||
|
t = None
|
||
|
p.bAtPostMortem = 0
|
||
|
p.done_run()
|
||
|
|
||
|
def pm(t=None):
|
||
|
post_mortem(t)
|