Skip to content

Commit d9fa84a

Browse files
authored
Fuzzer: Adjust parameters by input size, sometimes (#7276)
Rather than always have a fixed max of heap types, globals, etc. allow more if the input size is large. This adds variety. There is a cost to this variety, we go from 0.89% ignored runs to 1.1% (that is, slightly more runs contain something that prevents us from doing the work we want, like hitting a host limitation or seeing the testcase just traps). This increase seems small enough to be reasonable, and we only do this half the time, so the old behavior is still being tested at half throughput.
1 parent 32b7a25 commit d9fa84a

5 files changed

Lines changed: 165 additions & 117 deletions

File tree

src/tools/fuzzing/fuzzing.cpp

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ TranslateToFuzzReader::TranslateToFuzzReader(Module& wasm,
3636
: wasm(wasm), closedWorld(closedWorld), builder(wasm),
3737
random(std::move(input), wasm.features) {
3838

39-
// Half the time add no unreachable code so that we'll execute the most code
40-
// as possible with no early exits.
41-
allowAddingUnreachableCode = oneIn(2);
42-
4339
// - funcref cannot be logged because referenced functions can be inlined or
4440
// removed during optimization
4541
// - there's no point in logging anyref because it is opaque
@@ -49,7 +45,53 @@ TranslateToFuzzReader::TranslateToFuzzReader(Module& wasm,
4945
loggableTypes.push_back(Type::v128);
5046
}
5147

48+
// Setup params. Start with the defaults.
5249
globalParams = std::make_unique<FuzzParamsContext>(*this);
50+
51+
// Some of the time, adjust parameters based on the size, e.g. allowing more
52+
// heap types in larger inputs, etc.
53+
if (random.oneIn(2)) {
54+
// A typical random wasm input from fuzz_opt.py is fairly large (to minimize
55+
// the process creation overhead of all the things we run from python), and
56+
// the defaults are tuned to that. This corresponds to INPUT_SIZE_MEAN in
57+
// scripts/fuzz_opt.py
58+
const double MEAN_SIZE = 40 * 1024;
59+
60+
// As we have not read anything from the input, the remaining size is its
61+
// size.
62+
double size = random.remaining();
63+
auto ratio = size / MEAN_SIZE;
64+
65+
auto bits = random.get();
66+
if (bits & 1) {
67+
fuzzParams->MAX_NEW_GC_TYPES *= ratio;
68+
}
69+
if (bits & 2) {
70+
fuzzParams->MAX_GLOBALS *= ratio;
71+
}
72+
if (bits & 4) {
73+
// Only adjust the limit if there is one.
74+
if (fuzzParams->HANG_LIMIT) {
75+
fuzzParams->HANG_LIMIT *= ratio;
76+
// There is a limit, so keep it non-zero to actually prevent hangs.
77+
fuzzParams->HANG_LIMIT = std::max(fuzzParams->HANG_LIMIT, 1);
78+
}
79+
}
80+
if (bits & 8) {
81+
// Only increase the number of tries. Trying fewer times does not help
82+
// find more interesting patterns.
83+
if (ratio > 1) {
84+
fuzzParams->TRIES *= ratio;
85+
}
86+
}
87+
if (bits & 16) {
88+
fuzzParams->MAX_ARRAY_SIZE *= ratio;
89+
}
90+
}
91+
92+
// Half the time add no unreachable code so that we'll execute the most code
93+
// as possible with no early exits.
94+
allowAddingUnreachableCode = oneIn(2);
5395
}
5496

5597
TranslateToFuzzReader::TranslateToFuzzReader(Module& wasm,

src/tools/fuzzing/random.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ class Random {
6363

6464
bool finished() { return finishedInput; }
6565

66+
// How many bytes of data remain to be used.
67+
size_t remaining() {
68+
if (finishedInput) {
69+
// We finished it and are cycling through it again (using xorFactor to try
70+
// to improve the entropy).
71+
return 0;
72+
}
73+
return bytes.size() - pos;
74+
}
75+
6676
// Pick from a vector-like container
6777
template<typename T> const typename T::value_type& pick(const T& vec) {
6878
assert(!vec.empty());
Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,35 @@
11
Metrics
22
total
3-
[exports] : 84
4-
[funcs] : 115
5-
[globals] : 18
6-
[imports] : 4
3+
[exports] : 24
4+
[funcs] : 30
5+
[globals] : 21
6+
[imports] : 5
77
[memories] : 1
8-
[memory-data] : 24
9-
[table-data] : 49
8+
[memory-data] : 5
9+
[table-data] : 8
1010
[tables] : 1
1111
[tags] : 0
12-
[total] : 10300
13-
[vars] : 325
14-
Binary : 679
15-
Block : 1736
16-
Break : 323
17-
Call : 340
18-
CallIndirect : 93
19-
Const : 1686
20-
Drop : 129
21-
GlobalGet : 882
22-
GlobalSet : 665
23-
If : 581
24-
Load : 146
25-
LocalGet : 738
26-
LocalSet : 614
27-
Loop : 211
28-
Nop : 156
29-
RefFunc : 49
30-
Return : 111
31-
Select : 67
32-
Store : 83
33-
Switch : 1
34-
Unary : 680
35-
Unreachable : 330
12+
[total] : 3231
13+
[vars] : 112
14+
Binary : 266
15+
Block : 529
16+
Break : 115
17+
Call : 122
18+
CallIndirect : 3
19+
Const : 529
20+
Drop : 31
21+
GlobalGet : 271
22+
GlobalSet : 190
23+
If : 181
24+
Load : 58
25+
LocalGet : 233
26+
LocalSet : 177
27+
Loop : 65
28+
Nop : 59
29+
RefFunc : 8
30+
Return : 31
31+
Select : 16
32+
Store : 29
33+
Switch : 4
34+
Unary : 220
35+
Unreachable : 94
Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,34 @@
11
Metrics
22
total
3-
[exports] : 46
4-
[funcs] : 62
5-
[globals] : 17
3+
[exports] : 39
4+
[funcs] : 53
5+
[globals] : 7
66
[imports] : 4
77
[memories] : 1
8-
[memory-data] : 11
9-
[table-data] : 11
8+
[memory-data] : 29
9+
[table-data] : 24
1010
[tables] : 1
1111
[tags] : 0
12-
[total] : 4599
13-
[vars] : 195
14-
Binary : 353
15-
Block : 753
16-
Break : 106
17-
Call : 195
18-
CallIndirect : 39
19-
Const : 776
20-
Drop : 77
21-
GlobalGet : 381
22-
GlobalSet : 299
23-
If : 220
24-
Load : 83
25-
LocalGet : 346
26-
LocalSet : 266
27-
Loop : 83
28-
Nop : 46
29-
RefFunc : 11
30-
Return : 67
31-
Select : 20
32-
Store : 33
33-
Switch : 2
34-
Unary : 299
35-
Unreachable : 144
12+
[total] : 4272
13+
[vars] : 162
14+
Binary : 328
15+
Block : 670
16+
Break : 131
17+
Call : 194
18+
CallIndirect : 38
19+
Const : 764
20+
Drop : 65
21+
GlobalGet : 364
22+
GlobalSet : 260
23+
If : 219
24+
Load : 80
25+
LocalGet : 299
26+
LocalSet : 209
27+
Loop : 77
28+
Nop : 41
29+
RefFunc : 24
30+
Return : 32
31+
Select : 34
32+
Store : 28
33+
Unary : 284
34+
Unreachable : 131
Lines changed: 51 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,58 @@
11
Metrics
22
total
3-
[exports] : 9
4-
[funcs] : 8
5-
[globals] : 1
6-
[imports] : 11
3+
[exports] : 21
4+
[funcs] : 26
5+
[globals] : 4
6+
[imports] : 12
77
[memories] : 1
8-
[memory-data] : 112
9-
[table-data] : 0
8+
[memory-data] : 17
9+
[table-data] : 4
1010
[tables] : 2
11-
[tags] : 0
12-
[total] : 738
13-
[vars] : 40
14-
ArrayCopy : 1
15-
ArrayFill : 1
16-
ArrayLen : 3
17-
ArrayNew : 5
18-
ArrayNewFixed : 1
19-
AtomicFence : 2
11+
[tags] : 3
12+
[total] : 960
13+
[vars] : 45
14+
ArrayNew : 1
15+
ArrayNewFixed : 9
2016
AtomicNotify : 2
21-
AtomicRMW : 1
22-
Binary : 82
23-
Block : 80
24-
BrOn : 4
25-
Break : 13
26-
Call : 29
27-
CallRef : 1
28-
Const : 134
17+
Binary : 93
18+
Block : 156
19+
BrOn : 2
20+
Break : 5
21+
Call : 55
22+
CallIndirect : 1
23+
Const : 173
24+
DataDrop : 1
2925
Drop : 15
30-
GlobalGet : 26
31-
GlobalSet : 26
32-
I31Get : 3
33-
If : 26
34-
Load : 16
35-
LocalGet : 85
36-
LocalSet : 51
37-
Loop : 6
38-
MemoryFill : 2
39-
Nop : 5
40-
Pop : 4
41-
RefAs : 10
42-
RefEq : 1
43-
RefFunc : 2
44-
RefI31 : 12
45-
RefIsNull : 1
46-
RefNull : 7
47-
RefTest : 2
48-
Return : 4
49-
SIMDExtract : 7
50-
Select : 7
51-
Store : 1
52-
StringConst : 3
53-
StringEncode : 2
54-
StringMeasure : 1
55-
StructGet : 2
56-
StructNew : 2
57-
StructSet : 2
58-
Try : 6
26+
GlobalGet : 77
27+
GlobalSet : 70
28+
If : 40
29+
Load : 17
30+
LocalGet : 48
31+
LocalSet : 24
32+
Loop : 10
33+
MemoryFill : 1
34+
MemoryInit : 1
35+
Nop : 12
36+
Pop : 2
37+
RefEq : 2
38+
RefFunc : 4
39+
RefI31 : 3
40+
RefNull : 9
41+
RefTest : 1
42+
Return : 6
43+
SIMDExtract : 4
44+
Select : 2
45+
Store : 3
46+
StringConst : 8
47+
StringEncode : 1
48+
StringEq : 1
49+
StringWTF16Get : 1
50+
StructNew : 4
51+
TableSet : 1
52+
Throw : 4
53+
Try : 1
5954
TryTable : 5
60-
Unary : 24
61-
Unreachable : 13
55+
TupleExtract : 1
56+
TupleMake : 3
57+
Unary : 45
58+
Unreachable : 36

0 commit comments

Comments
 (0)