[PATCH] D21218: [LibFuzzer] Avoid using std::random_swap() due to platform differences and implement our own version.
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Sat Jun 11 04:47:34 PDT 2016
What problem are you trying to fix and do you really need to fix it?
-- kcc (sent from phone)
On Jun 10, 2016 1:22 AM, "Dan Liew" <dan at su-root.co.uk> wrote:
> delcypher created this revision.
> delcypher added reviewers: kcc, aizatsky.
> delcypher added subscribers: kcc, aizatsky, zaks.anna, kubabrecka,
> dcoughlin, llvm-commits.
>
> [LibFuzzer] Avoid using std::random_swap() due to platform differences
> and implement our own version.
>
> It turns out that the behavior of std::random_swap is different between
> libstdc++ and libcxx (even with the same random number source).
> Therefore if we want consistent behavior between platforms we have to
> use our own implementation.
>
> This change (plus a change to the number of iterations of the Mutator in
> the test required for the particular shuffle implementation used) fixes
> the ``FuzzerMutate.ShuffleBytes2`` unit test on OSX.
>
> I have verified that for the above unittest identical mutations are
> now generated on both Linux and on OSX.
>
>
> http://reviews.llvm.org/D21218
>
> Files:
> lib/Fuzzer/FuzzerInternal.h
> lib/Fuzzer/FuzzerLoop.cpp
> lib/Fuzzer/FuzzerMutate.cpp
> lib/Fuzzer/test/FuzzerUnittest.cpp
>
> Index: lib/Fuzzer/test/FuzzerUnittest.cpp
> ===================================================================
> --- lib/Fuzzer/test/FuzzerUnittest.cpp
> +++ lib/Fuzzer/test/FuzzerUnittest.cpp
> @@ -259,7 +259,7 @@
> TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 16);
> }
> TEST(FuzzerMutate, ShuffleBytes2) {
> - TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 19);
> + TestShuffleBytes(&MutationDispatcher::Mutate, 566171);
> }
>
> void TestAddWordFromDictionary(Mutator M, int NumIter) {
> Index: lib/Fuzzer/FuzzerMutate.cpp
> ===================================================================
> --- lib/Fuzzer/FuzzerMutate.cpp
> +++ lib/Fuzzer/FuzzerMutate.cpp
> @@ -96,8 +96,7 @@
> Rand(std::min(Size, (size_t)8)) + 1; // [1,8] and <= Size.
> size_t ShuffleStart = Rand(Size - ShuffleAmount);
> assert(ShuffleStart + ShuffleAmount <= Size);
> - std::random_shuffle(Data + ShuffleStart, Data + ShuffleStart +
> ShuffleAmount,
> - Rand);
> + Rand.Shuffle(Data + ShuffleStart, Data + ShuffleStart + ShuffleAmount);
> return Size;
> }
>
> Index: lib/Fuzzer/FuzzerLoop.cpp
> ===================================================================
> --- lib/Fuzzer/FuzzerLoop.cpp
> +++ lib/Fuzzer/FuzzerLoop.cpp
> @@ -321,7 +321,7 @@
> }
>
> void Fuzzer::ShuffleCorpus(UnitVector *V) {
> - std::random_shuffle(V->begin(), V->end(), MD.GetRand());
> + MD.GetRand().Shuffle(V->begin(), V->end());
> if (Options.PreferSmall)
> std::stable_sort(V->begin(), V->end(), [](const Unit &A, const Unit
> &B) {
> return A.size() < B.size();
> Index: lib/Fuzzer/FuzzerInternal.h
> ===================================================================
> --- lib/Fuzzer/FuzzerInternal.h
> +++ lib/Fuzzer/FuzzerInternal.h
> @@ -137,6 +137,22 @@
> size_t RandBool() { return Rand() % 2; }
> size_t operator()(size_t n) { return n ? Rand() % n : 0; }
> std::mt19937 &Get_mt19937() { return R; }
> + // Shuffle data in the range [First, End)
> + //
> + // We do not use std::random_shuffle() here because its
> + // behavior is not consistent across different platforms.
> + //
> + // The algorithm used here will pick a permutation at
> + // random where every permutation has equal probability
> + // (provided the random source is uniformly distributed).
> + template<typename RndAccessIt>
> + void Shuffle(RndAccessIt First, RndAccessIt End) {
> + typename std::iterator_traits<RndAccessIt>::difference_type Offset, N;
> + N = End - First;
> + for (Offset = 0; Offset < N; ++Offset) {
> + std::swap(First[Offset], First[Offset + (*this)(N - Offset)]);
> + }
> + }
> private:
> std::mt19937 R;
> };
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160611/6fdab31a/attachment.html>
More information about the llvm-commits
mailing list