Bug 1535671 - Remove some static initializers that call into PR_GetEnv during initialization unnecessarily. r=truber,posidron

I though this was going to be enough to unbreak rr, but it seems not to be the
case, see https://github.com/mozilla/rr/issues/2329.

In any case avoiding static initializers that initialize PR seems desirable.

Differential Revision: https://phabricator.services.mozilla.com/D23706

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2019-03-21 20:34:06 +00:00
Родитель 557728d4ad
Коммит 0204cde0f2
4 изменённых файлов: 58 добавлений и 49 удалений

Просмотреть файл

@ -5,6 +5,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <prinrval.h>
#include <thread>
#include <mutex>
#include "FuzzingTraits.h"
namespace mozilla {
@ -14,7 +16,7 @@ namespace fuzzing {
unsigned int FuzzingTraits::Random(unsigned int aMax) {
MOZ_ASSERT(aMax > 0, "aMax needs to be bigger than 0");
std::uniform_int_distribution<unsigned int> d(0, aMax);
return d(FuzzingTraits::rng);
return d(Rng());
}
/* static */
@ -28,7 +30,12 @@ size_t FuzzingTraits::Frequency(const size_t aSize, const uint64_t aFactor) {
}
/* static */
std::mt19937_64 FuzzingTraits::rng(PR_IntervalNow());
std::mt19937_64& FuzzingTraits::Rng() {
static std::mt19937_64 rng;
static std::once_flag flag;
std::call_once(flag, [&] { rng.seed(PR_IntervalNow()); });
return rng;
}
} // namespace fuzzing
} // namespace mozilla

Просмотреть файл

