improve CI build times by limiting runs#337
Conversation
bertschneider
left a comment
There was a problem hiding this comment.
Strange, any idea why it differs so much?
|
@bertschneider From what I can observe locally is that setting a seed x on Linux produces somewhat different behavior compared to setting the same seed on Windows.. In the mentioned example and the current seed, on Linux the fuzzing behavior in over 20 test runs roughly follows the pattern of: On Windows, the behavior is a lot more "random" as in it can produce a similar output but also tends to completely end up with other mutators, or in other cases fails to find the necessary coverage from Bottom line, setting a seed (in libfuzzer) is not a guarantee for 100% deterministic behavior (across different systems and/or operating systems)? I tried checking if there's a difference in PRNG that is being used, but at first glance it doesn't look like it: Ripping out the used PRNG as a standalone test produced the same random numbers over 100 iterations: // clang++ test.cpp -O3 -o test
// ./test 111994470
#include <cstdlib>
#include <iostream>
#include <random>
#include <stdlib.h>
#include <string>
class Random : public std::minstd_rand {
public:
Random(unsigned int seed) : std::minstd_rand(seed) {}
result_type operator()() { return this->std::minstd_rand::operator()(); }
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type Rand() {
return static_cast<T>(this->operator()());
}
size_t RandBool() { return this->operator()() % 2; }
size_t SkewTowardsLast(size_t n) {
size_t T = this->operator()(n * n);
size_t Res = static_cast<size_t>(sqrt(T));
return Res;
}
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type operator()(T n) {
return n ? Rand<T>() % n : 0;
}
template <typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
operator()(T From, T To) {
assert(From < To);
auto RangeSize = static_cast<unsigned long long>(To) -
static_cast<unsigned long long>(From) + 1;
return static_cast<T>(this->operator()(RangeSize) + From);
}
};
int main(int argc, char **argv) {
unsigned int seed = atoi(argv[1]);
std::cout << "Seed: " << seed << std::endl;
Random Rand(seed);
for (int i = 0; i <= 100; i++) {
std::cout << "Rolled value: " << Rand() << std::endl;
}
return 0;
}So, there might be something else at play here, which would need some more investigating |
It seems like the randomness of a fuzzing run and the generally slower CI makes some runs really unpredictable. The
string_compareexample seems to be one of them. Bumping up the runs in the hope to fix the flakiness. Offline 100-200k runs were sufficient in 95% of the time, so the initial upper limit of 1 million was deemed enough. However, #335 failed to succeed