aboutsummaryrefslogtreecommitdiff
path: root/tests/qtest/fuzz
diff options
context:
space:
mode:
authorAlexander Bulekov <alxndr@bu.edu>2021-03-10 01:12:36 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2021-03-16 14:19:54 -0400
commitd0614b8e7a365e64ebf2ed068754787fae34d501 (patch)
tree8bb7d6b2144d90c3602b3200bf2c9edb1cb29b0c /tests/qtest/fuzz
parente8a2a62106d219016f8372c3888bbf555006243b (diff)
downloadqemu-d0614b8e7a365e64ebf2ed068754787fae34d501.zip
qemu-d0614b8e7a365e64ebf2ed068754787fae34d501.tar.gz
qemu-d0614b8e7a365e64ebf2ed068754787fae34d501.tar.bz2
fuzz: don't leave orphan llvm-symbolizers around
I noticed that with a sufficiently small timeout, the fuzzer fork-server sometimes locks up. On closer inspection, the issue appeared to be caused by entering our SIGALRM handler, while libfuzzer is in it's crash handlers. Because libfuzzer relies on pipe communication with an external child process to print out stack-traces, we shouldn't exit early, and leave an orphan child. Check for children in the SIGALRM handler to avoid this issue. Signed-off-by: Alexander Bulekov <alxndr@bu.edu> Acked-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'tests/qtest/fuzz')
-rw-r--r--tests/qtest/fuzz/generic_fuzz.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/tests/qtest/fuzz/generic_fuzz.c b/tests/qtest/fuzz/generic_fuzz.c
index ee8c17a..387ae20 100644
--- a/tests/qtest/fuzz/generic_fuzz.c
+++ b/tests/qtest/fuzz/generic_fuzz.c
@@ -583,6 +583,21 @@ static void handle_timeout(int sig)
fprintf(stderr, "[Timeout]\n");
fflush(stderr);
}
+
+ /*
+ * If there is a crash, libfuzzer/ASAN forks a child to run an
+ * "llvm-symbolizer" process for printing out a pretty stacktrace. It
+ * communicates with this child using a pipe. If we timeout+Exit, while
+ * libfuzzer is still communicating with the llvm-symbolizer child, we will
+ * be left with an orphan llvm-symbolizer process. Sometimes, this appears
+ * to lead to a deadlock in the forkserver. Use waitpid to check if there
+ * are any waitable children. If so, exit out of the signal-handler, and
+ * let libfuzzer finish communicating with the child, and exit, on its own.
+ */
+ if (waitpid(-1, NULL, WNOHANG) == 0) {
+ return;
+ }
+
_Exit(0);
}