@ -25,7 +25,8 @@ class FuzzingTraits {
* the less mutations are being made.
*/
static size_t Frequency(const size_t aSize, const uint64_t aFactor);
static std::mt19937_64 rng;
static std::mt19937_64& Rng();
};
/**
@ -65,7 +66,7 @@ T RandomIntegerRange(T min, T max) {
"T must be an integral type");
MOZ_ASSERT(min < max);
std::uniform_int_distribution<T> d(min, max);
return d(FuzzingTraits::rng);
return d(FuzzingTraits::Rng());
}
/**
* uniform_int_distribution is undefined for char/uchar. Need to handle them
@ -75,13 +76,13 @@ template <>
inline unsigned char RandomIntegerRange(unsigned char min, unsigned char max) {
MOZ_ASSERT(min < max);
std::uniform_int_distribution<unsigned short> d(min, max);
return static_cast<unsigned char>(d(FuzzingTraits::rng));
return static_cast<unsigned char>(d(FuzzingTraits::Rng()));
}
template <>
inline char RandomIntegerRange(char min, char max) {
MOZ_ASSERT(min < max);
std::uniform_int_distribution<short> d(min, max);
return static_cast<char>(d(FuzzingTraits::rng));
return static_cast<char>(d(FuzzingTraits::Rng()));
}
/**
@ -95,7 +96,7 @@ T RandomFloatingPointRange(T min, T max) {
MOZ_ASSERT(min < max);
std::uniform_real_distribution<T> d(
min, std::nextafter(max, std::numeric_limits<T>::max()));
return d(FuzzingTraits::rng);
return d(FuzzingTraits::Rng());
}
/**

Просмотреть файл

@ -8,6 +8,7 @@
#include <climits>
#include <cmath>
#include <fstream>
#include <mutex>
#include <prinrval.h>
#ifdef _WINDOWS
# include <process.h>
@ -47,9 +48,6 @@ namespace ipc {
using namespace mozilla::fuzzing;
const unsigned int Faulty::sDefaultProbability = Faulty::DefaultProbability();
const bool Faulty::sIsLoggingEnabled = Faulty::Logging();
/**
* FuzzIntegralType mutates an incercepted integral type of a pickled message.
*/
@ -179,7 +177,7 @@ Faulty::Faulty()
randomSeed = static_cast<unsigned long>(n);
}
}
FuzzingTraits::rng.seed(randomSeed);
FuzzingTraits::Rng().seed(randomSeed);
/* Setup directory for dumping messages. */
mMessagePath = PR_GetEnv("FAULTY_MESSAGE_PATH");
@ -201,7 +199,7 @@ Faulty::Faulty()
mFuzzPickle ? "enabled" : "disabled");
FAULTY_LOG("* Fuzzing strategy: pipe = %s",
mFuzzPipes ? "enabled" : "disabled");
FAULTY_LOG("* Fuzzing probability = %u", sDefaultProbability);
FAULTY_LOG("* Fuzzing probability = %u", DefaultProbability());
FAULTY_LOG("* Fuzzing mutation factor = %u", MutationFactor());
FAULTY_LOG("* RNG seed = %lu", randomSeed);
@ -239,22 +237,30 @@ bool Faulty::IsValidProcessType(void) {
}
// static
unsigned int Faulty::DefaultProbability(void) {
// Defines the likelihood of fuzzing a message.
const char* probability = PR_GetEnv("FAULTY_PROBABILITY");
if (probability) {
long n = std::strtol(probability, nullptr, 10);
if (n != 0) {
return n;
unsigned int Faulty::DefaultProbability() {
static std::once_flag flag;
static unsigned probability;
std::call_once(flag, [&] {
probability = FAULTY_DEFAULT_PROBABILITY;
// Defines the likelihood of fuzzing a message.
if (const char* p = PR_GetEnv("FAULTY_PROBABILITY")) {
long n = std::strtol(p, nullptr, 10);
if (n != 0) {
probability = n;
}
}
}
return FAULTY_DEFAULT_PROBABILITY;
});
return probability;
}
// static
bool Faulty::Logging(void) {
// Enables logging of sendmsg() calls even in optimized builds.
return !!PR_GetEnv("FAULTY_ENABLE_LOGGING");
bool Faulty::IsLoggingEnabled(void) {
static bool enabled;
static std::once_flag flag;
std::call_once(flag, [&] { enabled = !!PR_GetEnv("FAULTY_ENABLE_LOGGING"); });
return enabled;
}
// static

Просмотреть файл

@ -37,11 +37,8 @@ namespace ipc {
class Faulty {
public:
// Used as a default argument for the Fuzz|datatype| methods.
static const unsigned int sDefaultProbability;
static unsigned int DefaultProbability(void);
static bool Logging(void);
static bool IsLoggingEnabled(void) { return sIsLoggingEnabled; }
static unsigned int DefaultProbability();
static bool IsLoggingEnabled(void);
static std::vector<uint8_t> GetDataFromIPCMessage(IPC::Message* aMsg);
static nsresult CreateOutputDirectory(const char* aPathname);
static nsresult ReadFile(const char* aPathname, nsTArray<nsCString>& aArray);
@ -50,38 +47,38 @@ class Faulty {
static Faulty& instance();
// Fuzzing methods for Pickle.
void FuzzBool(bool* aValue, unsigned int aProbability = sDefaultProbability);
void FuzzChar(char* aValue, unsigned int aProbability = sDefaultProbability);
void FuzzBool(bool* aValue, unsigned int aProbability = DefaultProbability());
void FuzzChar(char* aValue, unsigned int aProbability = DefaultProbability());
void FuzzUChar(unsigned char* aValue,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzInt16(int16_t* aValue,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzUInt16(uint16_t* aValue,
unsigned int aProbability = sDefaultProbability);
void FuzzInt(int* aValue, unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzInt(int* aValue, unsigned int aProbability = DefaultProbability());
void FuzzUInt32(uint32_t* aValue,
unsigned int aProbability = sDefaultProbability);
void FuzzLong(long* aValue, unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzLong(long* aValue, unsigned int aProbability = DefaultProbability());
void FuzzULong(unsigned long* aValue,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzInt64(int64_t* aValue,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzUInt64(uint64_t* aValue,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzFloat(float* aValue,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzDouble(double* aValue,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzString(std::string& aValue,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzWString(std::wstring& aValue,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void FuzzBytes(void* aData, int aLength,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
// Fuzzing methods for pipe fuzzing.
void MaybeCollectAndClosePipe(
int aPipe, unsigned int aProbability = sDefaultProbability);
int aPipe, unsigned int aProbability = DefaultProbability());
// Fuzzing methods for message blob fuzzing.
void DumpMessage(const char* aChannel, IPC::Message* aMsg,
@ -89,7 +86,7 @@ class Faulty {
bool IsMessageNameBlacklisted(const char* aMessageName);
IPC::Message* MutateIPCMessage(
const char* aChannel, IPC::Message* aMsg,
unsigned int aProbability = sDefaultProbability);
unsigned int aProbability = DefaultProbability());
void LogMessage(const char* aChannel, IPC::Message* aMsg);
@ -108,8 +105,6 @@ class Faulty {
size_t sMsgCounter;
static const bool sIsLoggingEnabled;
Faulty();
DISALLOW_EVIL_CONSTRUCTORS(Faulty);