aboutsummaryrefslogtreecommitdiff
path: root/lib/Fuzzer/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Fuzzer/test')
-rw-r--r--lib/Fuzzer/test/AbsNegAndConstant64Test.cpp2
-rw-r--r--lib/Fuzzer/test/BadStrcmpTest.cpp19
-rw-r--r--lib/Fuzzer/test/BogusInitializeTest.cpp15
-rw-r--r--lib/Fuzzer/test/CMakeLists.txt107
-rw-r--r--lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp34
-rw-r--r--lib/Fuzzer/test/CxxStringEqTest.cpp25
-rw-r--r--lib/Fuzzer/test/DSO1.cpp4
-rw-r--r--lib/Fuzzer/test/DSO2.cpp4
-rw-r--r--lib/Fuzzer/test/EquivalenceATest.cpp17
-rw-r--r--lib/Fuzzer/test/EquivalenceBTest.cpp27
-rw-r--r--lib/Fuzzer/test/FuzzerUnittest.cpp43
-rw-r--r--lib/Fuzzer/test/LargeTest.cpp37
-rw-r--r--lib/Fuzzer/test/LoadTest.cpp2
-rw-r--r--lib/Fuzzer/test/Memcmp64BytesTest.cpp20
-rw-r--r--lib/Fuzzer/test/NotinstrumentedTest.cpp (renamed from lib/Fuzzer/test/UninstrumentedTest.cpp)0
-rw-r--r--lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp2
-rw-r--r--lib/Fuzzer/test/RepeatedMemcmp.cpp17
-rw-r--r--lib/Fuzzer/test/SimpleCmpTest.cpp9
-rw-r--r--lib/Fuzzer/test/SingleByteInputTest.cpp17
-rw-r--r--lib/Fuzzer/test/SingleStrcmpTest.cpp12
-rw-r--r--lib/Fuzzer/test/SingleStrncmpTest.cpp3
-rw-r--r--lib/Fuzzer/test/SwapCmpTest.cpp3
-rw-r--r--lib/Fuzzer/test/TableLookupTest.cpp45
-rw-r--r--lib/Fuzzer/test/TwoDifferentBugsTest.cpp22
-rw-r--r--lib/Fuzzer/test/afl-driver-extra-stats.test2
-rw-r--r--lib/Fuzzer/test/afl-driver-stderr.test2
-rw-r--r--lib/Fuzzer/test/bad-strcmp.test1
-rw-r--r--lib/Fuzzer/test/coverage.test4
-rw-r--r--lib/Fuzzer/test/cxxstring.test2
-rw-r--r--lib/Fuzzer/test/disable-leaks.test4
-rw-r--r--lib/Fuzzer/test/dump_coverage.test26
-rw-r--r--lib/Fuzzer/test/equivalence-signals.test9
-rw-r--r--lib/Fuzzer/test/equivalence.test8
-rw-r--r--lib/Fuzzer/test/extra-counters.test6
-rw-r--r--lib/Fuzzer/test/fuzzer-customcrossover.test2
-rw-r--r--lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test1
-rw-r--r--lib/Fuzzer/test/fuzzer-dirs.test4
-rw-r--r--lib/Fuzzer/test/fuzzer-jobs.test29
-rw-r--r--lib/Fuzzer/test/fuzzer-leak.test2
-rw-r--r--lib/Fuzzer/test/fuzzer-oom.test6
-rw-r--r--lib/Fuzzer/test/fuzzer-segv.test2
-rw-r--r--lib/Fuzzer/test/fuzzer-singleinputs.test2
-rw-r--r--lib/Fuzzer/test/fuzzer-traces-hooks.test26
-rw-r--r--lib/Fuzzer/test/fuzzer.test9
-rw-r--r--lib/Fuzzer/test/lit.cfg26
-rw-r--r--lib/Fuzzer/test/lit.site.cfg.in1
-rw-r--r--lib/Fuzzer/test/merge-posix.test23
-rw-r--r--lib/Fuzzer/test/merge-summary.test15
-rw-r--r--lib/Fuzzer/test/merge.test27
-rw-r--r--lib/Fuzzer/test/minimize_crash.test9
-rw-r--r--lib/Fuzzer/test/minimize_two_crashes.test16
-rw-r--r--lib/Fuzzer/test/no-coverage/CMakeLists.txt20
-rw-r--r--lib/Fuzzer/test/trace-malloc-2.test8
-rw-r--r--lib/Fuzzer/test/trace-malloc.test5
-rw-r--r--lib/Fuzzer/test/trace-pc.test2
-rw-r--r--lib/Fuzzer/test/trace-pc/CMakeLists.txt13
-rw-r--r--lib/Fuzzer/test/ubsan/CMakeLists.txt3
-rw-r--r--lib/Fuzzer/test/ulimit.test2
-rw-r--r--lib/Fuzzer/test/uninstrumented/CMakeLists.txt3
-rw-r--r--lib/Fuzzer/test/value-profile-div.test2
-rw-r--r--lib/Fuzzer/test/value-profile-mem.test2
-rw-r--r--lib/Fuzzer/test/value-profile-strcmp.test2
-rw-r--r--lib/Fuzzer/test/value-profile-strncmp.test2
63 files changed, 649 insertions, 165 deletions
diff --git a/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp b/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp
index 577481431ae2..69b0d59fb8ef 100644
--- a/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp
+++ b/lib/Fuzzer/test/AbsNegAndConstant64Test.cpp
@@ -14,7 +14,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
uint64_t y;
memcpy(&x, Data, sizeof(x));
memcpy(&y, Data + sizeof(x), sizeof(y));
- if (labs(x) < 0 && y == 0xbaddcafedeadbeefUL) {
+ if (llabs(x) < 0 && y == 0xbaddcafedeadbeefULL) {
printf("BINGO; Found the target, exiting; x = 0x%lx y 0x%lx\n", x, y);
exit(1);
}
diff --git a/lib/Fuzzer/test/BadStrcmpTest.cpp b/lib/Fuzzer/test/BadStrcmpTest.cpp
new file mode 100644
index 000000000000..159cd7ea5f70
--- /dev/null
+++ b/lib/Fuzzer/test/BadStrcmpTest.cpp
@@ -0,0 +1,19 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test that we don't creash in case of bad strcmp params.
+#include <cstdint>
+#include <cstring>
+#include <cstddef>
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size != 10) return 0;
+ // Data is not zero-terminated, so this call is bad.
+ // Still, there are cases when such calles appear, see e.g.
+ // https://bugs.llvm.org/show_bug.cgi?id=32357
+ Sink = strcmp(reinterpret_cast<const char*>(Data), "123456789");
+ return 0;
+}
+
diff --git a/lib/Fuzzer/test/BogusInitializeTest.cpp b/lib/Fuzzer/test/BogusInitializeTest.cpp
new file mode 100644
index 000000000000..c7e81a5478b2
--- /dev/null
+++ b/lib/Fuzzer/test/BogusInitializeTest.cpp
@@ -0,0 +1,15 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Make sure LLVMFuzzerInitialize does not change argv[0].
+#include <stddef.h>
+#include <stdint.h>
+
+extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv) {
+ ***argv = 'X';
+ return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ return 0;
+}
diff --git a/lib/Fuzzer/test/CMakeLists.txt b/lib/Fuzzer/test/CMakeLists.txt
index c0457746a0e7..f72bc3909a3c 100644
--- a/lib/Fuzzer/test/CMakeLists.txt
+++ b/lib/Fuzzer/test/CMakeLists.txt
@@ -11,21 +11,35 @@ set(variables_to_filter
LIBFUZZER_FLAGS_BASE
)
foreach (VARNAME ${variables_to_filter})
- string(REPLACE " " ";" BUILD_FLAGS_AS_LIST "${${VARNAME}}")
- set(new_flags "")
- foreach (flag ${BUILD_FLAGS_AS_LIST})
- # NOTE: Use of XX here is to avoid a CMake warning due to CMP0054
- if (NOT ("XX${flag}" MATCHES "XX-O[0123s]"))
- set(new_flags "${new_flags} ${flag}")
- else()
- set(new_flags "${new_flags} -O0")
- endif()
- endforeach()
- set(${VARNAME} "${new_flags}")
+ string(REGEX REPLACE "([-/]O)[123s]" "\\10" ${VARNAME} "${${VARNAME}}")
endforeach()
# Enable the coverage instrumentation (it is disabled for the Fuzzer lib).
-set(CMAKE_CXX_FLAGS "${LIBFUZZER_FLAGS_BASE} -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp,trace-div,trace-gep -g")
+set(CMAKE_CXX_FLAGS "${LIBFUZZER_FLAGS_BASE} -fsanitize-coverage=trace-pc-guard,indirect-calls,trace-cmp,trace-div,trace-gep -gline-tables-only")
+
+if(MSVC)
+ # For tests use the CRT specified for release build
+ # (asan doesn't support MDd and MTd)
+ if ("${LLVM_USE_CRT_RELEASE}" STREQUAL "")
+ set(CRT_FLAG " /MD ")
+ else()
+ set(CRT_FLAG " /${LLVM_USE_CRT_RELEASE} ")
+ endif()
+ # In order to use the sanitizers in Windows, we need to link against many
+ # runtime libraries which will depend on the target being created
+ # (executable or dll) and the c runtime library used (MT/MD).
+ # By default, cmake uses link.exe for linking, which fails because we don't
+ # specify the appropiate dependencies.
+ # As we don't want to consider all of that possible situations which depends
+ # on the implementation of the compiler-rt, the simplest option is to change
+ # the rules for linking executables and shared libraries, using the compiler
+ # instead of link.exe. Clang will consider the sanitizer flags, and
+ # automatically provide the required libraries to the linker.
+ set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_CXX_COMPILER> <FLAGS> ${CMAKE_CXX_FLAGS} ${CRT_FLAG} <OBJECTS> -o <TARGET> <LINK_LIBRARIES> /link <CMAKE_CXX_LINK_FLAGS> <LINK_FLAGS>")
+ set(CMAKE_CXX_CREATE_SHARED_LIBRARY "<CMAKE_CXX_COMPILER> ${CMAKE_CXX_FLAGS} ${CRT_FLAG} /LD <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG> <TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES> /link <LINK_FLAGS>")
+endif()
+
+add_custom_target(TestBinaries)
# add_libfuzzer_test(<name>
# SOURCES source0.cpp [source1.cpp ...]
@@ -51,12 +65,9 @@ function(add_libfuzzer_test name)
PROPERTIES RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_BINARY_DIR}/lib/Fuzzer/test"
)
- set(TestBinaries ${TestBinaries} LLVMFuzzer-${name} PARENT_SCOPE)
+ add_dependencies(TestBinaries LLVMFuzzer-${name})
endfunction()
-# Variable to keep track of all test targets
-set(TestBinaries)
-
###############################################################################
# Basic tests
###############################################################################
@@ -65,16 +76,23 @@ set(Tests
AbsNegAndConstantTest
AbsNegAndConstant64Test
AccumulateAllocationsTest
+ BadStrcmpTest
+ BogusInitializeTest
BufferOverflowOnInput
CallerCalleeTest
CounterTest
+ CustomCrossOverAndMutateTest
CustomCrossOverTest
CustomMutatorTest
+ CxxStringEqTest
DivTest
EmptyTest
+ EquivalenceATest
+ EquivalenceBTest
FourIndependentBranchesTest
FullCoverageSetTest
InitializeTest
+ Memcmp64BytesTest
MemcmpTest
LeakTest
LeakTimeoutTest
@@ -92,6 +110,7 @@ set(Tests
SimpleHashTest
SimpleTest
SimpleThreadedTest
+ SingleByteInputTest
SingleMemcmpTest
SingleStrcmpTest
SingleStrncmpTest
@@ -105,17 +124,19 @@ set(Tests
SwapCmpTest
SwitchTest
Switch2Test
+ TableLookupTest
ThreadedLeakTest
ThreadedTest
TimeoutTest
TimeoutEmptyTest
TraceMallocTest
+ TwoDifferentBugsTest
)
-if(APPLE)
- # LeakSanitizer is not supported on OSX right now
+if(APPLE OR MSVC)
+ # LeakSanitizer is not supported on OSX and Windows right now
set(HAS_LSAN 0)
- message(WARNING "LeakSanitizer is not supported on Apple platforms."
+ message(WARNING "LeakSanitizer is not supported."
" Building and running LibFuzzer LeakSanitizer tests is disabled."
)
else()
@@ -126,6 +147,17 @@ foreach(Test ${Tests})
add_libfuzzer_test(${Test} SOURCES ${Test}.cpp)
endforeach()
+function(test_export_symbol target symbol)
+ if(MSVC)
+ set_target_properties(LLVMFuzzer-${target} PROPERTIES LINK_FLAGS
+ "-export:${symbol}")
+ endif()
+endfunction()
+
+test_export_symbol(InitializeTest "LLVMFuzzerInitialize")
+test_export_symbol(BogusInitializeTest "LLVMFuzzerInitialize")
+test_export_symbol(CustomCrossOverTest "LLVMFuzzerCustomCrossOver")
+test_export_symbol(CustomMutatorTest "LLVMFuzzerCustomMutator")
###############################################################################
# Unit tests
@@ -150,13 +182,13 @@ target_include_directories(LLVMFuzzer-Unittest PRIVATE
"${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest/include"
)
-set(TestBinaries ${TestBinaries} LLVMFuzzer-Unittest)
+add_dependencies(TestBinaries LLVMFuzzer-Unittest)
set_target_properties(LLVMFuzzer-Unittest
PROPERTIES RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}"
)
-set(TestBinaries ${TestBinaries} LLVMFuzzer-StandaloneInitializeTest)
+add_dependencies(TestBinaries LLVMFuzzer-StandaloneInitializeTest)
set_target_properties(LLVMFuzzer-StandaloneInitializeTest
PROPERTIES RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}"
@@ -170,6 +202,7 @@ include_directories(..)
# add_subdirectory(uninstrumented)
add_subdirectory(no-coverage)
+add_subdirectory(trace-pc)
add_subdirectory(ubsan)
add_library(LLVMFuzzer-DSO1 SHARED DSO1.cpp)
@@ -187,12 +220,22 @@ target_link_libraries(LLVMFuzzer-DSOTest
set_target_properties(LLVMFuzzer-DSOTest PROPERTIES RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_BINARY_DIR}/lib/Fuzzer/test")
-set_target_properties(LLVMFuzzer-DSO1 PROPERTIES LIBRARY_OUTPUT_DIRECTORY
- "${CMAKE_BINARY_DIR}/lib/Fuzzer/lib")
-set_target_properties(LLVMFuzzer-DSO2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY
- "${CMAKE_BINARY_DIR}/lib/Fuzzer/lib")
-set(TestBinaries ${TestBinaries} LLVMFuzzer-DSOTest)
+if(MSVC)
+ set_output_directory(LLVMFuzzer-DSO1
+ BINARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/test"
+ LIBRARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/test")
+ set_output_directory(LLVMFuzzer-DSO2
+ BINARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/test"
+ LIBRARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/test")
+else(MSVC)
+ set_output_directory(LLVMFuzzer-DSO1
+ LIBRARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/lib")
+ set_output_directory(LLVMFuzzer-DSO2
+ LIBRARY_DIR "${CMAKE_BINARY_DIR}/lib/Fuzzer/lib")
+endif()
+
+add_dependencies(TestBinaries LLVMFuzzer-DSOTest)
###############################################################################
# Configure lit to run the tests
@@ -200,6 +243,10 @@ set(TestBinaries ${TestBinaries} LLVMFuzzer-DSOTest)
# Note this is done after declaring all tests so we can inform lit if any tests
# need to be disabled.
###############################################################################
+set(LIBFUZZER_POSIX 1)
+if (MSVC)
+ set(LIBFUZZER_POSIX 0)
+endif()
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
@@ -213,5 +260,11 @@ configure_lit_site_cfg(
add_lit_testsuite(check-fuzzer "Running Fuzzer tests"
${CMAKE_CURRENT_BINARY_DIR}
- DEPENDS ${TestBinaries} FileCheck not
+ DEPENDS TestBinaries
)
+
+# Don't add dependencies on Windows. The linker step would fail on Windows,
+# since cmake will use link.exe for linking and won't include compiler-rt libs.
+if(NOT MSVC)
+ add_dependencies(check-fuzzer FileCheck sancov not)
+endif()
diff --git a/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp b/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp
new file mode 100644
index 000000000000..74fc939534ca
--- /dev/null
+++ b/lib/Fuzzer/test/CustomCrossOverAndMutateTest.cpp
@@ -0,0 +1,34 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test that libFuzzer does not crash when LLVMFuzzerMutate called from
+// LLVMFuzzerCustomCrossOver.
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <string.h>
+#include <string>
+#include <vector>
+
+#include "FuzzerInterface.h"
+
+static volatile int sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ std::string Str(reinterpret_cast<const char *>(Data), Size);
+ if (Size && Data[0] == '0')
+ sink++;
+ return 0;
+}
+
+extern "C" size_t LLVMFuzzerCustomCrossOver(const uint8_t *Data1, size_t Size1,
+ const uint8_t *Data2, size_t Size2,
+ uint8_t *Out, size_t MaxOutSize,
+ unsigned int Seed) {
+ std::vector<uint8_t> Buffer(MaxOutSize * 10);
+ LLVMFuzzerMutate(Buffer.data(), Buffer.size(), Buffer.size());
+ size_t Size = std::min(Size1, MaxOutSize);
+ memcpy(Out, Data1, Size);
+ return Size;
+}
diff --git a/lib/Fuzzer/test/CxxStringEqTest.cpp b/lib/Fuzzer/test/CxxStringEqTest.cpp
new file mode 100644
index 000000000000..e0e23c972ccb
--- /dev/null
+++ b/lib/Fuzzer/test/CxxStringEqTest.cpp
@@ -0,0 +1,25 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. Must find a specific string
+// used in std::string operator ==.
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#include <string>
+#include <iostream>
+
+static volatile int Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ std::string Str((const char*)Data, Size);
+ bool Eq = Str == "FooBar";
+ Sink = Str == "123456"; // Try to confuse the fuzzer
+ if (Eq) {
+ std::cout << "BINGO; Found the target, exiting\n";
+ std::cout.flush();
+ abort();
+ }
+ return 0;
+}
+
diff --git a/lib/Fuzzer/test/DSO1.cpp b/lib/Fuzzer/test/DSO1.cpp
index 4a293890f4b0..72a5ec4a0cde 100644
--- a/lib/Fuzzer/test/DSO1.cpp
+++ b/lib/Fuzzer/test/DSO1.cpp
@@ -2,7 +2,9 @@
// License. See LICENSE.TXT for details.
// Source code for a simple DSO.
-
+#ifdef _WIN32
+__declspec( dllexport )
+#endif
int DSO1(int a) {
if (a < 123456)
return 0;
diff --git a/lib/Fuzzer/test/DSO2.cpp b/lib/Fuzzer/test/DSO2.cpp
index 04b308d193ac..2967055dc227 100644
--- a/lib/Fuzzer/test/DSO2.cpp
+++ b/lib/Fuzzer/test/DSO2.cpp
@@ -2,7 +2,9 @@
// License. See LICENSE.TXT for details.
// Source code for a simple DSO.
-
+#ifdef _WIN32
+__declspec( dllexport )
+#endif
int DSO2(int a) {
if (a < 3598235)
return 0;
diff --git a/lib/Fuzzer/test/EquivalenceATest.cpp b/lib/Fuzzer/test/EquivalenceATest.cpp
new file mode 100644
index 000000000000..7d1ebb0f6a4a
--- /dev/null
+++ b/lib/Fuzzer/test/EquivalenceATest.cpp
@@ -0,0 +1,17 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+// Test for libFuzzer's "equivalence" fuzzing, part A.
+extern "C" void LLVMFuzzerAnnounceOutput(const uint8_t *Data, size_t Size);
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ // fprintf(stderr, "A %zd\n", Size);
+ uint8_t Result[50];
+ if (Size > 50) Size = 50;
+ for (size_t i = 0; i < Size; i++)
+ Result[Size - i - 1] = Data[i];
+ LLVMFuzzerAnnounceOutput(Result, Size);
+ return 0;
+}
diff --git a/lib/Fuzzer/test/EquivalenceBTest.cpp b/lib/Fuzzer/test/EquivalenceBTest.cpp
new file mode 100644
index 000000000000..b1de208b57f6
--- /dev/null
+++ b/lib/Fuzzer/test/EquivalenceBTest.cpp
@@ -0,0 +1,27 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+
+// Test for libFuzzer's "equivalence" fuzzing, part B.
+extern "C" void LLVMFuzzerAnnounceOutput(const uint8_t *Data, size_t Size);
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ // fprintf(stderr, "B %zd\n", Size);
+ uint8_t Result[50];
+ if (Size > 50) Size = 50;
+ for (size_t i = 0; i < Size; i++)
+ Result[Size - i - 1] = Data[i];
+
+ // Be a bit different from EquivalenceATest
+ if (Size > 10 && Data[5] == 'B' && Data[6] == 'C' && Data[7] == 'D') {
+ static int c;
+ if (!c)
+ fprintf(stderr, "ZZZZZZZ\n");
+ c = 1;
+ Result[2]++;
+ }
+
+ LLVMFuzzerAnnounceOutput(Result, Size);
+ return 0;
+}
diff --git a/lib/Fuzzer/test/FuzzerUnittest.cpp b/lib/Fuzzer/test/FuzzerUnittest.cpp
index 4992ef57b6ca..78ea874f2ce2 100644
--- a/lib/Fuzzer/test/FuzzerUnittest.cpp
+++ b/lib/Fuzzer/test/FuzzerUnittest.cpp
@@ -10,10 +10,12 @@
#include "FuzzerDictionary.h"
#include "FuzzerMerge.h"
#include "FuzzerMutate.h"
+#include "FuzzerTracePC.h"
#include "FuzzerRandom.h"
#include "gtest/gtest.h"
#include <memory>
#include <set>
+#include <sstream>
using namespace fuzzer;
@@ -584,15 +586,15 @@ TEST(FuzzerUtil, Base64) {
TEST(Corpus, Distribution) {
Random Rand(0);
- InputCorpus C("");
+ std::unique_ptr<InputCorpus> C(new InputCorpus(""));
size_t N = 10;
size_t TriesPerUnit = 1<<16;
for (size_t i = 0; i < N; i++)
- C.AddToCorpus(Unit{ static_cast<uint8_t>(i) }, 0);
+ C->AddToCorpus(Unit{ static_cast<uint8_t>(i) }, 0);
std::vector<size_t> Hist(N);
for (size_t i = 0; i < N * TriesPerUnit; i++) {
- Hist[C.ChooseUnitIdxToMutate(Rand)]++;
+ Hist[C->ChooseUnitIdxToMutate(Rand)]++;
}
for (size_t i = 0; i < N; i++) {
// A weak sanity check that every unit gets invoked.
@@ -636,7 +638,10 @@ static void Merge(const std::string &Input,
Merger M;
std::vector<std::string> NewFiles;
EXPECT_TRUE(M.Parse(Input, true));
+ std::stringstream SS;
+ M.PrintSummary(SS);
EXPECT_EQ(NumNewFeatures, M.Merge(&NewFiles));
+ EXPECT_EQ(M.AllFeatures(), M.ParseSummary(SS));
EQ(NewFiles, Result);
}
@@ -706,6 +711,16 @@ TEST(Merge, Good) {
EQ(M.Files[2].Features, {1, 3, 6});
EXPECT_EQ(3U, M.Merge(&NewFiles));
EQ(NewFiles, {"B"});
+
+ // Same as the above, but with InitialFeatures.
+ EXPECT_TRUE(M.Parse("2\n0\nB\nC\n"
+ "STARTED 0 1001\nDONE 0 4 5 6 \n"
+ "STARTED 1 1002\nDONE 1 6 1 3\n"
+ "", true));
+ EQ(M.Files[0].Features, {4, 5, 6});
+ EQ(M.Files[1].Features, {1, 3, 6});
+ EXPECT_EQ(3U, M.Merge({1, 2, 3}, &NewFiles));
+ EQ(NewFiles, {"B"});
}
TEST(Merge, Merge) {
@@ -736,3 +751,25 @@ TEST(Merge, Merge) {
"STARTED 3 1000\nDONE 3 1 \n",
{"B", "D"}, 3);
}
+
+TEST(Fuzzer, ForEachNonZeroByte) {
+ const size_t N = 64;
+ alignas(64) uint8_t Ar[N + 8] = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 0, 6, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 8,
+ 9, 9, 9, 9, 9, 9, 9, 9,
+ };
+ typedef std::vector<std::pair<size_t, uint8_t> > Vec;
+ Vec Res, Expected;
+ auto CB = [&](size_t Idx, uint8_t V) { Res.push_back({Idx, V}); };
+ ForEachNonZeroByte(Ar, Ar + N, 100, CB);
+ Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4},
+ {135, 5}, {137, 6}, {146, 7}, {163, 8}};
+ EXPECT_EQ(Res, Expected);
+}
diff --git a/lib/Fuzzer/test/LargeTest.cpp b/lib/Fuzzer/test/LargeTest.cpp
new file mode 100644
index 000000000000..83ed61971801
--- /dev/null
+++ b/lib/Fuzzer/test/LargeTest.cpp
@@ -0,0 +1,37 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// A fuzz target with lots of edges.
+#include <cstdint>
+#include <cstdlib>
+
+static inline void break_optimization(const void *arg) {
+ __asm__ __volatile__("" : : "r" (arg) : "memory");
+}
+
+#define A \
+ do { \
+ i++; \
+ c++; \
+ if (Data[(i + __LINE__) % Size] == (c % 256)) \
+ break_optimization(Data); \
+ else \
+ break_optimization(0); \
+ } while (0)
+
+// for (int i = 0, n = Data[(__LINE__ - 1) % Size] % 16; i < n; i++)
+
+#define B do{A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; A; }while(0)
+#define C do{B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; B; }while(0)
+#define D do{C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; C; }while(0)
+#define E do{D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; D; }while(0)
+
+volatile int sink;
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (!Size) return 0;
+ int c = 0;
+ int i = 0;
+ D;
+ return 0;
+}
+
diff --git a/lib/Fuzzer/test/LoadTest.cpp b/lib/Fuzzer/test/LoadTest.cpp
index c1780d5c7bd9..eef16c7be51e 100644
--- a/lib/Fuzzer/test/LoadTest.cpp
+++ b/lib/Fuzzer/test/LoadTest.cpp
@@ -14,7 +14,7 @@ int array[kArraySize];
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size < 8) return 0;
- size_t a = 0;
+ uint64_t a = 0;
memcpy(&a, Data, 8);
Sink = array[a % (kArraySize + 1)];
return 0;
diff --git a/lib/Fuzzer/test/Memcmp64BytesTest.cpp b/lib/Fuzzer/test/Memcmp64BytesTest.cpp
new file mode 100644
index 000000000000..e81526b578a3
--- /dev/null
+++ b/lib/Fuzzer/test/Memcmp64BytesTest.cpp
@@ -0,0 +1,20 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. The fuzzer must find a particular string.
+#include <cassert>
+#include <cstring>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ const char kString64Bytes[] =
+ "123456789 123456789 123456789 123456789 123456789 123456789 1234";
+ assert(sizeof(kString64Bytes) == 65);
+ if (Size >= 64 && memcmp(Data, kString64Bytes, 64) == 0) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
+ return 0;
+}
diff --git a/lib/Fuzzer/test/UninstrumentedTest.cpp b/lib/Fuzzer/test/NotinstrumentedTest.cpp
index ffe952c749d2..ffe952c749d2 100644
--- a/lib/Fuzzer/test/UninstrumentedTest.cpp
+++ b/lib/Fuzzer/test/NotinstrumentedTest.cpp
diff --git a/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp b/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp
index ea23a601aa23..316b7682b8e6 100644
--- a/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp
+++ b/lib/Fuzzer/test/OutOfMemorySingleLargeMallocTest.cpp
@@ -15,7 +15,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
if (Size > 0 && Data[0] == 'H') {
if (Size > 1 && Data[1] == 'i') {
if (Size > 2 && Data[2] == '!') {
- size_t kSize = 0xff000000U;
+ size_t kSize = 0x20000000U;
char *p = new char[kSize];
SinkPtr = p;
delete [] p;
diff --git a/lib/Fuzzer/test/RepeatedMemcmp.cpp b/lib/Fuzzer/test/RepeatedMemcmp.cpp
index a327bbee7815..7377f65ed76d 100644
--- a/lib/Fuzzer/test/RepeatedMemcmp.cpp
+++ b/lib/Fuzzer/test/RepeatedMemcmp.cpp
@@ -8,13 +8,16 @@
#include <cstdlib>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
- int Matches = 0;
- for (size_t i = 0; i + 2 < Size; i += 3) {
- const char *Pat = i % 2 ? "foo" : "bar";
- if (!memcmp(Data + i, Pat, 3))
- Matches++;
- }
- if (Matches > 20) {
+ int Matches1 = 0;
+ for (size_t i = 0; i + 2 < Size; i += 3)
+ if (!memcmp(Data + i, "foo", 3))
+ Matches1++;
+ int Matches2 = 0;
+ for (size_t i = 0; i + 2 < Size; i += 3)
+ if (!memcmp(Data + i, "bar", 3))
+ Matches2++;
+
+ if (Matches1 > 10 && Matches2 > 10) {
fprintf(stderr, "BINGO!\n");
exit(1);
}
diff --git a/lib/Fuzzer/test/SimpleCmpTest.cpp b/lib/Fuzzer/test/SimpleCmpTest.cpp
index 0220c30f9a6b..12b5cdda0660 100644
--- a/lib/Fuzzer/test/SimpleCmpTest.cpp
+++ b/lib/Fuzzer/test/SimpleCmpTest.cpp
@@ -26,12 +26,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
memcpy(&y, Data + 8, 8); // 16
memcpy(&z, Data + 16, sizeof(z)); // 20
memcpy(&a, Data + 20, sizeof(a)); // 22
+ const bool k32bit = sizeof(void*) == 4;
- if (x > 1234567890 && PrintOnce(__LINE__) &&
- x < 1234567895 && PrintOnce(__LINE__) &&
+ if ((k32bit || x > 1234567890) && PrintOnce(__LINE__) &&
+ (k32bit || x < 1234567895) && PrintOnce(__LINE__) &&
a == 0x4242 && PrintOnce(__LINE__) &&
- y >= 987654321 && PrintOnce(__LINE__) &&
- y <= 987654325 && PrintOnce(__LINE__) &&
+ (k32bit || y >= 987654321) && PrintOnce(__LINE__) &&
+ (k32bit || y <= 987654325) && PrintOnce(__LINE__) &&
z < -10000 && PrintOnce(__LINE__) &&
z >= -10005 && PrintOnce(__LINE__) &&
z != -10003 && PrintOnce(__LINE__) &&
diff --git a/lib/Fuzzer/test/SingleByteInputTest.cpp b/lib/Fuzzer/test/SingleByteInputTest.cpp
new file mode 100644
index 000000000000..4ce819d230ce
--- /dev/null
+++ b/lib/Fuzzer/test/SingleByteInputTest.cpp
@@ -0,0 +1,17 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer, need just one byte to crash.
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#include <cstdio>
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size > 0 && Data[Size/2] == 42) {
+ fprintf(stderr, "BINGO\n");
+ abort();
+ }
+ return 0;
+}
+
diff --git a/lib/Fuzzer/test/SingleStrcmpTest.cpp b/lib/Fuzzer/test/SingleStrcmpTest.cpp
index 73470b527eeb..48f481dfc51a 100644
--- a/lib/Fuzzer/test/SingleStrcmpTest.cpp
+++ b/lib/Fuzzer/test/SingleStrcmpTest.cpp
@@ -8,10 +8,14 @@
#include <cstdlib>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
- char *S = (char*)Data;
- if (Size >= 7 && !strcmp(S, "qwerty")) {
- fprintf(stderr, "BINGO\n");
- exit(1);
+ if (Size >= 7) {
+ char Copy[7];
+ memcpy(Copy, Data, 6);
+ Copy[6] = 0;
+ if (!strcmp(Copy, "qwerty")) {
+ fprintf(stderr, "BINGO\n");
+ exit(1);
+ }
}
return 0;
}
diff --git a/lib/Fuzzer/test/SingleStrncmpTest.cpp b/lib/Fuzzer/test/SingleStrncmpTest.cpp
index dbcc464b0a78..e5601da86329 100644
--- a/lib/Fuzzer/test/SingleStrncmpTest.cpp
+++ b/lib/Fuzzer/test/SingleStrncmpTest.cpp
@@ -9,7 +9,8 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
char *S = (char*)Data;
- if (Size >= 6 && !strncmp(S, "qwerty", 6)) {
+ volatile auto Strncmp = &(strncmp); // Make sure strncmp is not inlined.
+ if (Size >= 6 && !Strncmp(S, "qwerty", 6)) {
fprintf(stderr, "BINGO\n");
exit(1);
}
diff --git a/lib/Fuzzer/test/SwapCmpTest.cpp b/lib/Fuzzer/test/SwapCmpTest.cpp
index f79db4ccf714..b90ac72c22c4 100644
--- a/lib/Fuzzer/test/SwapCmpTest.cpp
+++ b/lib/Fuzzer/test/SwapCmpTest.cpp
@@ -19,8 +19,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
x = __builtin_bswap64(x);
y = __builtin_bswap32(y);
z = __builtin_bswap16(z);
+ const bool k32bit = sizeof(void*) == 4;
- if (x == 0x46555A5A5A5A5546ULL &&
+ if ((k32bit || x == 0x46555A5A5A5A5546ULL) &&
z == 0x4F4B &&
y == 0x66757A7A &&
true
diff --git a/lib/Fuzzer/test/TableLookupTest.cpp b/lib/Fuzzer/test/TableLookupTest.cpp
new file mode 100644
index 000000000000..f9d5610820ff
--- /dev/null
+++ b/lib/Fuzzer/test/TableLookupTest.cpp
@@ -0,0 +1,45 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Make sure the fuzzer eventually finds all possible values of a variable
+// within a range.
+#include <cstring>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <cassert>
+#include <set>
+
+const size_t N = 1 << 12;
+
+// Define an array of counters that will be understood by libFuzzer
+// as extra coverage signal. The array must be:
+// * uint8_t
+// * aligned by 64
+// * in the section named __libfuzzer_extra_counters.
+// The target code may declare more than one such array.
+//
+// Use either `Counters[Idx] = 1` or `Counters[Idx]++;`
+// depending on whether multiple occurrences of the event 'Idx'
+// is important to distinguish from one occurrence.
+#ifdef __linux__
+alignas(64) __attribute__((section("__libfuzzer_extra_counters")))
+#endif
+static uint8_t Counters[N];
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ static std::set<uint16_t> SeenIdx;
+ if (Size != 4) return 0;
+ uint32_t Idx;
+ memcpy(&Idx, Data, 4);
+ Idx %= N;
+ assert(Counters[Idx] == 0); // libFuzzer should reset these between the runs.
+ // Or Counters[Idx]=1 if we don't care how many times this happened.
+ Counters[Idx]++;
+ SeenIdx.insert(Idx);
+ if (SeenIdx.size() == N) {
+ fprintf(stderr, "BINGO: found all values\n");
+ abort();
+ }
+ return 0;
+}
diff --git a/lib/Fuzzer/test/TwoDifferentBugsTest.cpp b/lib/Fuzzer/test/TwoDifferentBugsTest.cpp
new file mode 100644
index 000000000000..42c0d192ba86
--- /dev/null
+++ b/lib/Fuzzer/test/TwoDifferentBugsTest.cpp
@@ -0,0 +1,22 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Simple test for a fuzzer. This test may trigger two different bugs.
+#include <cstdint>
+#include <cstdlib>
+#include <cstddef>
+#include <iostream>
+
+static volatile int *Null = 0;
+
+void Foo() { Null[1] = 0; }
+void Bar() { Null[2] = 0; }
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ if (Size < 10 && Data[0] == 'H')
+ Foo();
+ if (Size >= 10 && Data[0] == 'H')
+ Bar();
+ return 0;
+}
+
diff --git a/lib/Fuzzer/test/afl-driver-extra-stats.test b/lib/Fuzzer/test/afl-driver-extra-stats.test
index 81e384e7dad2..1b0818e55ea5 100644
--- a/lib/Fuzzer/test/afl-driver-extra-stats.test
+++ b/lib/Fuzzer/test/afl-driver-extra-stats.test
@@ -1,3 +1,5 @@
+REQUIRES: posix
+
; Test that not specifying an extra stats file isn't broken.
RUN: unset AFL_DRIVER_EXTRA_STATS_FILENAME
RUN: AFLDriverTest
diff --git a/lib/Fuzzer/test/afl-driver-stderr.test b/lib/Fuzzer/test/afl-driver-stderr.test
index c0f9c8398c2a..e835acd4275b 100644
--- a/lib/Fuzzer/test/afl-driver-stderr.test
+++ b/lib/Fuzzer/test/afl-driver-stderr.test
@@ -1,3 +1,5 @@
+REQUIRES: posix
+
; Test that not specifying a stderr file isn't broken.
RUN: unset AFL_DRIVER_STDERR_DUPLICATE_FILENAME
RUN: AFLDriverTest
diff --git a/lib/Fuzzer/test/bad-strcmp.test b/lib/Fuzzer/test/bad-strcmp.test
new file mode 100644
index 000000000000..9a2f3742a5f4
--- /dev/null
+++ b/lib/Fuzzer/test/bad-strcmp.test
@@ -0,0 +1 @@
+RUN: LLVMFuzzer-BadStrcmpTest -runs=100000
diff --git a/lib/Fuzzer/test/coverage.test b/lib/Fuzzer/test/coverage.test
index fa11be502ef9..ff3fdff57a3d 100644
--- a/lib/Fuzzer/test/coverage.test
+++ b/lib/Fuzzer/test/coverage.test
@@ -1,9 +1,11 @@
+XFAIL: darwin
+
CHECK: COVERAGE:
CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:13
CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:14
CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:16
CHECK-DAG: COVERED: {{.*}}in LLVMFuzzerTestOneInput {{.*}}NullDerefTest.cpp:19
-CHECK: COVERED_DIRS: {{.*}}lib/Fuzzer/test
+CHECK: COVERED_DIRS: {{.*}}lib{{[/\\]}}Fuzzer{{[/\\]}}test
RUN: not LLVMFuzzer-NullDerefTest -print_coverage=1 2>&1 | FileCheck %s
RUN: LLVMFuzzer-DSOTest -print_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
diff --git a/lib/Fuzzer/test/cxxstring.test b/lib/Fuzzer/test/cxxstring.test
new file mode 100644
index 000000000000..c60d7aee9686
--- /dev/null
+++ b/lib/Fuzzer/test/cxxstring.test
@@ -0,0 +1,2 @@
+RUN: not LLVMFuzzer-CxxStringEqTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
+CHECK: BINGO
diff --git a/lib/Fuzzer/test/disable-leaks.test b/lib/Fuzzer/test/disable-leaks.test
new file mode 100644
index 000000000000..467b64ccc6f4
--- /dev/null
+++ b/lib/Fuzzer/test/disable-leaks.test
@@ -0,0 +1,4 @@
+REQUIRES: lsan
+RUN: LLVMFuzzer-AccumulateAllocationsTest -detect_leaks=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=ACCUMULATE_ALLOCS
+ACCUMULATE_ALLOCS: INFO: libFuzzer disabled leak detection after every mutation
+
diff --git a/lib/Fuzzer/test/dump_coverage.test b/lib/Fuzzer/test/dump_coverage.test
index 9bd98daa3619..8acc8304fc60 100644
--- a/lib/Fuzzer/test/dump_coverage.test
+++ b/lib/Fuzzer/test/dump_coverage.test
@@ -1,16 +1,14 @@
-RUN: DIR=%t_workdir
-RUN: BUILD_DIR=$(pwd)
-RUN: rm -rf $DIR && mkdir -p $DIR && cd $DIR
-RUN: not $BUILD_DIR/LLVMFuzzer-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s
-RUN: $BUILD_DIR/LLVMFuzzer-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
-RUN: not $BUILD_DIR/LLVMFuzzer-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV
-RUN: rm -rf $DIR
-
-
-CHECK: SanitizerCoverage: ./LLVMFuzzer-NullDerefTest.{{.*}}.sancov {{.*}} PCs written
-
-DSO: SanitizerCoverage: ./LLVMFuzzer-DSOTest.{{.*}}.sancov {{.*}} PCs written
-DSO-DAG: SanitizerCoverage: ./libLLVMFuzzer-DSO1.{{.*}}.sancov {{.*}} PCs written
-DSO-DAG: SanitizerCoverage: ./libLLVMFuzzer-DSO2.{{.*}}.sancov {{.*}} PCs written
+RUN: rm -rf %t_workdir && mkdir -p %t_workdir
+RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not LLVMFuzzer-NullDerefTest -dump_coverage=1 2>&1 | FileCheck %s
+RUN: sancov -covered-functions LLVMFuzzer-NullDerefTest* %t_workdir/*.sancov | FileCheck %s --check-prefix=SANCOV
+RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' LLVMFuzzer-DSOTest -dump_coverage=1 -runs=0 2>&1 | FileCheck %s --check-prefix=DSO
+RUN: env ASAN_OPTIONS=coverage_dir='"%t_workdir"' not LLVMFuzzer-NullDerefTest -dump_coverage=0 2>&1 | FileCheck %s --check-prefix=NOCOV
+
+CHECK: SanitizerCoverage: {{.*}}LLVMFuzzer-NullDerefTest.{{.*}}.sancov {{.*}} PCs written
+SANCOV: LLVMFuzzerTestOneInput
+
+DSO: SanitizerCoverage: {{.*}}LLVMFuzzer-DSOTest.{{.*}}.sancov {{.*}} PCs written
+DSO-DAG: SanitizerCoverage: {{.*}}LLVMFuzzer-DSO1.{{.*}}.sancov {{.*}} PCs written
+DSO-DAG: SanitizerCoverage: {{.*}}LLVMFuzzer-DSO2.{{.*}}.sancov {{.*}} PCs written
NOCOV-NOT: SanitizerCoverage: {{.*}} PCs written
diff --git a/lib/Fuzzer/test/equivalence-signals.test b/lib/Fuzzer/test/equivalence-signals.test
new file mode 100644
index 000000000000..81a7f37602cc
--- /dev/null
+++ b/lib/Fuzzer/test/equivalence-signals.test
@@ -0,0 +1,9 @@
+REQUIRES: posix
+# Run EquivalenceATest against itself with a small timeout
+# to stress the signal handling and ensure that shmem doesn't mind
+# the signals.
+
+RUN: LLVMFuzzer-EquivalenceATest -timeout=1 -run_equivalence_server=EQUIV_SIG_TEST & export APID=$!
+RUN: sleep 3
+RUN: LLVMFuzzer-EquivalenceATest -timeout=1 -use_equivalence_server=EQUIV_SIG_TEST -runs=500000 2>&1
+RUN: kill -9 $APID
diff --git a/lib/Fuzzer/test/equivalence.test b/lib/Fuzzer/test/equivalence.test
new file mode 100644
index 000000000000..015ba855c600
--- /dev/null
+++ b/lib/Fuzzer/test/equivalence.test
@@ -0,0 +1,8 @@
+REQUIRES: posix
+
+RUN: LLVMFuzzer-EquivalenceATest -run_equivalence_server=EQUIV_TEST & export APID=$!
+RUN: sleep 3
+RUN: not LLVMFuzzer-EquivalenceBTest -use_equivalence_server=EQUIV_TEST -max_len=4096 2>&1 | FileCheck %s
+CHECK: ERROR: libFuzzer: equivalence-mismatch. Sizes: {{.*}}; offset 2
+CHECK: SUMMARY: libFuzzer: equivalence-mismatch
+RUN: kill -9 $APID
diff --git a/lib/Fuzzer/test/extra-counters.test b/lib/Fuzzer/test/extra-counters.test
new file mode 100644
index 000000000000..61fce44784b7
--- /dev/null
+++ b/lib/Fuzzer/test/extra-counters.test
@@ -0,0 +1,6 @@
+REQUIRES: linux
+
+RUN: not LLVMFuzzer-TableLookupTest -print_final_stats=1 2>&1 | FileCheck %s
+CHECK: BINGO
+// Expecting >= 4096 new_units_added
+CHECK: stat::new_units_added:{{.*[4][0-9][0-9][0-9]}}
diff --git a/lib/Fuzzer/test/fuzzer-customcrossover.test b/lib/Fuzzer/test/fuzzer-customcrossover.test
index 28d39ce31dec..ccf8261af8ad 100644
--- a/lib/Fuzzer/test/fuzzer-customcrossover.test
+++ b/lib/Fuzzer/test/fuzzer-customcrossover.test
@@ -2,7 +2,7 @@ RUN: rm -rf %t/CustomCrossover
RUN: mkdir -p %t/CustomCrossover
RUN: echo "0123456789" > %t/CustomCrossover/digits
RUN: echo "abcdefghij" > %t/CustomCrossover/chars
-RUN: not LLVMFuzzer-CustomCrossOverTest -seed=1 -use_memcmp=0 -runs=100000 %t/CustomCrossover 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomCrossover
+RUN: not LLVMFuzzer-CustomCrossOverTest -seed=1 -runs=100000 %t/CustomCrossover 2>&1 | FileCheck %s --check-prefix=LLVMFuzzerCustomCrossover
RUN: rm -rf %t/CustomCrossover
LLVMFuzzerCustomCrossover: In LLVMFuzzerCustomCrossover
diff --git a/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test b/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test
new file mode 100644
index 000000000000..1e322ec0da63
--- /dev/null
+++ b/lib/Fuzzer/test/fuzzer-customcrossoverandmutate.test
@@ -0,0 +1 @@
+RUN: LLVMFuzzer-CustomCrossOverAndMutateTest -seed=1 -runs=100000
diff --git a/lib/Fuzzer/test/fuzzer-dirs.test b/lib/Fuzzer/test/fuzzer-dirs.test
index 63afe8dfcf9c..3de64f278f5d 100644
--- a/lib/Fuzzer/test/fuzzer-dirs.test
+++ b/lib/Fuzzer/test/fuzzer-dirs.test
@@ -5,9 +5,9 @@ RUN: echo b > %t/SUB1/SUB2/b
RUN: echo c > %t/SUB1/SUB2/SUB3/c
RUN: LLVMFuzzer-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=SUBDIRS
SUBDIRS: READ units: 3
-RUN: echo zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz > %t/SUB1/long
+RUN: echo -n zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz > %t/SUB1/long
RUN: LLVMFuzzer-SimpleTest %t/SUB1 -runs=0 2>&1 | FileCheck %s --check-prefix=LONG
-LONG: INFO: -max_len is not provided, using 94
+LONG: INFO: -max_len is not provided, using 93
RUN: rm -rf %t/SUB1
RUN: not LLVMFuzzer-SimpleTest NONEXISTENT_DIR 2>&1 | FileCheck %s --check-prefix=NONEXISTENT_DIR
diff --git a/lib/Fuzzer/test/fuzzer-jobs.test b/lib/Fuzzer/test/fuzzer-jobs.test
deleted file mode 100644
index 5bf8cfadfb75..000000000000
--- a/lib/Fuzzer/test/fuzzer-jobs.test
+++ /dev/null
@@ -1,29 +0,0 @@
-RUN: rm -rf %tmp
-RUN: mkdir %tmp && cd %tmp
-# Create a shared corpus directory
-RUN: rm -rf FuzzerJobsTestCORPUS
-RUN: mkdir FuzzerJobsTestCORPUS
-RUN: rm -f fuzz-{0,1}.log
-# Start fuzzer and in parallel check that the output files
-# that should be created exist.
-RUN: LLVMFuzzer-EmptyTest -max_total_time=4 -jobs=2 -workers=2 FuzzerJobsTestCORPUS > %t-fuzzer-jobs-test.log 2>&1 & export FUZZER_PID=$!
-# Wait a short while to give time for the child processes
-# to start fuzzing
-RUN: sleep 2
-# If the instances are running in parallel they should have created their log
-# files by now.
-RUN: ls fuzz-0.log
-RUN: ls fuzz-1.log
-# Wait for libfuzzer to finish.
-# This probably isn't portable but we need a way to block until
-# the fuzzer is done otherwise we might remove the files while
-# they are being used.
-RUN: while kill -0 ${FUZZER_PID}; do : ; done
-RUN: rm -f fuzz-{0,1}.log
-RUN: rm -rf FuzzerJobsTestCORPUS
-RUN: FileCheck -input-file=%t-fuzzer-jobs-test.log %s
-RUN: rm %t-fuzzer-jobs-test.log
-RUN: cd ../
-
-CHECK-DAG: Job 0 exited with exit code 0
-CHECK-DAG: Job 1 exited with exit code 0
diff --git a/lib/Fuzzer/test/fuzzer-leak.test b/lib/Fuzzer/test/fuzzer-leak.test
index 9cf5c743fff5..13e3ad740e6d 100644
--- a/lib/Fuzzer/test/fuzzer-leak.test
+++ b/lib/Fuzzer/test/fuzzer-leak.test
@@ -29,7 +29,5 @@ RUN: not LLVMFuzzer-LeakTimeoutTest -timeout=1 2>&1 | FileCheck %s --check-prefi
LEAK_TIMEOUT: ERROR: libFuzzer: timeout after
LEAK_TIMEOUT-NOT: LeakSanitizer
-RUN: LLVMFuzzer-AccumulateAllocationsTest -detect_leaks=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=ACCUMULATE_ALLOCS
-ACCUMULATE_ALLOCS: INFO: libFuzzer disabled leak detection after every mutation
RUN: LLVMFuzzer-LeakTest -error_exitcode=0
diff --git a/lib/Fuzzer/test/fuzzer-oom.test b/lib/Fuzzer/test/fuzzer-oom.test
index 8caf649e9f04..e9d33552723e 100644
--- a/lib/Fuzzer/test/fuzzer-oom.test
+++ b/lib/Fuzzer/test/fuzzer-oom.test
@@ -1,10 +1,12 @@
+XFAIL: darwin
RUN: not LLVMFuzzer-OutOfMemoryTest -rss_limit_mb=300 2>&1 | FileCheck %s
+
CHECK: ERROR: libFuzzer: out-of-memory (used: {{.*}}; limit: 300Mb)
CHECK: Test unit written to ./oom-
SUMMARY: libFuzzer: out-of-memory
-RUN: not LLVMFuzzer-OutOfMemorySingleLargeMallocTest 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC
-SINGLE_LARGE_MALLOC: libFuzzer: out-of-memory (malloc(42{{.*}}))
+RUN: not LLVMFuzzer-OutOfMemorySingleLargeMallocTest -rss_limit_mb=300 2>&1 | FileCheck %s --check-prefix=SINGLE_LARGE_MALLOC
+SINGLE_LARGE_MALLOC: libFuzzer: out-of-memory (malloc(53{{.*}}))
SINGLE_LARGE_MALLOC: in LLVMFuzzerTestOneInput
# Check that -rss_limit_mb=0 means no limit.
diff --git a/lib/Fuzzer/test/fuzzer-segv.test b/lib/Fuzzer/test/fuzzer-segv.test
index 330f03bcc494..b9a6a5ce44ca 100644
--- a/lib/Fuzzer/test/fuzzer-segv.test
+++ b/lib/Fuzzer/test/fuzzer-segv.test
@@ -1,4 +1,4 @@
-RUN: ASAN_OPTIONS=handle_segv=0 not LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER
+RUN: env ASAN_OPTIONS=handle_segv=0 not LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=LIBFUZZER_OWN_SEGV_HANDLER
LIBFUZZER_OWN_SEGV_HANDLER: == ERROR: libFuzzer: deadly signal
LIBFUZZER_OWN_SEGV_HANDLER: SUMMARY: libFuzzer: deadly signal
LIBFUZZER_OWN_SEGV_HANDLER: Test unit written to ./crash-
diff --git a/lib/Fuzzer/test/fuzzer-singleinputs.test b/lib/Fuzzer/test/fuzzer-singleinputs.test
index ca8403bff81f..500e5da8faa9 100644
--- a/lib/Fuzzer/test/fuzzer-singleinputs.test
+++ b/lib/Fuzzer/test/fuzzer-singleinputs.test
@@ -8,7 +8,7 @@ RUN: echo bbb > %tmp/SINGLE_INPUTS/bbb
RUN: LLVMFuzzer-SimpleTest %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS
RUN: LLVMFuzzer-SimpleTest -max_len=2 %tmp/SINGLE_INPUTS/aaa %tmp/SINGLE_INPUTS/bbb 2>&1 | FileCheck %s --check-prefix=SINGLE_INPUTS
RUN: rm -rf %tmp/SINGLE_INPUTS
-SINGLE_INPUTS: LLVMFuzzer-SimpleTest: Running 2 inputs 1 time(s) each.
+SINGLE_INPUTS: LLVMFuzzer-SimpleTest{{.*}}: Running 2 inputs 1 time(s) each.
SINGLE_INPUTS: aaa in
SINGLE_INPUTS: bbb in
SINGLE_INPUTS: NOTE: fuzzing was not performed, you have only
diff --git a/lib/Fuzzer/test/fuzzer-traces-hooks.test b/lib/Fuzzer/test/fuzzer-traces-hooks.test
index 71fe6f2daf11..f93a8b7199e2 100644
--- a/lib/Fuzzer/test/fuzzer-traces-hooks.test
+++ b/lib/Fuzzer/test/fuzzer-traces-hooks.test
@@ -1,25 +1,17 @@
-// FIXME: Support sanitizer hooks for memcmp and strcmp need
-// to be implemented in the sanitizer runtime for platforms other
-// than linux
-REQUIRES: linux
+// FIXME: Support for sanitizer hooks for memcmp and strcmp needs to
+// be implemented in the sanitizer runtime for this test
+UNSUPPORTED: windows
CHECK: BINGO
-Done1000000: Done 1000000 runs in
-RUN: not LLVMFuzzer-MemcmpTest -seed=4294967295 -runs=100000 2>&1 | FileCheck %s
-RUN: LLVMFuzzer-MemcmpTest -use_memcmp=0 -seed=4294967295 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+RUN: not LLVMFuzzer-MemcmpTest -seed=1 -runs=2000000 2>&1 | FileCheck %s
+RUN: not LLVMFuzzer-StrncmpTest -seed=1 -runs=2000000 2>&1 | FileCheck %s
+RUN: not LLVMFuzzer-StrcmpTest -seed=1 -runs=2000000 2>&1 | FileCheck %s
+RUN: not LLVMFuzzer-StrstrTest -seed=1 -runs=2000000 2>&1 | FileCheck %s
-RUN: not LLVMFuzzer-StrncmpTest -seed=2 -runs=100000 2>&1 | FileCheck %s
-RUN: LLVMFuzzer-StrncmpTest -use_memcmp=0 -seed=3 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
+RUN: not LLVMFuzzer-Memcmp64BytesTest -seed=1 -runs=1000000 2>&1 | FileCheck %s
-RUN: not LLVMFuzzer-StrcmpTest -seed=4 -runs=200000 2>&1 | FileCheck %s
-RUN: LLVMFuzzer-StrcmpTest -use_memcmp=0 -seed=5 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
-
-RUN: not LLVMFuzzer-StrstrTest -seed=6 -runs=200000 2>&1 | FileCheck %s
-RUN: LLVMFuzzer-StrstrTest -use_memmem=0 -seed=7 -runs=1000000 2>&1 | FileCheck %s --check-prefix=Done1000000
-
-RUN: LLVMFuzzer-RepeatedMemcmp -seed=10 -runs=100000 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT
+RUN: LLVMFuzzer-RepeatedMemcmp -seed=11 -runs=100000 2>&1 | FileCheck %s --check-prefix=RECOMMENDED_DICT
RECOMMENDED_DICT:###### Recommended dictionary. ######
RECOMMENDED_DICT-DAG: "foo"
RECOMMENDED_DICT-DAG: "bar"
RECOMMENDED_DICT:###### End of recommended dictionary. ######
-
diff --git a/lib/Fuzzer/test/fuzzer.test b/lib/Fuzzer/test/fuzzer.test
index 2f91c2195ca9..ff46d32b387d 100644
--- a/lib/Fuzzer/test/fuzzer.test
+++ b/lib/Fuzzer/test/fuzzer.test
@@ -11,7 +11,7 @@ MaxTotalTime: Done {{.*}} runs in {{.}} second(s)
RUN: not LLVMFuzzer-NullDerefTest 2>&1 | FileCheck %s --check-prefix=NullDerefTest
RUN: not LLVMFuzzer-NullDerefTest -close_fd_mask=3 2>&1 | FileCheck %s --check-prefix=NullDerefTest
-NullDerefTest: ERROR: AddressSanitizer: SEGV on unknown address
+NullDerefTest: ERROR: AddressSanitizer: {{SEGV|access-violation}} on unknown address
NullDerefTest: Test unit written to ./crash-
RUN: not LLVMFuzzer-NullDerefTest -artifact_prefix=ZZZ 2>&1 | FileCheck %s --check-prefix=NullDerefTestPrefix
NullDerefTestPrefix: Test unit written to ZZZcrash-
@@ -34,7 +34,7 @@ COUNTERS: BINGO
DISABLED: not LLVMFuzzer-UninstrumentedTest-Uninstrumented 2>&1 | FileCheck %s --check-prefix=UNINSTRUMENTED
UNINSTRUMENTED: ERROR: __sanitizer_set_death_callback is not defined. Exiting.
-RUN: not LLVMFuzzer-UninstrumentedTest-NoCoverage 2>&1 | FileCheck %s --check-prefix=NO_COVERAGE
+RUN: not LLVMFuzzer-NotinstrumentedTest-NoCoverage 2>&1 | FileCheck %s --check-prefix=NO_COVERAGE
NO_COVERAGE: ERROR: no interesting inputs were found. Is the code instrumented for coverage? Exiting
RUN: not LLVMFuzzer-BufferOverflowOnInput 2>&1 | FileCheck %s --check-prefix=OOB
@@ -51,7 +51,10 @@ RUN: LLVMFuzzer-SimpleTest -exit_on_src_pos=SimpleTest.cpp:17 2
RUN: LLVMFuzzer-ShrinkControlFlowTest -exit_on_src_pos=ShrinkControlFlowTest.cpp:23 2>&1 | FileCheck %s --check-prefix=EXIT_ON_SRC_POS
EXIT_ON_SRC_POS: INFO: found line matching '{{.*}}', exiting.
-RUN: ASAN_OPTIONS=strict_string_checks=1 not LLVMFuzzer-StrncmpOOBTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=STRNCMP
+RUN: env ASAN_OPTIONS=strict_string_checks=1 not LLVMFuzzer-StrncmpOOBTest -seed=1 -runs=1000000 2>&1 | FileCheck %s --check-prefix=STRNCMP
STRNCMP: AddressSanitizer: heap-buffer-overflow
STRNCMP-NOT: __sanitizer_weak_hook_strncmp
STRNCMP: in LLVMFuzzerTestOneInput
+
+RUN: not LLVMFuzzer-BogusInitializeTest 2>&1 | FileCheck %s --check-prefix=BOGUS_INITIALIZE
+BOGUS_INITIALIZE: argv[0] has been modified in LLVMFuzzerInitialize
diff --git a/lib/Fuzzer/test/lit.cfg b/lib/Fuzzer/test/lit.cfg
index 745af0c38245..85c95b42d1ea 100644
--- a/lib/Fuzzer/test/lit.cfg
+++ b/lib/Fuzzer/test/lit.cfg
@@ -6,6 +6,23 @@ config.test_format = lit.formats.ShTest(True)
config.suffixes = ['.test']
config.test_source_root = os.path.dirname(__file__)
+# Choose between lit's internal shell pipeline runner and a real shell. If
+# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
+use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
+if use_lit_shell:
+ # 0 is external, "" is default, and everything else is internal.
+ execute_external = (use_lit_shell == "0")
+else:
+ # Otherwise we default to internal on Windows and external elsewhere, as
+ # bash on Windows is usually very slow.
+ execute_external = (not sys.platform in ['win32'])
+
+# testFormat: The test format to use to interpret tests.
+#
+# For now we require '&&' between commands, until they get globally killed and
+# the test runner updated.
+config.test_format = lit.formats.ShTest(execute_external)
+
# Tweak PATH to include llvm tools dir and current exec dir.
llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
if (not llvm_tools_dir) or (not os.path.exists(llvm_tools_dir)):
@@ -20,6 +37,15 @@ if config.has_lsan:
else:
lit_config.note('lsan feature unavailable')
+if sys.platform.startswith('win') or sys.platform.startswith('cygwin'):
+ config.available_features.add('windows')
+
+if sys.platform.startswith('darwin'):
+ config.available_features.add('darwin')
+
+if config.is_posix:
+ config.available_features.add('posix')
+
if sys.platform.startswith('linux'):
# Note the value of ``sys.platform`` is not consistent
# between python 2 and 3, hence the use of ``.startswith()``.
diff --git a/lib/Fuzzer/test/lit.site.cfg.in b/lib/Fuzzer/test/lit.site.cfg.in
index 03e86c487ca9..069f2b72c0d9 100644
--- a/lib/Fuzzer/test/lit.site.cfg.in
+++ b/lib/Fuzzer/test/lit.site.cfg.in
@@ -1,4 +1,5 @@
config.test_exec_root = "@CMAKE_CURRENT_BINARY_DIR@"
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
config.has_lsan = True if @HAS_LSAN@ == 1 else False
+config.is_posix = @LIBFUZZER_POSIX@
lit_config.load_config(config, "@CMAKE_CURRENT_SOURCE_DIR@/lit.cfg")
diff --git a/lib/Fuzzer/test/merge-posix.test b/lib/Fuzzer/test/merge-posix.test
new file mode 100644
index 000000000000..47b90b986791
--- /dev/null
+++ b/lib/Fuzzer/test/merge-posix.test
@@ -0,0 +1,23 @@
+REQUIRES: posix
+
+RUN: rm -rf %tmp/T1 %tmp/T2
+RUN: mkdir -p %tmp/T1 %tmp/T2
+
+RUN: echo F..... > %tmp/T1/1
+RUN: echo .U.... > %tmp/T1/2
+RUN: echo ..Z... > %tmp/T1/3
+
+RUN: echo .....F > %tmp/T2/1
+RUN: echo ....U. > %tmp/T2/2
+RUN: echo ...Z.. > %tmp/T2/3
+RUN: echo ...Z.. > %tmp/T2/4
+RUN: echo ....E. > %tmp/T2/5
+RUN: echo .....R > %tmp/T2/6
+
+# Check that we can report an error if file size exceeded
+RUN: (ulimit -f 1; not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=SIGXFSZ)
+SIGXFSZ: ERROR: libFuzzer: file size exceeded
+
+# Check that we honor TMPDIR
+RUN: TMPDIR=DIR_DOES_NOT_EXIST not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=TMPDIR
+TMPDIR: MERGE-OUTER: failed to write to the control file: DIR_DOES_NOT_EXIST/libFuzzerTemp
diff --git a/lib/Fuzzer/test/merge-summary.test b/lib/Fuzzer/test/merge-summary.test
new file mode 100644
index 000000000000..df9d62dec636
--- /dev/null
+++ b/lib/Fuzzer/test/merge-summary.test
@@ -0,0 +1,15 @@
+RUN: rm -rf %t/T1 %t/T2
+RUN: mkdir -p %t/T0 %t/T1 %t/T2
+RUN: echo ...Z.. > %t/T2/1
+RUN: echo ....E. > %t/T2/2
+RUN: echo .....R > %t/T2/3
+RUN: echo F..... > %t/T2/a
+RUN: echo .U.... > %t/T2/b
+RUN: echo ..Z... > %t/T2/c
+
+RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -save_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=SAVE_SUMMARY
+SAVE_SUMMARY: MERGE-OUTER: writing coverage summary for 6 files to {{.*}}SUMMARY
+RUN: rm %t/T1/*
+RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %t/T1 %t/T2 -load_coverage_summary=%t/SUMMARY 2>&1 | FileCheck %s --check-prefix=LOAD_SUMMARY
+LOAD_SUMMARY: MERGE-OUTER: coverage summary loaded from {{.*}}SUMMAR
+LOAD_SUMMARY: MERGE-OUTER: 0 new files with 0 new features added
diff --git a/lib/Fuzzer/test/merge.test b/lib/Fuzzer/test/merge.test
index 5c7d30e41caa..e59da8c3e091 100644
--- a/lib/Fuzzer/test/merge.test
+++ b/lib/Fuzzer/test/merge.test
@@ -1,12 +1,13 @@
CHECK: BINGO
-RUN: rm -rf %tmp/T1 %tmp/T2
-RUN: mkdir -p %tmp/T1 %tmp/T2
-RUN: echo F..... > %tmp/T1/1
-RUN: echo .U.... > %tmp/T1/2
-RUN: echo ..Z... > %tmp/T1/3
+RUN: rm -rf %tmp/T0 %tmp/T1 %tmp/T2
+RUN: mkdir -p %tmp/T0 %tmp/T1 %tmp/T2
+RUN: echo F..... > %tmp/T0/1
+RUN: echo .U.... > %tmp/T0/2
+RUN: echo ..Z... > %tmp/T0/3
# T1 has 3 elements, T2 is empty.
+RUN: cp %tmp/T0/* %tmp/T1/
RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=CHECK1
CHECK1: MERGE-OUTER: 3 files, 3 in the initial corpus
CHECK1: MERGE-OUTER: 0 new files with 0 new features added
@@ -29,13 +30,15 @@ CHECK3: MERGE-OUTER: 12 files, 6 in the initial corpus
CHECK3: MERGE-OUTER: 0 new files with 0 new features added
# Check that we respect max_len during the merge and don't crash.
-RUN: rm %tmp/T1/??*
+RUN: rm %tmp/T1/*
+RUN: cp %tmp/T0/* %tmp/T1/
RUN: echo looooooooong > %tmp/T2/looooooooong
RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 -max_len=6 2>&1 | FileCheck %s --check-prefix=MAX_LEN
MAX_LEN: MERGE-OUTER: 3 new files
# Check that merge tolerates failures.
-RUN: rm %tmp/T1/??*
+RUN: rm %tmp/T1/*
+RUN: cp %tmp/T0/* %tmp/T1/
RUN: echo 'FUZZER' > %tmp/T2/FUZZER
RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=MERGE_WITH_CRASH
MERGE_WITH_CRASH: MERGE-OUTER: succesfull in 2 attempt(s)
@@ -45,10 +48,6 @@ MERGE_WITH_CRASH: MERGE-OUTER: 3 new files
RUN: LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 -max_len=5 2>&1 | FileCheck %s --check-prefix=MERGE_LEN5
MERGE_LEN5: MERGE-OUTER: succesfull in 1 attempt(s)
-# Check that we honor TMPDIR
-RUN: TMPDIR=DIR_DOES_NOT_EXIST not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=TMPDIR
-TMPDIR: MERGE-OUTER: failed to write to the control file: DIR_DOES_NOT_EXIST/libFuzzerTemp
-
-# Check that we can report an error if file size exceeded
-RUN: (ulimit -f 1; not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=SIGXFSZ)
-SIGXFSZ: ERROR: libFuzzer: file size exceeded
+RUN: rm -rf %tmp/T1/* %tmp/T2/*
+RUN: not LLVMFuzzer-FullCoverageSetTest -merge=1 %tmp/T1 %tmp/T2 2>&1 | FileCheck %s --check-prefix=EMPTY
+EMPTY: MERGE-OUTER: zero succesfull attempts, exiting
diff --git a/lib/Fuzzer/test/minimize_crash.test b/lib/Fuzzer/test/minimize_crash.test
index 7e5406598e4a..5643c6bacb09 100644
--- a/lib/Fuzzer/test/minimize_crash.test
+++ b/lib/Fuzzer/test/minimize_crash.test
@@ -1,6 +1,13 @@
RUN: echo 'Hi!rv349f34t3gg' > not_minimal_crash
RUN: LLVMFuzzer-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 2>&1 | FileCheck %s
-CHECK: CRASH_MIN: failed to minimize beyond minimized-from-{{.*}} (3 bytes), exiting
+CHECK: CRASH_MIN: failed to minimize beyond ./minimized-from-{{.*}} (3 bytes), exiting
RUN: LLVMFuzzer-NullDerefTest -minimize_crash=1 not_minimal_crash -max_total_time=2 -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=CHECK_EXACT
CHECK_EXACT: CRASH_MIN: failed to minimize beyond exact_minimized_path (3 bytes), exiting
RUN: rm not_minimal_crash minimized-from-* exact_minimized_path
+
+RUN: echo -n 'abcd*xyz' > not_minimal_crash
+RUN: LLVMFuzzer-SingleByteInputTest -minimize_crash=1 not_minimal_crash -exact_artifact_path=exact_minimized_path 2>&1 | FileCheck %s --check-prefix=MIN1
+MIN1: Test unit written to exact_minimized_path
+MIN1: Test unit written to exact_minimized_path
+MIN1: INFO: The input is small enough, exiting
+MIN1: CRASH_MIN: failed to minimize beyond exact_minimized_path (1 bytes), exiting
diff --git a/lib/Fuzzer/test/minimize_two_crashes.test b/lib/Fuzzer/test/minimize_two_crashes.test
new file mode 100644
index 000000000000..2358d8c2a92e
--- /dev/null
+++ b/lib/Fuzzer/test/minimize_two_crashes.test
@@ -0,0 +1,16 @@
+# Test that the minimizer stops when it sees a differe bug.
+
+RUN: rm -rf %t && mkdir %t
+RUN: echo H12345678901234667888090 > %t/long_crash
+RUN: env ASAN_OPTIONS=dedup_token_length=3 LLVMFuzzer-TwoDifferentBugsTest -seed=1 -minimize_crash=1 %t/long_crash -exact_artifact_path=%t/result 2>&1 | FileCheck %s
+
+CHECK: DedupToken1: DEDUP_TOKEN: Bar
+CHECK: DedupToken2: DEDUP_TOKEN: Bar
+CHECK: DedupToken1: DEDUP_TOKEN: Bar
+CHECK: DedupToken2: DEDUP_TOKEN: Foo
+CHECK: CRASH_MIN: mismatch in dedup tokens
+
+RUN: not LLVMFuzzer-TwoDifferentBugsTest %t/result 2>&1 | FileCheck %s --check-prefix=VERIFY
+
+VERIFY: ERROR: AddressSanitizer:
+VERIFY: in Bar
diff --git a/lib/Fuzzer/test/no-coverage/CMakeLists.txt b/lib/Fuzzer/test/no-coverage/CMakeLists.txt
index d2f6f438ad79..52e7240333ee 100644
--- a/lib/Fuzzer/test/no-coverage/CMakeLists.txt
+++ b/lib/Fuzzer/test/no-coverage/CMakeLists.txt
@@ -5,7 +5,7 @@ set(CMAKE_CXX_FLAGS
"${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard")
set(NoCoverageTests
- UninstrumentedTest
+ NotinstrumentedTest
)
foreach(Test ${NoCoverageTests})
@@ -16,14 +16,14 @@ endforeach()
###############################################################################
# AFL Driver test
###############################################################################
+if(NOT MSVC)
+ add_executable(AFLDriverTest
+ ../AFLDriverTest.cpp ../../afl/afl_driver.cpp)
-add_executable(AFLDriverTest
- ../AFLDriverTest.cpp ../../afl/afl_driver.cpp)
+ set_target_properties(AFLDriverTest
+ PROPERTIES RUNTIME_OUTPUT_DIRECTORY
+ "${CMAKE_BINARY_DIR}/lib/Fuzzer/test"
+ )
-set_target_properties(AFLDriverTest
- PROPERTIES RUNTIME_OUTPUT_DIRECTORY
- "${CMAKE_BINARY_DIR}/lib/Fuzzer/test"
- )
-
-# Propagate value into parent directory
-set(TestBinaries ${TestBinaries} AFLDriverTest PARENT_SCOPE)
+ add_dependencies(TestBinaries AFLDriverTest)
+endif()
diff --git a/lib/Fuzzer/test/trace-malloc-2.test b/lib/Fuzzer/test/trace-malloc-2.test
new file mode 100644
index 000000000000..7719b650c791
--- /dev/null
+++ b/lib/Fuzzer/test/trace-malloc-2.test
@@ -0,0 +1,8 @@
+// FIXME: This test infinite loops on darwin because it crashes
+// printing a stack trace repeatedly
+UNSUPPORTED: darwin
+
+RUN: LLVMFuzzer-TraceMallocTest -seed=1 -trace_malloc=2 -runs=1000 2>&1 | FileCheck %s --check-prefix=TRACE2
+TRACE2-DAG: FREE[0]
+TRACE2-DAG: MALLOC[0]
+TRACE2-DAG: in LLVMFuzzerTestOneInput
diff --git a/lib/Fuzzer/test/trace-malloc.test b/lib/Fuzzer/test/trace-malloc.test
index c95147904d42..25694cc2de5c 100644
--- a/lib/Fuzzer/test/trace-malloc.test
+++ b/lib/Fuzzer/test/trace-malloc.test
@@ -3,8 +3,3 @@ CHECK-DAG: MallocFreeTracer: STOP 0 0 (same)
CHECK-DAG: MallocFreeTracer: STOP 0 1 (DIFFERENT)
CHECK-DAG: MallocFreeTracer: STOP 1 0 (DIFFERENT)
CHECK-DAG: MallocFreeTracer: STOP 1 1 (same)
-
-RUN: LLVMFuzzer-TraceMallocTest -seed=1 -trace_malloc=2 -runs=1000 2>&1 | FileCheck %s --check-prefix=TRACE2
-TRACE2-DAG: FREE[0]
-TRACE2-DAG: MALLOC[0]
-TRACE2-DAG: in LLVMFuzzerTestOneInput
diff --git a/lib/Fuzzer/test/trace-pc.test b/lib/Fuzzer/test/trace-pc.test
new file mode 100644
index 000000000000..3709677b71b6
--- /dev/null
+++ b/lib/Fuzzer/test/trace-pc.test
@@ -0,0 +1,2 @@
+CHECK: BINGO
+RUN: LLVMFuzzer-SimpleTest-TracePC -runs=100000 -seed=1 2>&1 | FileCheck %s
diff --git a/lib/Fuzzer/test/trace-pc/CMakeLists.txt b/lib/Fuzzer/test/trace-pc/CMakeLists.txt
new file mode 100644
index 000000000000..e800f82cc5dc
--- /dev/null
+++ b/lib/Fuzzer/test/trace-pc/CMakeLists.txt
@@ -0,0 +1,13 @@
+# These tests are not instrumented with coverage and don't
+# have coverage rt in the binary.
+
+set(CMAKE_CXX_FLAGS
+ "${LIBFUZZER_FLAGS_BASE} -fno-sanitize-coverage=edge,trace-cmp,indirect-calls,8bit-counters,trace-pc-guard -fsanitize-coverage=trace-pc")
+
+set(TracePCTests
+ SimpleTest
+ )
+
+foreach(Test ${TracePCTests})
+ add_libfuzzer_test(${Test}-TracePC SOURCES ../${Test}.cpp)
+endforeach()
diff --git a/lib/Fuzzer/test/ubsan/CMakeLists.txt b/lib/Fuzzer/test/ubsan/CMakeLists.txt
index 7a9eacdbe7df..55e0a118186b 100644
--- a/lib/Fuzzer/test/ubsan/CMakeLists.txt
+++ b/lib/Fuzzer/test/ubsan/CMakeLists.txt
@@ -10,6 +10,3 @@ set(UbsanTests
foreach(Test ${UbsanTests})
add_libfuzzer_test(${Test}-Ubsan SOURCES ../${Test}.cpp)
endforeach()
-
-# Propagate value into parent directory
-set(TestBinaries ${TestBinaries} PARENT_SCOPE)
diff --git a/lib/Fuzzer/test/ulimit.test b/lib/Fuzzer/test/ulimit.test
index a60636c351bd..c2faca13f728 100644
--- a/lib/Fuzzer/test/ulimit.test
+++ b/lib/Fuzzer/test/ulimit.test
@@ -1,2 +1,4 @@
+REQUIRES: posix
+
RUN: ulimit -s 1000
RUN: LLVMFuzzer-SimpleTest
diff --git a/lib/Fuzzer/test/uninstrumented/CMakeLists.txt b/lib/Fuzzer/test/uninstrumented/CMakeLists.txt
index 29b66e6e586a..f4ab59e5b18d 100644
--- a/lib/Fuzzer/test/uninstrumented/CMakeLists.txt
+++ b/lib/Fuzzer/test/uninstrumented/CMakeLists.txt
@@ -11,6 +11,3 @@ set(UninstrumentedTests
foreach(Test ${UninstrumentedTests})
add_libfuzzer_test(${Test}-Uninstrumented SOURCES ../${Test}.cpp)
endforeach()
-
-# Propagate value into parent directory
-set(TestBinaries ${TestBinaries} PARENT_SCOPE)
diff --git a/lib/Fuzzer/test/value-profile-div.test b/lib/Fuzzer/test/value-profile-div.test
index ba45e4129d30..b966a8916512 100644
--- a/lib/Fuzzer/test/value-profile-div.test
+++ b/lib/Fuzzer/test/value-profile-div.test
@@ -1,3 +1,3 @@
-CHECK: AddressSanitizer: FPE
+CHECK: AddressSanitizer: {{FPE|int-divide-by-zero}}
RUN: not LLVMFuzzer-DivTest -seed=1 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/lib/Fuzzer/test/value-profile-mem.test b/lib/Fuzzer/test/value-profile-mem.test
index 09d737dbe736..880b2692910a 100644
--- a/lib/Fuzzer/test/value-profile-mem.test
+++ b/lib/Fuzzer/test/value-profile-mem.test
@@ -1,2 +1,2 @@
CHECK: BINGO
-RUN: not LLVMFuzzer-SingleMemcmpTest -seed=1 -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
+RUN: not LLVMFuzzer-SingleMemcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/lib/Fuzzer/test/value-profile-strcmp.test b/lib/Fuzzer/test/value-profile-strcmp.test
index 1e7ef9b45e96..7f1047594548 100644
--- a/lib/Fuzzer/test/value-profile-strcmp.test
+++ b/lib/Fuzzer/test/value-profile-strcmp.test
@@ -1,2 +1,2 @@
CHECK: BINGO
-RUN: not LLVMFuzzer-SingleStrcmpTest -seed=1 -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
+RUN: not LLVMFuzzer-SingleStrcmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
diff --git a/lib/Fuzzer/test/value-profile-strncmp.test b/lib/Fuzzer/test/value-profile-strncmp.test
index 650973180c06..84a74c4f0ad2 100644
--- a/lib/Fuzzer/test/value-profile-strncmp.test
+++ b/lib/Fuzzer/test/value-profile-strncmp.test
@@ -1,2 +1,2 @@
CHECK: BINGO
-RUN: not LLVMFuzzer-SingleStrncmpTest -seed=1 -use_cmp=0 -use_memcmp=0 -use_value_profile=1 -runs=10000000 2>&1 | FileCheck %s
+RUN: not LLVMFuzzer-SingleStrncmpTest -seed=1 -use_cmp=0 -use_value_profile=1 -runs=100000000 2>&1 | FileCheck %s