Run the debugger.
(self, *args)
| 115 | self.nesting_level = 0 |
| 116 | |
| 117 | def run(self, *args): |
| 118 | """Run the debugger.""" |
| 119 | # Deal with the scenario where we've already got a program running |
| 120 | # in the debugger and we want to start another. If that is the case, |
| 121 | # our second 'run' was invoked from an event dispatched not from |
| 122 | # the main event loop, but from the nested event loop in 'interaction' |
| 123 | # below. So our stack looks something like this: |
| 124 | # outer main event loop |
| 125 | # run() |
| 126 | # <running program with traces> |
| 127 | # callback to debugger's interaction() |
| 128 | # nested event loop |
| 129 | # run() for second command |
| 130 | # |
| 131 | # This kind of nesting of event loops causes all kinds of problems |
| 132 | # (see e.g. issue #24455) especially when dealing with running as a |
| 133 | # subprocess, where there's all kinds of extra stuff happening in |
| 134 | # there - insert a traceback.print_stack() to check it out. |
| 135 | # |
| 136 | # By this point, we've already called restart_subprocess() in |
| 137 | # ScriptBinding. However, we also need to unwind the stack back to |
| 138 | # that outer event loop. To accomplish this, we: |
| 139 | # - return immediately from the nested run() |
| 140 | # - abort_loop ensures the nested event loop will terminate |
| 141 | # - the debugger's interaction routine completes normally |
| 142 | # - the restart_subprocess() will have taken care of stopping |
| 143 | # the running program, which will also let the outer run complete |
| 144 | # |
| 145 | # That leaves us back at the outer main event loop, at which point our |
| 146 | # after event can fire, and we'll come back to this routine with a |
| 147 | # clean stack. |
| 148 | if self.nesting_level > 0: |
| 149 | self.abort_loop() |
| 150 | self.root.after(100, lambda: self.run(*args)) |
| 151 | return |
| 152 | try: |
| 153 | self.interacting = True |
| 154 | return self.idb.run(*args) |
| 155 | finally: |
| 156 | self.interacting = False |
| 157 | |
| 158 | def close(self, event=None): |
| 159 | """Close the debugger and window.""" |