[fuzzing] better fallback rng (#35621)

`ProtoBitGen` provides a random number generator that returns values directly from fuzzer selected values, which allows us to test-into random selection algorithms deterministically.

Since the list of values provided by the fuzzer is limited, we need a fallback implementation. Previously we'd used something that was very correlated, and some of the distribution algorithms get into a very slow convergence mode when we do that (so we repeatedly return the same value for billions of iterations and cause timeouts in fuzzers).

Instead, when we run out of fuzzer supplied values, seed an mt19937 generator with the fuzzer selected values and use that from there on. Said generator will then produce values deterministically (for a given fuzzer input), but with a better distribution to allow convergence for fiddly algorithms.

Closes #35621

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35621 from ctiller:cg-timeout 6c9ef9cac5
PiperOrigin-RevId: 600607424
pull/35634/head
Craig Tiller 1 year ago committed by Copybara-Service
parent 6dc928c98c
commit 562bc9b363
  1. 3
      test/core/transport/test_suite/corpus/chaotic_good/5033076095254528
  2. 17
      test/core/util/proto_bit_gen.h

@ -0,0 +1,3 @@
test_id: 637599745
fixture_id: 262144
rng: 18446744073709551614

@ -21,6 +21,7 @@
#include <cstdint>
#include <limits>
#include <random>
#include <vector>
namespace grpc_core {
@ -39,21 +40,19 @@ class ProtoBitGen : public std::numeric_limits<uint64_t> {
using result_type = uint64_t;
uint64_t operator()() {
if (results_.empty()) {
++current_;
return current_;
if (current_ < results_.size()) {
return results_[current_++];
}
// We loop through but increment by one each round, to guarantee to see all
// values eventually.
uint64_t out =
results_[current_ % results_.size()] + (current_ / results_.size());
++current_;
return out;
return generator_();
}
private:
std::vector<uint64_t> results_;
size_t current_ = 0;
std::mt19937_64 generator_ = [this]() {
std::seed_seq seq(results_.begin(), results_.end());
return std::mt19937_64(seq);
}();
};
} // namespace grpc_core

Loading…
Cancel
Save