summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Swiecki <robert@swiecki.net>2019-02-15 01:56:55 +0100
committerRobert Swiecki <robert@swiecki.net>2019-02-15 01:56:55 +0100
commit66fc573be82884d7c274362ede1c97909e197c7b (patch)
tree133cc5dbe77cee275f29aac79ae326c1fbefdf4b
parent387b79af93e06a8e85597a99209735e22f0aa02e (diff)
downloadhonggfuzz-66fc573be82884d7c274362ede1c97909e197c7b.tar.gz
posix: check wait events in a loop
-rw-r--r--honggfuzz.c10
-rw-r--r--posix/arch.c84
2 files changed, 54 insertions, 40 deletions
diff --git a/honggfuzz.c b/honggfuzz.c
index 4ecf345c..eb8eaa47 100644
--- a/honggfuzz.c
+++ b/honggfuzz.c
@@ -197,7 +197,7 @@ static void printSummary(honggfuzz_t* hfuzz) {
static void pingThreads(honggfuzz_t* hfuzz) {
for (size_t i = 0; i < hfuzz->threads.threadsMax; i++) {
- if (pthread_kill(hfuzz->threads.threads[i], SIGUSR1) != 0) {
+ if (pthread_kill(hfuzz->threads.threads[i], SIGUSR1) != 0 && errno != EINTR) {
PLOG_W("pthread_kill(thread=%zu, SIGUSR1)", i);
}
}
@@ -215,13 +215,15 @@ static void* signalThread(void* arg) {
for (;;) {
int sig;
- if (sigwait(&ss, &sig) != 0) {
+ if (sigwait(&ss, &sig) != 0 && errno != EINTR) {
PLOG_F("sigwait(SIGCHLD)");
}
if (fuzz_isTerminating()) {
break;
}
- pingThreads(hfuzz);
+ if (sig == SIGCHLD) {
+ pingThreads(hfuzz);
+ }
}
return NULL;
@@ -321,11 +323,11 @@ int main(int argc, char** argv) {
fuzz_setTerminating();
- /* Ping threads one last time */
void* retval;
if (pthread_join(sigthread, &retval) != 0) {
PLOG_W("Couldn't stop the signal thread");
}
+ /* Ping threads one last time */
pingThreads(&hfuzz);
fuzz_threadsStop(&hfuzz);
diff --git a/posix/arch.c b/posix/arch.c
index 2aafac29..cdc14293 100644
--- a/posix/arch.c
+++ b/posix/arch.c
@@ -80,12 +80,12 @@ struct {
* Returns true if a process exited (so, presumably, we can delete an input
* file)
*/
-static bool arch_analyzeSignal(run_t* run, int status) {
+static void arch_analyzeSignal(run_t* run, int status) {
/*
* Resumed by delivery of SIGCONT
*/
if (WIFCONTINUED(status)) {
- return false;
+ return;
}
/*
@@ -93,7 +93,7 @@ static bool 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 true;
+ return;
}
/*
@@ -102,14 +102,14 @@ static bool 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 false;
+ return;
}
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 true;
+ return;
}
char localtmstr[PATH_MAX];
@@ -137,8 +137,6 @@ static bool arch_analyzeSignal(run_t* run, int status) {
newname, run->dynamicFile, run->dynamicFileSz, O_CREAT | O_EXCL | O_WRONLY) == false) {
LOG_E("Couldn't save crash to '%s'", run->crashFileName);
}
-
- return true;
}
pid_t arch_fork(run_t* fuzzer HF_ATTR_UNUSED) {
@@ -186,6 +184,48 @@ void arch_prepareParent(run_t* fuzzer HF_ATTR_UNUSED) {
void arch_prepareParentAfterFork(run_t* fuzzer HF_ATTR_UNUSED) {
}
+static bool arch_checkWait(run_t* run) {
+ /* All queued wait events must be tested when SIGCHLD was delivered */
+ for (;;) {
+ int status;
+ int wflags = WNOHANG;
+#if defined(__WNOTHREAD)
+ wflags |= __WNOTHREAD;
+#endif /* defined(__WNOTHREAD) */
+#if defined(__WALL)
+ wflags |= __WALL;
+#endif /* defined(__WALL) */
+
+ pid_t pid = TEMP_FAILURE_RETRY(waitpid(run->pid, &status, wflags));
+ if (pid == 0) {
+ return false;
+ }
+ if (pid == -1 && errno == ECHILD) {
+ LOG_D("No more processes to track");
+ return true;
+ }
+ if (pid == -1) {
+ PLOG_F("waitpid() failed");
+ }
+
+ char statusStr[4096];
+ LOG_D("pid=%d returned with status: %s", pid,
+ subproc_StatusToStr(status, statusStr, sizeof(statusStr)));
+
+ arch_analyzeSignal(run, status);
+
+ 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", (int)run->pid,
+ subproc_StatusToStr(status, statusStr, sizeof(statusStr)));
+ }
+ }
+ return true;
+ }
+ }
+}
+
void arch_reapChild(run_t* run) {
for (;;) {
if (subproc_persistentModeStateMachine(run)) {
@@ -216,35 +256,7 @@ void arch_reapChild(run_t* run) {
}
}
- int status;
- int ret = waitpid(run->pid, &status, WNOHANG);
- if (ret == 0) {
- continue;
- }
- if (ret == -1 && errno == EINTR) {
- continue;
- }
- if (ret == -1) {
- PLOG_W("waitpid(pid=%d)", run->pid);
- continue;
- }
- if (ret != run->pid) {
- continue;
- }
-
- char strStatus[4096];
- if (run->global->exe.persistent && ret == run->pid &&
- (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)) {
+ if (arch_checkWait(run)) {
run->pid = 0;
break;
}