diff -r 25115adf9758 -r 85dfb7886fb9 DebugClients/Python3/DebugBase.py --- a/DebugClients/Python3/DebugBase.py Mon Aug 08 22:30:48 2016 +0200 +++ b/DebugClients/Python3/DebugBase.py Mon Aug 08 22:38:07 2016 +0200 @@ -72,6 +72,7 @@ self._dbgClient = dbgClient self._mainThread = True + self.quitting = 0 self.tracePythonLibs(0) @@ -87,6 +88,11 @@ # frame that we are stepping in, can be different than currentFrame self.stepFrame = None + self.botframe = None + self.stopframe = None + self.returnframe = None + self.stop_everywhere = False + # provide a hook to perform a hard breakpoint # Use it like this: # if hasattr(sys, 'breakpoint): sys.breakpoint() @@ -293,10 +299,12 @@ return if event == 'call': - if self.botframe is None: - # First call of dispatch since reset() - # (CT) Note that this may also be None! + if self.botframe is None and frame.f_lineno > 1: self.botframe = frame.f_back + frame.f_trace = self.trace_dispatch + self._dbgClient.mainFrame = frame + + self.user_line(frame) return self.trace_dispatch if not (self.stop_here(frame) or @@ -307,7 +315,7 @@ return self.trace_dispatch if event == 'return': - if self.stop_here(frame) or frame == self.returnframe: + if self.stop_here(frame): # Ignore return events in generator except when stepping. if self.stopframe and frame.f_code.co_flags & CO_GENERATOR: return @@ -316,10 +324,7 @@ self._mainThread: atexit._run_exitfuncs() self._dbgClient.progTerminated(arg) - elif frame is not self.stepFrame: - self.stepFrame = None - self.user_line(frame) - + if self.quitting and not self._dbgClient.passive: raise SystemExit return @@ -407,22 +412,42 @@ self.quitting = 1 sys.settrace(None) + def _set_stopinfo(self, stopframe, returnframe): + """ + Protected method to update the frame pointers. + + @param stopframe the frame object where to stop + @type frame object + @param returnframe the frame object where to stop on a function return + @type frame object + """ + self.stopframe = stopframe + self.returnframe = returnframe + self.stop_everywhere = False + def set_continue(self, special): """ - Public method reimplemented from bdb.py to always get informed of - exceptions. + Public method to stop only on next breakpoint. @param special flag indicating a special continue operation + @type bool """ - # Modified version of the one found in bdb.py # Here we only set a new stop frame if it is a normal continue. if not special: self._set_stopinfo(self.botframe, None) + # Disable tracing if not started in debug mode if not self._dbgClient.debugging: sys.settrace(None) sys.setprofile(None) + def set_step(self): + """ + Public method to stop after one line of code. + """ + self._set_stopinfo(None, None) + self.stop_everywhere = True + def set_quit(self): """ Public method to quit. @@ -832,12 +857,17 @@ debugger that are called from the application being debugged. @param frame the frame object + @type frame object @return flag indicating whether the debugger should stop here + @rtype bool """ if self.__skipFrame(frame): return False - return bdb.Bdb.stop_here(self, frame) + return (self.stop_everywhere or + frame is self.stopframe or + frame is self.returnframe or + frame is self.botframe) def tracePythonLibs(self, enable): """