def describe_exit_status(exitstatus, exitcodedescs=None): import warnings warnings.warn("Use ExitCode instead of describe_exit_status()", DeprecationWarning) desc = [] if os.WIFSIGNALED(exitstatus): signum = os.WTERMSIG(exitstatus) signame = signum_to_name(signum) if signame: signame = " (%s)" % signame else: signame = "" desc.append("Killed by signal %d%s" % (signum, signame)) if os.WIFEXITED(exitstatus): exitcode = os.WEXITSTATUS(exitstatus) if exitcodedescs and exitcodedescs.get(exitcode): codedesc = " (%s)" % exitcodedescs.get(exitcode) else: codedesc = '' desc.append("Exited with code %d%s" % (exitcode, codedesc)) if os.WIFSTOPPED(exitstatus): desc.append("Stopped by signal %d" % os.WSTOPSIG(exitstatus)) if os.WCOREDUMP(exitstatus): desc.append("coredumped") return desc
def wait_for_active_job(last_task=None, backgrounded=False): """ Wait for the active job to finish, to be killed by SIGINT, or to be suspended by ctrl-z. """ _clear_dead_jobs() active_task = get_next_task() # Return when there are no foreground active task if active_task is None: return last_task obj = active_task["obj"] backgrounded = False try: _, wcode = os.waitpid(obj.pid, os.WUNTRACED) except ChildProcessError: # No child processes return wait_for_active_job(last_task=active_task, backgrounded=backgrounded) if os.WIFSTOPPED(wcode): print("^Z") active_task["status"] = "stopped" backgrounded = True elif os.WIFSIGNALED(wcode): print() # get a newline because ^C will have been printed obj.signal = (os.WTERMSIG(wcode), os.WCOREDUMP(wcode)) obj.returncode = None else: obj.returncode = os.WEXITSTATUS(wcode) obj.signal = None return wait_for_active_job(last_task=active_task, backgrounded=backgrounded)
def waitpid(self): if self.pid == 0: return try: pid, status = os.waitpid(self.pid, os.WNOHANG) except OSError as exc: self.pid = 0 error('waitpid: %s', exc) return if (pid, status) != (0, 0): self.pid = 0 if os.WCOREDUMP(status): self.pid_status = ('%s process terminated with a core dump.' % self._pgm) elif os.WIFSIGNALED(status): self.pid_status = ( '%s process terminated after receiving signal %d.' % (self._pgm, os.WTERMSIG(status))) elif os.WIFEXITED(status): self.pid_status = ('%s process terminated with exit %d.' % (self._pgm, os.WEXITSTATUS(status))) else: self.pid_status = '%s process terminated.' % self._pgm
def wait_for_active_job(): """ Wait for the active job to finish, to be killed by SIGINT, or to be suspended by ctrl-z. """ _clear_dead_jobs() active_task = get_next_task() # Return when there are no foreground active task if active_task is None: _give_terminal_to(_shell_pgrp) # give terminal back to the shell return pgrp = active_task['pgrp'] obj = active_task['obj'] # give the terminal over to the fg process _give_terminal_to(pgrp) _continue(active_task) _, wcode = os.waitpid(obj.pid, os.WUNTRACED) if os.WIFSTOPPED(wcode): print() # get a newline because ^Z will have been printed active_task['status'] = "stopped" elif os.WIFSIGNALED(wcode): print() # get a newline because ^C will have been printed obj.signal = (os.WTERMSIG(wcode), os.WCOREDUMP(wcode)) obj.returncode = None else: obj.returncode = os.WEXITSTATUS(wcode) obj.signal = None return wait_for_active_job()
def processEnded(self, reason=None): """ When we are told the process ended, try to notify the other side about how the process ended using the exit-signal or exit-status requests. Also, close the channel. """ if reason is not None: err = reason.value if err.signal is not None: signame = self._getSignalName(err.signal) if getattr(os, "WCOREDUMP", None) is not None and os.WCOREDUMP( err.status): log.info("exitSignal: {signame} (core dumped)", signame=signame) coreDumped = True else: log.info("exitSignal: {}", signame=signame) coreDumped = False self.session.conn.sendRequest( self.session, b"exit-signal", common.NS(networkString(signame[3:])) + (b"\1" if coreDumped else b"\0") + common.NS(b"") + common.NS(b""), ) elif err.exitCode is not None: log.info("exitCode: {exitCode!r}", exitCode=err.exitCode) self.session.conn.sendRequest(self.session, b"exit-status", struct.pack(">L", err.exitCode)) self.session.loseConnection()
def print_exit_status(process, printer): exit_signal = None exit_code = None core_dumped = False try: wait_result = os.waitpid(process.pid, 0)[1] if os.WIFSIGNALED(wait_result): exit_signal = os.WTERMSIG(wait_result) exit_code = 128 + exit_signal elif os.WIFEXITED(wait_result): exit_code = os.WEXITSTATUS(wait_result) core_dumped = os.WCOREDUMP(wait_result) except ChildProcessError: # Must be Windows; waiting for a terminated process doesn't work (?) exit_code = process.returncode if exit_signal is not None: signal_name = signal_names.get(exit_signal, 'unknown signal') printer.print(Fore.RED + 'Terminated by %s (%i)' % (signal_name, exit_signal) + Style.RESET_ALL) exit_code = 128 + exit_signal if core_dumped: printer.print(Fore.RED + 'Core dumped' + Style.RESET_ALL) return exit_code
def waitpid(self, nohang=os.WNOHANG): """Wait on the process.""" if self.pid != 0: try: pid, status = os.waitpid(self.pid, nohang) except OSError, err: # may be called by sigchld_handler while in close() if err.errno == errno.ECHILD: return raise if (pid, status) != (0, 0): self.pid = 0 if self.sig_handler is not None: signal.signal(signal.SIGCHLD, self.sig_handler) if os.WCOREDUMP(status): self.pid_status = ( '%s process terminated with a core dump.' % self.pgm_name) elif os.WIFSIGNALED(status): self.pid_status = ( '%s process terminated after receiving signal %d.' % (self.pgm_name, os.WTERMSIG(status))) elif os.WIFEXITED(status): self.pid_status = ('%s process terminated with exit %d.' % (self.pgm_name, os.WEXITSTATUS(status))) else: self.pid_status = '%s process terminated.' % self.pgm_name self.close()
def decode_wait_status(sts): """Decode the status returned by wait() or waitpid(). Return a tuple (exitstatus, message) where exitstatus is the exit status, or -1 if the process was killed by a signal; and message is a message telling what happened. It is the caller's responsibility to display the message. """ if os.WIFEXITED(sts): es = os.WEXITSTATUS(sts) & 0xffff msg = "exit status %s" % es return es, msg elif os.WIFSIGNALED(sts): sig = os.WTERMSIG(sts) msg = "terminated by %s" % signame(sig) if hasattr(os, "WCOREDUMP"): iscore = os.WCOREDUMP(sts) else: iscore = sts & 0x80 if iscore: msg += " (core dumped)" return -1, msg else: msg = "unknown termination cause 0x%04x" % sts return -1, msg
def post_send(self): ''' This routine is called after the fuzzer transmits a test case and returns the status of the target. @rtype: Boolean @return: Return True if the target is still active, False otherwise. ''' if not self.dbg.isAlive(): exit_status = self.dbg.get_exit_status() rec_file = open(self.crash_bin, 'a') if os.WCOREDUMP(exit_status): reason = 'Segmentation fault' elif os.WIFSTOPPED(exit_status): reason = 'Stopped with signal ' + str(os.WTERMSIG(exit_status)) elif os.WIFSIGNALED(exit_status): reason = 'Terminated with signal ' + str( os.WTERMSIG(exit_status)) elif os.WIFEXITED(exit_status): reason = 'Exit with code - ' + str(os.WEXITSTATUS(exit_status)) else: reason = 'Process died for unknown reason' self.last_synopsis = '[%s] Crash : Test - %d Reason - %s\n' % ( time.strftime("%I:%M.%S"), self.test_number, reason) rec_file.write(self.last_synopsis) rec_file.close() return self.dbg.isAlive()
def processEnded(self, reason=None): """ When we are told the process ended, try to notify the other side about how the process ended using the exit-signal or exit-status requests. Also, close the channel. """ if reason is not None: err = reason.value if err.signal is not None: signame = self._getSignalName(err.signal) if (getattr(os, 'WCOREDUMP', None) is not None and os.WCOREDUMP(err.status)): log.msg('exitSignal: %s (core dumped)' % (signame, )) coreDumped = 1 else: log.msg('exitSignal: %s' % (signame, )) coreDumped = 0 self.session.conn.sendRequest( self.session, 'exit-signal', common.NS(signame[3:]) + chr(coreDumped) + common.NS('') + common.NS('')) elif err.exitCode is not None: log.msg('exitCode: %r' % (err.exitCode, )) self.session.conn.sendRequest(self.session, 'exit-status', struct.pack('>L', err.exitCode)) self.session.loseConnection()
def signal(self): """Process signal, or None.""" s = getattr(self.proc, "signal", None) if s is None: rtn = self.returncode if rtn is not None and rtn != 0: s = (-1 * rtn, rtn < 0 if xp.ON_WINDOWS else os.WCOREDUMP(rtn)) return s
def signal(self): """If the process was terminated by a signal a 2-tuple is returned containing the signal number and a boolean indicating whether a core file was produced. Otherwise None is returned.""" if os.WIFSIGNALED(self._tpty.wcode): return (os.WTERMSIG(self._tpty.wcode), os.WCOREDUMP(self._tpty.wcode)) else: return None
def run(self): """ self.exit_status = os.waitpid(self.pid, os.WNOHANG | os.WUNTRACED) while self.exit_status == (0, 0): self.exit_status = os.waitpid(self.pid, os.WNOHANG | os.WUNTRACED) """ self.spawn_target() self.finished_starting.set() if self.proc_name: gone, _ = psutil.wait_procs([self._psutil_proc]) self.exit_status = gone[0].returncode else: exit_info = os.waitpid(self.pid, 0) self.exit_status = exit_info[1] # [0] is the pid default_reason = "Process died for unknown reason" if self.exit_status is not None: if os.WCOREDUMP(self.exit_status): reason = "Segmentation fault" elif os.WIFSTOPPED(self.exit_status): reason = "Stopped with signal " + str( os.WTERMSIG(self.exit_status)) elif os.WIFSIGNALED(self.exit_status): reason = "Terminated with signal " + str( os.WTERMSIG(self.exit_status)) elif os.WIFEXITED(self.exit_status): reason = "Exit with code - " + str( os.WEXITSTATUS(self.exit_status)) else: reason = default_reason else: reason = default_reason outdata = None errdata = None try: if self._process is not None: outdata, errdata = self._process.communicate( timeout=POPEN_COMMUNICATE_TIMEOUT_FOR_ALREADY_DEAD_TASK) except subprocess.TimeoutExpired: self.process_monitor.log( msg="Expired waiting for process {0} to terminate".format( self._process.pid), level=1) msg = "[{0}] Crash. Exit code: {1}. Reason - {2}\n".format( time.strftime("%I:%M.%S"), self.exit_status if self.exit_status is not None else "<unknown>", reason) if errdata is not None: msg += "STDERR:\n{0}\n".format(errdata.decode("ascii")) if outdata is not None: msg += "STDOUT:\n{0}\n".format(outdata.decode("ascii")) self.process_monitor.last_synopsis = msg
def waitstatus_description(st): if os.WIFEXITED(st): es = os.WEXITSTATUS(st) if es: return "exited with nonzero status %i" % es else: return "exited" elif os.WIFSIGNALED(st): s = "died due to signal %i" % os.WTERMSIG(st) if os.WCOREDUMP(st): s += " (core dumped)" return s else: return "failed with unexpected wait status %i" % st
def parse_waitpid_result(status): l = [] if os.WIFEXITED(status): l.append("WIFEXITED({0})".format(os.WEXITSTATUS(status))) if os.WIFSIGNALED(status): l.append("WIFSIGNALED({0})".format(os.WTERMSIG(status))) if os.WCOREDUMP(status): l.append("WCOREDUMP") if os.WIFSTOPPED(status): l.append("WIFSTOPPED({0})".format(os.WSTOPSIG(status))) return '|'.join(l)
def status_decode(status: int) -> Tuple[bool, str, TProcessItems]: ''' Decode status ''' if os.WIFSIGNALED(status): return True, 'Signaled', \ (('Signal', os.WTERMSIG(status)), ('Coredump', os.WCOREDUMP(status))) if os.WIFEXITED(status): return True, 'Exited', (('Status', os.WEXITSTATUS(status)),) if os.WIFCONTINUED(status): return False, 'Continued', None if os.WIFSTOPPED(status): return False, 'Stopped', (('Signal', os.WSTOPSIG(status)),) raise RuntimeError('Status unknown')
def exit_status_string(self): """Return a string representation of the command's exit status.""" statusString = None if self.__status: exitStatus = os.WEXITSTATUS(self.__status) exitSignal = os.WIFSIGNALED(self.__status) coreDump = os.WCOREDUMP(self.__status) statusString = "exit code: %s | signal: %s | core %s" % \ (exitStatus, exitSignal, coreDump) return (statusString)
def status_msg(status): """Given 'status', which is a process status in the form reported by waitpid(2) and returned by process_status(), returns a string describing how the process terminated.""" if os.WIFEXITED(status): s = "exit status %d" % os.WEXITSTATUS(status) elif os.WIFSIGNALED(status): s = _signal_status_msg("killed", os.WTERMSIG(status)) elif os.WIFSTOPPED(status): s = _signal_status_msg("stopped", os.WSTOPSIG(status)) else: s = "terminated abnormally (%x)" % status if os.WCOREDUMP(status): s += ", core dumped" return s
def statusfmt(status): """ Format an exit status as text. """ if status == 0: msg = 'exited ok' elif os.WIFSIGNALED(status): msg = 'died on ' + signame(os.WTERMSIG(status)) elif os.WIFEXITED(status) and os.WEXITSTATUS(status) > 0: msg = 'exited ' + str(os.WEXITSTATUS(status)) else: msg = 'unknown exit code 0x%04x' % (status, ) if os.WCOREDUMP(status): msg += ' (core dumped)' return msg
def wait_for_active_job(signal_to_send=None): """ Wait for the active job to finish, to be killed by SIGINT, or to be suspended by ctrl-z. """ _clear_dead_jobs() act = builtins.__xonsh_active_job__ if act is None: return job = builtins.__xonsh_all_jobs__[act] obj = job['obj'] if job['bg'] and job['status'] == 'running': return pgrp = job['pgrp'] # give the terminal over to the fg process _give_terminal_to(pgrp) # if necessary, send the specified signal to this process # (this hook was added because vim, emacs, etc, seem to need to have # the terminal when they receive SIGCONT from the "fg" command) if signal_to_send is not None: if signal_to_send == signal.SIGCONT: job['status'] = 'running' os.kill(obj.pid, signal_to_send) if job['bg']: _give_terminal_to(_shell_pgrp) return _, wcode = os.waitpid(obj.pid, os.WUNTRACED) if os.WIFSTOPPED(wcode): job['bg'] = True job['status'] = 'stopped' print() # get a newline because ^Z will have been printed print_one_job(act) elif os.WIFSIGNALED(wcode): print() # get a newline because ^C will have been printed obj.signal = (os.WTERMSIG(wcode), os.WCOREDUMP(wcode)) obj.returncode = None else: obj.returncode = os.WEXITSTATUS(wcode) obj.signal = None if obj.poll() is not None: builtins.__xonsh_active_job__ = None _give_terminal_to(_shell_pgrp) # give terminal back to the shell
def get_sigchlds(): try: while True: (pid, status) = os.waitpid(-1, os.WUNTRACED | os.WCONTINUED | os.WNOHANG) if pid == 0: return res = { "ssi_signo": 0, # Signal number "ssi_errno": 0, # Error number (unused) "ssi_code": 0, # Signal code "ssi_pid": 0, # PID of sender "ssi_uid": 0, # Real UID of sender "ssi_fd": 0, # File descriptor (SIGIO) "ssi_tid": 0, # Kernel timer ID (POSIX timers) "ssi_band": 0, # Band event (SIGIO) "ssi_overrun": 0, # POSIX timer overrun count "ssi_trapno": 0, # Trap number that caused signal "ssi_status": 0, # Exit status or signal (SIGCHLD) "ssi_int": 0, # Integer sent by sigqueue(3) "ssi_ptr": 0, # Pointer sent by sigqueue(3) "ssi_utime": 0, # User CPU time consumed (SIGCHLD) "ssi_stime": 0, # System CPU time consumed (SIGCHLD) "ssi_addr": 0, # Address that generated signal (for hardware-generated signals) } res["ssi_signo"] = signal.SIGCHLD res["ssi_pid"] = pid if os.WIFEXITED(status): res["ssi_code"] = CLD_EXITED res["ssi_status"] = os.WEXITSTATUS(status) elif os.WCOREDUMP(status): res["ssi_code"] = CLD_DUMPED res["ssi_status"] = os.WTERMSIG(status) elif os.WIFCONTINUED(status): res["ssi_code"] = CLD_CONTINUED elif os.WIFSTOPPED(status): res["ssi_code"] = CLD_STOPPED res["ssi_status"] = os.WSTOPSIG(status) elif os.WIFSIGNALED(status): res["ssi_code"] = CLD_KILLED res["ssi_status"] = os.WTERMSIG(status) yield res except OSError: return
def __sig_child_handler(self, signum, frame): # Our child exits with sig 9 when all is good... so map that to 0 try: status = None sig = None core = False self.logger.debug("Running children: %s" % self.executor_pids) self.logger.debug("Got signal %s" % signum) pid, ret = os.wait() msg = "Child %s: wait returned code %s which means:" % (pid, ret) if os.WIFSIGNALED(ret): sig = os.WTERMSIG(ret) msg += " signalled %s" % sig if os.WIFEXITED(ret): status = os.WEXITSTATUS(ret) msg += " exited %s" % status if os.WIFSTOPPED(ret): msg += " stopped %s" % os.WSTOPSIG(ret) if os.WCOREDUMP(ret): core = True msg += " core dumped" if os.WIFCONTINUED(ret): msg += " contunied" self.logger.debug(msg) if pid in self.executor_pids: self.executor_pids.remove(pid) self.executor_rets.append((status, sig, core)) else: self.logger.error("Pid %s is not a child" % pid) ret = 0 if len(self.executor_pids) == 0: self.logger.trace("Statuses of all executors: %s" % self.executor_rets) for st, sg, co in self.executor_rets: if st is not None and st != 0: ret = st if co: ret = 1 self.logger.debug("Exit with code %s" % ret) sys.exit(ret) except Exception, ex: self.logger.error("Error waiting for child process: %s" % ex)
def _waitChildToDieAndScheduleNew(self, signal=None, frame=None): """STEP 2 (parent): Child told us via SIGCHLD that we can spawn new child """ if self.isChild(): # Ignore grandchildren return try: # Acknowledge dead child pid, exit_status = os.wait() if pid != self.child_pid: # Ignore unknown children return exit_flags = [] if os.WCOREDUMP(exit_status): exit_flags.append("core dumped") if os.WIFSIGNALED(exit_status): code = os.WTERMSIG(exit_status) exit_flags.append("terminated by signal %d" % code) if os.WIFEXITED(exit_status): code = os.WEXITSTATUS(exit_status) exit_flags.append("exited with code %d" % code) if exit_status == 0: print(WAIT("Fork loop terminated child process %d" % pid)) elif exit_flags: print( ERROR("Forked child process %d %s" % (pid, ", ".join(exit_flags)))) else: print( ERROR("Forked child process %d exited with code %s" % (pid, exit_status))) except OSError: # OSError: [Errno 10] No child processes pass # Schedule new self._scheduleFork()
def status_code(status): ''' Decode child process exit code. status is the exist status indication from os.waitpid(pid,0)[1] ''' if os.WIFSIGNALED(status): # process exited due to a signal # get the signal which caused the process to exit: make it negative to # distinguish from exit(2) call return -os.WTERMSIG(status) elif os.WIFEXITED(status): # process exited using exit(2) system call # get the integer parameter to exit(2) call return os.WEXITSTATUS(status) elif os.WIFSTOPPED(status) or os.WIFCONTINUED(status): raise RuntimeError("Child stopped or continued?") elif os.WCOREDUMP(status): raise RuntimeError("Child core dump!") else: raise RuntimeError("Unknown child return status!")
def _monitor_daemon(daemon_pid): # XXX should log daemon's stderr output at startup time # XXX should use setproctitle module if available last_restart = None while True: retval, status = _waitpid(daemon_pid, 0) if retval < 0: sys.stderr.write("waitpid failed\n") sys.exit(1) elif retval == daemon_pid: status_msg = ("pid %d died, %s" % (daemon_pid, ovs.process.status_msg(status))) if _should_restart(status): if sys.platform != 'win32' and os.WCOREDUMP(status): # Disable further core dumps to save disk space. try: resource.setrlimit(resource.RLIMIT_CORE, (0, 0)) except resource.error: vlog.warn("failed to disable core dumps") # Throttle restarts to no more than once every 10 seconds. if (last_restart is not None and ovs.timeval.msec() < last_restart + 10000): vlog.warn("%s, waiting until 10 seconds since last " "restart" % status_msg) while True: now = ovs.timeval.msec() wakeup = last_restart + 10000 if now > wakeup: break sys.stdout.write("sleep %f\n" % ((wakeup - now) / 1000.0)) time.sleep((wakeup - now) / 1000.0) last_restart = ovs.timeval.msec() vlog.err("%s, restarting" % status_msg) daemon_pid = _fork_and_wait_for_startup() if not daemon_pid: break else: vlog.info("%s, exiting" % status_msg) sys.exit(0)
def post_send(self): """ This routine is called after the fuzzer transmits a test case and returns the status of the target. @rtype: bool @return: Return True if the target is still active, False otherwise. """ # TODO: Fix this ruby-coap-server hack. # Apparently the rails (or rack?) framework takes a while to die, maybe the app dies but the framework is still logging or cleaning up something. if 'david' in self.start_commands[0]: time.sleep(0.4) if not self.dbg.is_alive(): exit_status = self.dbg.get_exit_status() rec_file = open(self.crash_bin, 'a') if os.WCOREDUMP(exit_status): reason = 'Segmentation fault' elif os.WIFSTOPPED(exit_status): reason = 'Stopped with signal ' + str(os.WTERMSIG(exit_status)) elif os.WIFSIGNALED(exit_status): reason = 'Terminated with signal ' + str(os.WTERMSIG(exit_status)) elif os.WIFEXITED(exit_status): reason = 'Exit with code - ' + str(os.WEXITSTATUS(exit_status)) else: reason = 'Process died for unknown reason' self.last_synopsis = '[%s] Crash : Test - %d Reason - %s\n' % ( time.strftime("%I:%M.%S"), self.test_number, reason ) rec_file.write(self.last_synopsis) rec_file.close() if self.coredump_dir is not None: dest = os.path.join( self.coredump_dir, "TC_%s.dump" % str(self.test_number) ) src = self._get_coredump_path() if src is not None: self.log("moving core dump %s -> %s" % (src, dest)) os.rename(src, dest) return self.dbg.is_alive()
def convertReturnCodeToExitStatusMessage(rc): exitstatusmessage = "" if not isinstance(rc, int): exitstatusmessage = "None" elif os.WIFSIGNALED(rc): signum = os.WTERMSIG(rc) exitstatusmessage = "signal %d %s" % (signum, getSignalName(signum)) elif os.WIFEXITED(rc): exitstatus = os.WEXITSTATUS(rc) if exitstatus == 0: exitstatusmessage = 'NORMAL' else: exitstatusmessage = 'ABNORMAL ' + str(exitstatus) if isinstance(rc, int) and os.WCOREDUMP(rc): exitstatusmessage += " dumped core" return exitstatusmessage.strip()
def wait(self): """Call os.waitpid to status of dead processes. """ while True: try: pid, status = os.waitpid(-1, os.WNOHANG) except OSError: # there are no child processes break # this is how waitpid + WNOHANG reports things are running # but not yet dead if pid == 0: break signum = 0 core_dump = False exit_status = None if os.WIFEXITED(status): exit_status = os.WEXITSTATUS(status) elif os.WIFSIGNALED(status): signum = os.WTERMSIG(status) if os.WCOREDUMP(status): core_dump = True exit_status = 128 + signum if exit_status is None: _logger.info("pid %s died but had no status", pid) break if signum: _logger.info( "pid %s died with status %s and signal %s; coredump=%s", pid, exit_status, signum, core_dump) else: _logger.info("pid %s died with status %s", pid, exit_status) for each in self.children.itervalues(): if each.pid == pid: _logger.info("task %s: dead pid %s matches", each.label, pid) each.exit_status = exit_status each.core_dump = core_dump each.signum = signum
def post_send(self): """ This routine is called after the fuzzer transmits a test case and returns the status of the target. @rtype: bool @return: Return True if the target is still active, False otherwise. """ if not self.dbg.is_alive(): exit_status = self.dbg.get_exit_status() rec_file = open(self.crash_bin, 'a') if os.WCOREDUMP(exit_status): reason = 'Segmentation fault' elif os.WIFSTOPPED(exit_status): reason = 'Stopped with signal ' + str(os.WTERMSIG(exit_status)) elif os.WIFSIGNALED(exit_status): reason = 'Terminated with signal ' + str(os.WTERMSIG(exit_status)) elif os.WIFEXITED(exit_status): reason = 'Exit with code - ' + str(os.WEXITSTATUS(exit_status)) else: reason = 'Process died for unknown reason' self.last_synopsis = '[%s] Crash : Test - %d Reason - %s\n' % ( time.strftime("%I:%M.%S"), self.test_number, reason ) rec_file.write(self.last_synopsis) rec_file.close() if self.coredump_dir is not None: dest = os.path.join(self.coredump_dir, str(self.test_number)) src = self._get_coredump_path() if src is not None: self.log("moving core dump %s -> %s" % (src, dest)) os.rename(src, dest) return self.dbg.is_alive()
def __init__(self, exitcode, message=''): """exitcode is the exit status of a command, message is a description which will be prepended in the str() of this.""" self.exitcode = exitcode self.message = message self.exitstatus = None self.exited = None self.killedbysignalnum = None self.killedbysignal = None self.stoppedbysignalnum = None self.stoppedbysignal = None self.coredumped = os.WCOREDUMP(exitcode) if os.WIFEXITED(exitcode): self.exited = True self.exitstatus = os.WEXITSTATUS(exitcode) if os.WIFSIGNALED(exitcode): self.killedbysignalnum = os.WTERMSIG(exitcode) self.killedbysignal = signum_to_name(self.killedbysignalnum) if os.WIFSTOPPED(exitcode): self.stoppedbysignalnum = os.WSTOPSIG(self.exitcode) self.stoppedbysignal = signum_to_name(self.stoppedbysignalnum)