summaryrefslogtreecommitdiff
path: root/mac/arch.c
diff options
context:
space:
mode:
Diffstat (limited to 'mac/arch.c')
-rw-r--r--mac/arch.c107
1 files changed, 54 insertions, 53 deletions
diff --git a/mac/arch.c b/mac/arch.c
index d641cea8..e0d0ca2e 100644
--- a/mac/arch.c
+++ b/mac/arch.c
@@ -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;
}