--- a/DebugClients/Python/DebugBase.py Fri Feb 17 22:10:34 2017 +0100 +++ b/DebugClients/Python/DebugBase.py Sat Feb 18 13:52:07 2017 +0100 @@ -327,20 +327,6 @@ return self.trace_dispatch if event == 'return': - if self.stop_here(frame) or frame == self.botframe: - # Ignore return events in generator except when stepping. - if self.stopframe and frame.f_code.co_flags & CO_GENERATOR: - return - # The program has finished if we have just left the first frame - if frame == self.botframe: - if self.isMainThread: - atexit._run_exitfuncs() - self._dbgClient.progTerminated(arg) - else: - self._dbgClient.threadTerminated(self.id) - - if self.quitting and not self._dbgClient.passive: - raise SystemExit return if event == 'exception': @@ -464,8 +450,13 @@ try: exec(cmd, globals, locals) + atexit._run_exitfuncs() + self._dbgClient.progTerminated(0) except SystemExit: - pass + atexit._run_exitfuncs() + excinfo = sys.exc_info() + exitcode, message = self.__extractSystemExitMessage(excinfo) + self._dbgClient.progTerminated(exitcode, message) finally: self.quitting = True sys.settrace(None) @@ -778,44 +769,10 @@ """ exctype, excval, exctb = excinfo - if exctype in [GeneratorExit, StopIteration]: + if exctype in [GeneratorExit, StopIteration, SystemExit]: # ignore these return - if exctype == SystemExit: - atexit._run_exitfuncs() - if excval is None: - exitcode = 0 - message = "" - elif isinstance(excval, basestring): - exitcode = 1 - message = excval - elif isinstance(excval, bytes): - exitcode = 1 - message = excval.decode() - elif isinstance(excval, int): - exitcode = excval - message = "" - elif isinstance(excval, SystemExit): - code = excval.code - if isinstance(code, basestring): - exitcode = 1 - message = code - elif isinstance(code, bytes): - exitcode = 1 - message = code.decode() - elif isinstance(code, int): - exitcode = code - message = "" - else: - exitcode = 1 - message = str(code) - else: - exitcode = 1 - message = str(excval) - self._dbgClient.progTerminated(exitcode, message) - return - if exctype in [SyntaxError, IndentationError]: try: # tuple could only occure on Python 2, but not always! @@ -932,6 +889,48 @@ tb = None return stack + def __extractSystemExitMessage(self, excinfo): + """ + Private method to get the SystemExit code and message. + + @param excinfo details about the SystemExit exception + @type tuple(Exception, excval object, traceback frame object) + @return SystemExit code and message + @rtype int, str + """ + exctype, excval, exctb = excinfo + if excval is None: + exitcode = 0 + message = "" + elif isinstance(excval, basestring): + exitcode = 1 + message = excval + elif isinstance(excval, bytes): + exitcode = 1 + message = excval.decode() + elif isinstance(excval, int): + exitcode = excval + message = "" + elif isinstance(excval, SystemExit): + code = excval.code + if isinstance(code, basestring): + exitcode = 1 + message = code + elif isinstance(code, bytes): + exitcode = 1 + message = code.decode() + elif isinstance(code, int): + exitcode = code + message = "" + else: + exitcode = 1 + message = str(code) + else: + exitcode = 1 + message = str(excval) + + return exitcode, message + def stop_here(self, frame): """ Public method reimplemented to filter out debugger files.