From 0e068c386ef1588c09e57a4d081be626d83bc31c Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Fri, 30 Nov 2018 09:54:57 -0800 Subject: Fuzzing: log values during execution (#1779) Before we just looked at function return values when looking for differences before and after running some passes, while fuzzing. This adds logging of values during execution, which can represent control flow, monitor locals, etc., giving a lot more opportunities for the fuzzer to find problems. Also: * Clean up the sigToFunctionType function, which allocated a struct and returned it. This makes it safer by returning the struct by value, which is also easier to use in this PR. * Fix printing of imported function calls without a function type - turns out we always generate function types in loading, so we didn't notice this was broken, but this new fuzzer feature hit it. --- src/tools/fuzzing.h | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'src/tools/fuzzing.h') diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 3b1a418b5..7954229c7 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -128,6 +128,7 @@ public: setupMemory(); setupTable(); setupGlobals(); + addImportLoggingSupport(); // keep adding functions until we run out of input while (!finishedInput) { auto* func = addFunction(); @@ -184,10 +185,13 @@ private: // Whether to emit atomic waits (which in single-threaded mode, may hang...) static const bool ATOMIC_WAITS = false; - // after we finish the input, we start going through it again, but xoring + // After we finish the input, we start going through it again, but xoring // so it's not identical int xorFactor = 0; + // The chance to emit a logging operation for a none expression. We + // randomize this in each function. + unsigned LOGGING_PERCENT = 0; void readData(std::vector input) { bytes.swap(input); @@ -300,6 +304,19 @@ private: wasm.addExport(export_); } + void addImportLoggingSupport() { + for (auto type : { i32, i64, f32, f64 }) { + auto* func = new Function; + Name name = std::string("log-") + printType(type); + func->name = name; + func->module = "fuzzing-support"; + func->base = name; + func->params.push_back(type); + func->result = none; + wasm.addFunction(func); + } + } + Expression* makeHangLimitCheck() { return builder.makeSequence( builder.makeIf( @@ -364,6 +381,7 @@ private: std::map> typeLocals; // type => list of locals with that type Function* addFunction() { + LOGGING_PERCENT = upToSquared(100); Index num = wasm.functions.size(); func = new Function; func->name = std::string("func_") + std::to_string(num); @@ -711,6 +729,8 @@ private: Expression* _makenone() { auto choice = upTo(100); + if (choice < LOGGING_PERCENT) return makeLogging(); + choice = upTo(100); if (choice < 50) return makeSetLocal(none); if (choice < 60) return makeBlock(none); if (choice < 70) return makeIf(none); @@ -1496,6 +1516,13 @@ private: } } + // special makers + + Expression* makeLogging() { + auto type = pick(i32, i64, f32, f64); + return builder.makeCall(std::string("log-") + printType(type), { make(type) }, none); + } + // special getters Type getType() { -- cgit v1.2.3