author | Brian Hackett <bhackett1024@gmail.com> |
Mon, 26 Nov 2018 12:42:28 -1000 | |
changeset 448191 | b12b2142017abdb8cce3ea9758ed0af16c398e15 |
parent 448190 | b9f41dd78cfdd2739b343595c1647ef1c4f57875 |
child 448192 | 47750e022e23d5b4eb445443a737a04ba9b45391 |
push id | 35106 |
push user | rmaries@mozilla.com |
push date | Tue, 27 Nov 2018 09:44:10 +0000 |
treeherder | mozilla-central@ce39a152428a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mccr8 |
bugs | 1500703 |
milestone | 65.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/toolkit/recordreplay/File.cpp +++ b/toolkit/recordreplay/File.cpp @@ -154,18 +154,27 @@ Stream::WriteScalar(size_t aValue) void Stream::RecordOrReplayThreadEvent(ThreadEvent aEvent) { if (IsRecording()) { WriteScalar((size_t) aEvent); } else { ThreadEvent oldEvent = (ThreadEvent) ReadScalar(); if (oldEvent != aEvent) { - child::ReportFatalError(Nothing(), "Event Mismatch: Recorded %s Replayed %s", - ThreadEventName(oldEvent), ThreadEventName(aEvent)); + const char* extra = ""; + if (oldEvent == ThreadEvent::Assert) { + // Include the asserted string in the error. This must match up with + // the writes in RecordReplayAssert. + if (mNameIndex == MainThreadId) { + (void) ReadScalar(); // For the ExecutionProgressCounter write below. + } + extra = ReadInputString(); + } + child::ReportFatalError(Nothing(), "Event Mismatch: Recorded %s %s Replayed %s", + ThreadEventName(oldEvent), extra, ThreadEventName(aEvent)); } mLastEvent = aEvent; } // Check the execution progress counter for events executing on the main thread. if (mNameIndex == MainThreadId) { CheckInput(*ExecutionProgressCounter()); } @@ -180,32 +189,38 @@ Stream::CheckInput(size_t aValue) size_t oldValue = ReadScalar(); if (oldValue != aValue) { child::ReportFatalError(Nothing(), "Input Mismatch: %s Recorded %llu Replayed %llu", ThreadEventName(mLastEvent), oldValue, aValue); } } } +const char* +Stream::ReadInputString() +{ + size_t len = ReadScalar(); + EnsureInputBallast(len + 1); + ReadBytes(mInputBallast.get(), len); + mInputBallast[len] = 0; + return mInputBallast.get(); +} + void Stream::CheckInput(const char* aValue) { size_t len = strlen(aValue); if (IsRecording()) { WriteScalar(len); WriteBytes(aValue, len); } else { - size_t oldLen = ReadScalar(); - EnsureInputBallast(oldLen + 1); - ReadBytes(mInputBallast.get(), oldLen); - mInputBallast[oldLen] = 0; - - if (len != oldLen || memcmp(aValue, mInputBallast.get(), len) != 0) { + const char* oldInput = ReadInputString(); + if (strcmp(oldInput, aValue) != 0) { child::ReportFatalError(Nothing(), "Input Mismatch: %s Recorded %s Replayed %s", - ThreadEventName(mLastEvent), mInputBallast.get(), aValue); + ThreadEventName(mLastEvent), oldInput, aValue); } } } void Stream::CheckInput(const void* aData, size_t aSize) { CheckInput(aSize);
--- a/toolkit/recordreplay/File.h +++ b/toolkit/recordreplay/File.h @@ -192,16 +192,17 @@ private: DontCopyExistingData, CopyExistingData }; void EnsureMemory(UniquePtr<char[]>* aBuf, size_t* aSize, size_t aNeededSize, size_t aMaxSize, ShouldCopy aCopy); void EnsureInputBallast(size_t aSize); void Flush(bool aTakeLock); + const char* ReadInputString(); static size_t BallastMaxSize(); }; class File { public: enum Mode {
--- a/toolkit/recordreplay/ProcessRecordReplay.cpp +++ b/toolkit/recordreplay/ProcessRecordReplay.cpp @@ -350,16 +350,18 @@ RecordReplayInterface_InternalRecordRepl if (!res.CanAccessEvents()) { return; } // Add the asserted string to the recording. char text[1024]; VsprintfLiteral(text, aFormat, aArgs); + // This must be kept in sync with Stream::RecordOrReplayThreadEvent, which + // peeks at the input string written after the thread event. thread->Events().RecordOrReplayThreadEvent(ThreadEvent::Assert); thread->Events().CheckInput(text); } MOZ_EXPORT void RecordReplayInterface_InternalRecordReplayAssertBytes(const void* aData, size_t aSize) { Thread* thread = Thread::Current();
--- a/toolkit/recordreplay/ProcessRedirectDarwin.cpp +++ b/toolkit/recordreplay/ProcessRedirectDarwin.cpp @@ -901,16 +901,19 @@ Preamble_getenv(CallArguments* aArgument // The JPEG library can fetch configuration information from the environment // in a way that can run non-deterministically on different threads. if (strncmp(env, "JSIMD_", 6) == 0) { aArguments->Rval<char*>() = nullptr; return PreambleResult::Veto; } + // Include the environment variable being checked in an assertion, to make it + // easier to debug recording mismatches involving getenv. + RecordReplayAssert("getenv %s", env); return PreambleResult::Redirect; } static struct tm gGlobalTM; // localtime behaves the same as localtime_r, except it is not reentrant. // For simplicity, define this in terms of localtime_r. static PreambleResult