diff options
Diffstat (limited to 'mac/arch.c')
-rw-r--r-- | mac/arch.c | 107 |
1 files changed, 54 insertions, 53 deletions
@@ -24,19 +24,11 @@ #include "arch.h" -#import <Foundation/Foundation.h> #include <ctype.h> #include <dirent.h> #include <errno.h> #include <fcntl.h> -#include <mach/i386/thread_status.h> -#include <mach/mach.h> -#include <mach/mach_types.h> -#include <mach/mach_vm.h> -#include <mach/task_info.h> #include <poll.h> -#include <pthread.h> -#include <servers/bootstrap.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> @@ -57,9 +49,20 @@ #include "libhfcommon/files.h" #include "libhfcommon/log.h" #include "libhfcommon/util.h" +#include "subproc.h" + +#include <mach/i386/thread_status.h> +#include <mach/mach.h> +#include <mach/mach_types.h> +#include <mach/mach_vm.h> +#include <mach/task_info.h> +#include <pthread.h> +#include <servers/bootstrap.h> + #include "mach_exc.h" #include "mach_excServer.h" -#include "subproc.h" + +#import <Foundation/Foundation.h> /* * Interface to third_party/CrashReport_*.o @@ -179,12 +182,12 @@ static void arch_generateReport(run_t* run, int termsig) { * Returns true if a process exited (so, presumably, we can delete an input * file) */ -static void arch_analyzeSignal(run_t* run, int status) { +static bool arch_analyzeSignal(run_t* run, int status) { /* * Resumed by delivery of SIGCONT */ if (WIFCONTINUED(status)) { - return; + return false; } /* @@ -192,7 +195,7 @@ static void arch_analyzeSignal(run_t* run, int status) { */ if (WIFEXITED(status)) { LOG_D("Process (pid %d) exited normally with status %d", run->pid, WEXITSTATUS(status)); - return; + return true; } /* @@ -201,14 +204,14 @@ static void arch_analyzeSignal(run_t* run, int status) { if (!WIFSIGNALED(status)) { LOG_E("Process (pid %d) exited with the following status %d, please report that as a bug", run->pid, status); - return; + return true; } int termsig = WTERMSIG(status); LOG_D("Process (pid %d) killed by signal %d '%s'", run->pid, termsig, strsignal(termsig)); if (!arch_sigs[termsig].important) { LOG_D("It's not that important signal, skipping"); - return; + return true; } /* @@ -242,7 +245,7 @@ static void arch_analyzeSignal(run_t* run, int status) { run->backtrace) != -1)) { LOG_I("Blacklisted stack hash '%" PRIx64 "', skipping", run->backtrace); ATOMIC_POST_INC(run->global->cnts.blCrashesCnt); - return; + return true; } /* If dry run mode, copy file with same name into workspace */ @@ -268,13 +271,13 @@ static void arch_analyzeSignal(run_t* run, int status) { LOG_I("Crash (dup): '%s' already exists, skipping", run->crashFileName); // Clear filename so that verifier can understand we hit a duplicate memset(run->crashFileName, 0, sizeof(run->crashFileName)); - return; + return true; } if (!files_writeBufToFile(run->crashFileName, run->dynamicFile, run->dynamicFileSz, O_CREAT | O_EXCL | O_WRONLY)) { LOG_E("Couldn't save crash as '%s'", run->crashFileName); - return; + return true; } LOG_I("Crash: saved as '%s'", run->crashFileName); @@ -284,6 +287,8 @@ static void arch_analyzeSignal(run_t* run, int status) { ATOMIC_CLEAR(run->global->cfg.dynFileIterExpire); arch_generateReport(run, termsig); + + return true; } pid_t arch_fork(run_t* run HF_ATTR_UNUSED) { @@ -357,41 +362,6 @@ void arch_prepareParent(run_t* run HF_ATTR_UNUSED) { void arch_prepareParentAfterFork(run_t* run HF_ATTR_UNUSED) { } -static bool arch_checkWait(run_t* run) { - /* All queued wait events must be tested when SIGCHLD was delivered */ - for (;;) { - int status; - /* Wait for the whole process group of run->pid */ - pid_t pid = TEMP_FAILURE_RETRY(wait4(-(run->pid), &status, WNOHANG, NULL)); - if (pid == 0) { - return false; - } - if (pid == -1 && errno == ECHILD) { - LOG_D("No more processes to track"); - return true; - } - if (pid == -1) { - PLOG_F("wait4(pid/session=%d) failed", (int)run->pid); - } - - arch_analyzeSignal(run, status); - - char statusStr[4096]; - LOG_D("pid=%d returned with status: %s", pid, - subproc_StatusToStr(status, statusStr, sizeof(statusStr))); - - if (pid == run->pid && (WIFEXITED(status) || WIFSIGNALED(status))) { - if (run->global->exe.persistent) { - if (!fuzz_isTerminating()) { - LOG_W("Persistent mode: PID %d exited with status: %s", pid, - subproc_StatusToStr(status, statusStr, sizeof(statusStr))); - } - } - return true; - } - } -} - void arch_reapChild(run_t* run) { for (;;) { if (subproc_persistentModeStateMachine(run)) { @@ -420,7 +390,38 @@ void arch_reapChild(run_t* run) { } } - if (arch_checkWait(run)) { + int status; + int ret = waitpid(run->pid, &status, WNOHANG); + if (ret == 0) { + continue; + } + if (ret == -1 && errno == EINTR) { + continue; + } + if (ret == -1 && errno == ECHILD) { + run->pid = 0; + break; + } + if (ret == -1) { + PLOG_W("waitpid(pid=%d)", run->pid); + continue; + } + if (ret != run->pid) { + continue; + } + + char strStatus[4096]; + if (run->global->exe.persistent && (WIFEXITED(status) || WIFSIGNALED(status))) { + if (!fuzz_isTerminating()) { + LOG_W("Persistent mode: PID %d exited with status: %s", ret, + subproc_StatusToStr(status, strStatus, sizeof(strStatus))); + } + } + + LOG_D("Process (pid %d) came back with status: %s", run->pid, + subproc_StatusToStr(status, strStatus, sizeof(strStatus))); + + if (arch_analyzeSignal(run, status)) { run->pid = 0; break; } |