// Copyright 2021 The Emscripten Authors. All rights reserved. // Emscripten is available under two separate licenses, the MIT license and the // University of Illinois/NCSA Open Source License. Both these licenses can be // found in the LICENSE file. // This file defines a fuzzer that validates operations in a multi-threaded // setting. #include "parameters.h" #include "random.h" #include "support/command-line.h" #include "workload.h" #include #include #include #include #include #include #include #include // Used to define the size of the bytes to seed the Random object. #define NUM_RAND_BYTES 4096 namespace wasmfs { using RandEngine = std::mt19937_64; bool VERBOSE = false; uint64_t getSeed() { // Return a (truly) random 64-bit value. std::random_device rand; return std::uniform_int_distribution{}(rand); } struct Fuzzer { void run(uint64_t seed) { RandEngine getRand(seed); printf("Running with seed: %llu\n", seed); std::vector bytes(NUM_RAND_BYTES); for (size_t i = 0; i < bytes.size(); i += sizeof(uint64_t)) { *(uint64_t*)(bytes.data() + i) = getRand(); } Random rand(std::move(bytes)); // Create a workload with the Random seed. auto workload = ReadWrite(rand); workload.execute(); } }; } // namespace wasmfs int main(int argc, const char* argv[]) { using namespace wasmfs; Options options("wasmfs-fuzzer", "Fuzz multi-threaded WasmFS operations"); std::optional seed; options.add("--seed", "", "Run a single workload generated by the given seed", Options::Arguments::One, [&](Options*, const std::string& arg) { seed = uint64_t(std::stoull(arg)); }); options.add("--verbose", "-v", "Run with verbose logging", Options::Arguments::Zero, [&](Options*, const std::string& arg) { VERBOSE = true; }); options.parse(argc, argv); Fuzzer fuzzer; if (seed) { fuzzer.run(*seed); } else { size_t i = 0; RandEngine nextSeed(getSeed()); while (true) { printf("Iteration %zu \n", ++i); printf("Seed %llu \n", getSeed()); fuzzer.run(nextSeed()); } } return 0; }