def __exit__(self, exc_type, exc_val, exc_tb): log.info("Ending {0}.", self) if self.timeline.is_frozen: self.timeline.unfreeze() # Only wait for exit if there was no exception in the test - if there was one, # the debuggee might still be waiting for further requests. if exc_type is None: # If expected_exit_code is set to None, the debuggee is not expected to # exit after this Session is closed (e.g. because another Session will # attach to it later on). if self.expected_exit_code is not None: self.wait_for_exit() else: # Log the error, in case another one happens during shutdown. log.exception(exc_info=(exc_type, exc_val, exc_tb)) if exc_type is None: self.disconnect() self.timeline.close() else: # If there was an exception, don't try to send any more messages to avoid # spamming log with irrelevant entries - just close the channel and kill # all the processes immediately. Don't close or finalize the timeline, # either, since it'll likely have unobserved events in it. if self.adapter is not None: log.info("Killing {0}.", self.adapter_id) try: self.adapter.kill() except Exception: pass if self.debuggee is not None: log.info("Killing {0}.", self.debuggee_id) try: self.debuggee.kill() except Exception: pass self.disconnect(force=True) if self.adapter_endpoints is not None and self.expected_exit_code is not None: log.info("Waiting for {0} to close listener ports ...", self.adapter_id) while self.adapter_endpoints.check(): time.sleep(0.1) if self.adapter is not None: log.info( "Waiting for {0} with PID={1} to exit.", self.adapter_id, self.adapter.pid, ) self.adapter.wait() watchdog.unregister_spawn(self.adapter.pid, self.adapter_id) self.adapter = None if self.backchannel is not None: self.backchannel.close() self.backchannel = None
def wait_for_exit(self): if self.debuggee is not None: log.info("Waiting for {0} to exit ...", self.debuggee_id) try: self.debuggee.wait() except Exception: pass finally: watchdog.unregister_spawn(self.debuggee.pid, self.debuggee_id) self.wait_for_terminated() # FIXME: "exited" event is not properly reported in attach scenarios at the # moment, so the exit code is only checked if it's present. if self.debuggee is not None and self.exit_code is not None: assert self.debuggee.returncode == self.exit_code return self.exit_code
def wait_for_exit(self): if self.debuggee is not None: try: self.debuggee.wait() except Exception: pass finally: watchdog.unregister_spawn(self.debuggee.pid, self.debuggee_id) self.timeline.wait_until_realized(timeline.Event("terminated")) # FIXME: "exited" event is not properly reported in attach scenarios at the # moment, so the exit code is only checked if it's present. if self.start_request.command == "launch": assert self.exit_code is not None if self.debuggee is not None and self.exit_code is not None: assert self.debuggee.returncode == self.exit_code return self.exit_code