[libFuzzer] make libFuzzer link if there is no sanitizer coverage instrumentation (it will fail at start-up time)

llvm-svn: 252533
This commit is contained in:
Kostya Serebryany 2015-11-09 23:17:45 +00:00
parent 72303a2436
commit 5eab74e9bc
4 changed files with 50 additions and 0 deletions

View File

@ -14,13 +14,34 @@
#include <algorithm>
extern "C" {
// Re-declare some of the sanitizer functions as "weak" so that
// libFuzzer can be linked w/o the sanitizers and sanitizer-coveragte
// (in which case it will complain at start-up time).
__attribute__((weak)) void __sanitizer_print_stack_trace();
__attribute__((weak)) size_t __sanitizer_get_total_unique_caller_callee_pairs();
__attribute__((weak)) size_t __sanitizer_get_total_unique_coverage();
__attribute__((weak))
void __sanitizer_set_death_callback(void (*callback)(void));
__attribute__((weak)) size_t __sanitizer_get_number_of_counters();
__attribute__((weak))
uintptr_t __sanitizer_update_counter_bitset_and_clear_counters(uint8_t *bitset);
}
namespace fuzzer {
static const size_t kMaxUnitSizeToPrint = 256;
static void MissingWeakApiFunction(const char *FnName) {
Printf("ERROR: %s is not defined. Exiting.\n"
"Did you use -fsanitize-coverage=... to build your code?\n", FnName);
exit(1);
}
#define CHECK_WEAK_API_FUNCTION(fn) \
do { \
if (!fn) \
MissingWeakApiFunction(#fn); \
} while (false)
// Only one Fuzzer per process.
static Fuzzer *F;
@ -33,6 +54,7 @@ Fuzzer::Fuzzer(UserSuppliedFuzzer &USF, FuzzingOptions Options)
}
void Fuzzer::SetDeathCallback() {
CHECK_WEAK_API_FUNCTION(__sanitizer_set_death_callback);
__sanitizer_set_death_callback(StaticDeathCallback);
}
@ -204,6 +226,7 @@ void Fuzzer::ExecuteCallback(const Unit &U) {
}
size_t Fuzzer::RecordBlockCoverage() {
CHECK_WEAK_API_FUNCTION(__sanitizer_get_total_unique_coverage);
return LastRecordedBlockCoverage = __sanitizer_get_total_unique_coverage();
}

View File

@ -34,6 +34,10 @@ set(CustomMainTests
UserSuppliedFuzzerTest
)
set(UninstrumentedTests
UninstrumentedTest
)
set(TestBinaries)
@ -89,6 +93,12 @@ foreach(Test ${DFSanTests})
set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test}-DFSan)
endforeach()
add_subdirectory(uninstrumented)
foreach(Test ${UninstrumentedTests})
set(TestBinaries ${TestBinaries} LLVMFuzzer-${Test}-Uninstrumented)
endforeach()
set_target_properties(${TestBinaries}
PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}

View File

@ -60,3 +60,6 @@ RUN: LLVMFuzzer-SimpleDictionaryTest -seed=1 -runs=100000
RUN: not LLVMFuzzer-SimpleHashTest -use_traces=1 -seed=1 -runs=100000 2>&1 | FileCheck %s
RUN: LLVMFuzzer-SimpleHashTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
RUN: not LLVMFuzzer-UninstrumentedTest-Uninstrumented 2>&1 | FileCheck %s --check-prefix=UNINSTRUMENTED
UNINSTRUMENTED: ERROR: __sanitizer_set_death_callback is not defined. Exiting.

View File

@ -0,0 +1,14 @@
# These tests are not instrumented with coverage.
set(CMAKE_CXX_FLAGS_RELEASE
"${LIBFUZZER_FLAGS_BASE} -O0 -fno-sanitize=all")
foreach(Test ${UninstrumentedTests})
add_executable(LLVMFuzzer-${Test}-Uninstrumented
../${Test}.cpp
)
target_link_libraries(LLVMFuzzer-${Test}-Uninstrumented
LLVMFuzzer
)
endforeach()