llvm_nvme_fuzz: add exit handler

When the LLVM fuzzer is done, it calls exit(0)
explicitly.  This triggers the DPDK exit handler
to run which starts unmapping huge pages while
our reactor thread is still running.

Currently, this doesn't cause any problems since
the fuzzing thread and reactor thread are running
on the same core.  But the next patch will
unaffinitize the fuzzing thread, meaning that the
reactor thread will be actively trying to read
hugepage memory while the fuzzing thread is in
DPDK exit handlers unmapping that same memory.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: Ie304ebbb1962855796dac699849a0726cfdcd0d4
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/12406
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: John Kariuki <John.K.Kariuki@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
This commit is contained in:
Jim Harris 2022-04-26 21:20:08 +00:00 committed by Tomasz Zawadzki
parent 88653b4fe0
commit 0674ead739

View File

@ -45,7 +45,9 @@ static bool g_trid_specified = false;
static int32_t g_time_in_sec = 10;
static char *g_corpus_dir;
static pthread_t g_fuzz_td;
static pthread_t g_reactor_td;
static bool g_shutdown;
static bool g_in_fuzzer;
#define MAX_COMMANDS 5
@ -584,6 +586,14 @@ static int TestOneInput(const uint8_t *data, size_t size)
int LLVMFuzzerRunDriver(int *argc, char ***argv, int (*UserCb)(const uint8_t *Data, size_t Size));
static void exit_handler(void)
{
if (g_in_fuzzer) {
spdk_app_stop(0);
pthread_join(g_reactor_td, NULL);
}
}
static void *
start_fuzzer(void *ctx)
{
@ -608,8 +618,18 @@ start_fuzzer(void *ctx)
argv[argc - 2] = time_str;
argv[argc - 1] = g_corpus_dir;
g_in_fuzzer = true;
atexit(exit_handler);
LLVMFuzzerRunDriver(&argc, &argv, TestOneInput);
/* TODO: in the normal case, LLVMFuzzerRunDriver never returns - it calls exit()
* directly and we never get here. But this behavior isn't really documented
* anywhere by LLVM, so call spdk_app_stop(0) if it does return, which will
* result in the app exiting like a normal SPDK application (spdk_app_start()
* returns to main().
*/
g_in_fuzzer = false;
spdk_app_stop(0);
return NULL;
}
@ -618,6 +638,8 @@ begin_fuzz(void *ctx)
{
int i;
g_reactor_td = pthread_self();
for (i = 0; i < MAX_COMMANDS; i++) {
g_cmds[i].buf = spdk_malloc(4096, 0, NULL, SPDK_ENV_LCORE_ID_ANY, SPDK_MALLOC_DMA);
assert(g_cmds[i].buf);