[libFuzzer] tweam use_feature_frequency to be less aggressive; run a dummy input before the seed corpus

llvm-svn: 315657
This commit is contained in:
Kostya Serebryany 2017-10-13 01:12:23 +00:00
parent 3da37e05f7
commit 51823d3aae
4 changed files with 26 additions and 11 deletions

View File

@ -220,9 +220,11 @@ class InputCorpus {
return FeatureFrequency[Idx % kFeatureSetSize];
}
void UpdateFeatureFrequencyScore(InputInfo *II) {
II->FeatureFrequencyScore = 0.00000001;
const float kMin = 0.01, kMax = 100.;
II->FeatureFrequencyScore = kMin;
for (auto Idx : II->UniqFeatureSet)
II->FeatureFrequencyScore += 1. / (GetFeatureFrequency(Idx) + 1.);
II->FeatureFrequencyScore = Min(II->FeatureFrequencyScore, kMax);
}
size_t NumFeatures() const { return NumAddedFeatures; }
@ -261,8 +263,20 @@ private:
Weights.resize(N);
std::iota(Intervals.begin(), Intervals.end(), 0);
for (size_t i = 0; i < N; i++)
Weights[i] =
Inputs[i]->NumFeatures * (i + 1) * Inputs[i]->FeatureFrequencyScore;
Weights[i] = Inputs[i]->NumFeatures
? (i + 1) * Inputs[i]->FeatureFrequencyScore
: 0.;
if (FeatureDebug) {
for (size_t i = 0; i < N; i++)
Printf("%zd ", Inputs[i]->NumFeatures);
Printf("NUM\n");
for (size_t i = 0; i < N; i++)
Printf("%f ", Inputs[i]->FeatureFrequencyScore);
Printf("SCORE\n");
for (size_t i = 0; i < N; i++)
Printf("%f ", Weights[i]);
Printf("Weights\n");
}
CorpusDistribution = std::piecewise_constant_distribution<double>(
Intervals.begin(), Intervals.end(), Weights.begin());
}

View File

@ -621,6 +621,10 @@ void Fuzzer::ReadAndExecuteSeedCorpora(const Vector<std::string> &CorpusDirs) {
SetMaxInputLen(std::min(std::max(kMinDefaultLen, MaxSize), kMaxSaneLen));
assert(MaxInputLen > 0);
// Test the callback with empty input and never try it again.
uint8_t dummy = 0;
ExecuteCallback(&dummy, 0);
if (SizedFiles.empty()) {
Printf("INFO: A corpus is not provided, starting from an empty corpus\n");
Unit U({'\n'}); // Valid ASCII input.
@ -648,9 +652,6 @@ void Fuzzer::ReadAndExecuteSeedCorpora(const Vector<std::string> &CorpusDirs) {
}
}
// Test the callback with empty input and never try it again.
uint8_t dummy;
ExecuteCallback(&dummy, 0);
PrintStats("INITED");
if (Corpus.empty()) {

View File

@ -28,5 +28,5 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
for (auto Flag : Flags)
fprintf(stderr, "%s ", Flag.c_str());
fprintf(stderr, "\n");
exit(0);
return 0;
}

View File

@ -1,19 +1,19 @@
RUN: %cpp_compiler %S/FlagsTest.cpp -o %t-FlagsTest
RUN: not %t-FlagsTest -foo_bar=1 2>&1 | FileCheck %s --check-prefix=FOO_BAR
RUN: %t-FlagsTest -runs=10 -foo_bar=1 2>&1 | FileCheck %s --check-prefix=FOO_BAR
FOO_BAR: WARNING: unrecognized flag '-foo_bar=1'; use -help=1 to list all flags
FOO_BAR: BINGO
RUN: not %t-FlagsTest -runs=10 --max_len=100 2>&1 | FileCheck %s --check-prefix=DASH_DASH
RUN: %t-FlagsTest -runs=10 --max_len=100 2>&1 | FileCheck %s --check-prefix=DASH_DASH
DASH_DASH: WARNING: did you mean '-max_len=100' (single dash)?
DASH_DASH: INFO: A corpus is not provided, starting from an empty corpus
RUN: %t-FlagsTest -help=1 2>&1 | FileCheck %s --check-prefix=NO_INTERNAL
NO_INTERNAL-NOT: internal flag
RUN: not %t-FlagsTest --foo-bar -runs=10 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU
RUN: %t-FlagsTest --foo-bar -runs=10 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU
PASSTHRU: BINGO --foo-bar --baz -help=1 test
RUN: mkdir -p %t/T0 %t/T1
RUN: echo z > %t/T1/z
RUN: not %t-FlagsTest --foo-bar -merge=1 %t/T0 %t/T1 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU-MERGE
RUN: %t-FlagsTest -runs=10 --foo-bar -merge=1 %t/T0 %t/T1 -ignore_remaining_args=1 --baz -help=1 test 2>&1 | FileCheck %s --check-prefix=PASSTHRU-MERGE
PASSTHRU-MERGE: BINGO --foo-bar --baz -help=1 test