File size: 3,160 Bytes
d12bc25
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
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.framework.app" 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)