| // 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 will validate operations in the new file |
| // system in a multi-threaded setting. |
| // Current Status: Work in Progress. See |
| // https://github.com/emscripten-core/emscripten/issues/15041. |
| |
| #include "random.h" |
| #include "support/command-line.h" |
| #include "workload.h" |
| #include <cstdlib> |
| #include <iostream> |
| #include <optional> |
| #include <pthread.h> |
| #include <random> |
| #include <stdlib.h> |
| #include <string> |
| #include <unistd.h> |
| #include "parameters.h" |
| |
| // 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<uint64_t>{}(rand); |
| } |
| |
| struct Fuzzer { |
| void run(uint64_t seed) { |
| RandEngine getRand(seed); |
| printf("Running with seed: %llu\n", seed); |
| |
| std::vector<char> 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<uint64_t> 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; |
| } |