Loading toolkit/recordreplay/ipc/Channel.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,7 @@ void Channel::SendMessage(const Message& aMsg) { MOZ_RELEASE_ASSERT(NS_IsMainThread() || aMsg.mType == MessageType::BeginFatalError || aMsg.mType == MessageType::FatalError || aMsg.mType == MessageType::MiddlemanCallRequest); Loading toolkit/recordreplay/ipc/Channel.h +7 −0 Original line number Diff line number Diff line Loading @@ -109,8 +109,13 @@ namespace recordreplay { \ /* A critical error occurred and execution cannot continue. The child will */ \ /* stop executing after sending this message and will wait to be terminated. */ \ /* A minidump for the child has been generated. */ \ _Macro(FatalError) \ \ /* Sent when a fatal error has occurred, but before the minidump has been */ \ /* generated. */ \ _Macro(BeginFatalError) \ \ /* The child's graphics were repainted. */ \ _Macro(Paint) \ \ Loading Loading @@ -371,6 +376,8 @@ struct FatalErrorMessage : public Message const char* Error() const { return Data<FatalErrorMessage, const char>(); } }; typedef EmptyMessage<MessageType::BeginFatalError> BeginFatalErrorMessage; // The format for graphics data which will be sent to the middleman process. // This needs to match the format expected for canvas image data, to avoid // transforming the data before rendering it in the middleman process. Loading toolkit/recordreplay/ipc/ChildIPC.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -108,8 +108,9 @@ ChannelMessageHandler(Message* aMsg) PrintSpew("Terminate message received, exiting...\n"); _exit(0); } else { MOZ_CRASH("Hanged replaying process"); ReportFatalError(Nothing(), "Hung replaying process"); } break; } case MessageType::SetIsActive: { const SetIsActiveMessage& nmsg = (const SetIsActiveMessage&) *aMsg; Loading Loading @@ -350,6 +351,10 @@ CreateCheckpoint() void ReportFatalError(const Maybe<MinidumpInfo>& aMinidump, const char* aFormat, ...) { // Notify the middleman that we are crashing and are going to try to write a // minidump. gChannel->SendMessage(BeginFatalErrorMessage()); // Unprotect any memory which might be written while producing the minidump. UnrecoverableSnapshotFailure(); Loading toolkit/recordreplay/ipc/ChildProcess.cpp +23 −6 Original line number Diff line number Diff line Loading @@ -40,6 +40,8 @@ ChildProcessInfo::ChildProcessInfo(UniquePtr<ChildRole> aRole, , mNumRecoveredMessages(0) , mRole(std::move(aRole)) , mPauseNeeded(false) , mHasBegunFatalError(false) , mHasFatalError(false) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); Loading Loading @@ -199,7 +201,11 @@ ChildProcessInfo::OnIncomingMessage(size_t aChannelId, const Message& aMsg) } // Always handle fatal errors in the same way. if (aMsg.mType == MessageType::FatalError) { if (aMsg.mType == MessageType::BeginFatalError) { mHasBegunFatalError = true; return; } else if (aMsg.mType == MessageType::FatalError) { mHasFatalError = true; const FatalErrorMessage& nmsg = static_cast<const FatalErrorMessage&>(aMsg); OnCrash(nmsg.Error()); return; Loading Loading @@ -527,14 +533,25 @@ ChildProcessInfo::OnCrash(const char* aWhy) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); // If a child process crashes or hangs then annotate the crash report and // shut down cleanly so that we don't mask the report with our own crash. // We want the crash to happen quickly so the user doesn't get a hanged tab. // If a child process crashes or hangs then annotate the crash report. CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RecordReplayError, nsAutoCString(aWhy)); // If we received a FatalError message then the child generated a minidump. // Shut down cleanly so that we don't mask the report with our own crash. if (mHasFatalError) { Shutdown(); } // Indicate when we crash if the child tried to send us a fatal error message // but had a problem either unprotecting system memory or generating the // minidump. MOZ_RELEASE_ASSERT(!mHasBegunFatalError); // The child crashed without producing a minidump, produce one ourselves. MOZ_CRASH("Unexpected child crash"); } /////////////////////////////////////////////////////////////////////////////// // Handling Channel Messages /////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -613,7 +630,7 @@ ChildProcessInfo::WaitUntil(const std::function<bool()>& aCallback) sentTerminateMessage = true; } else { // The child is still non-responsive after sending the terminate // message, fail without producing a minidump. // message. OnCrash("Child process non-responsive"); } } Loading toolkit/recordreplay/ipc/ParentInternal.h +5 −0 Original line number Diff line number Diff line Loading @@ -274,6 +274,11 @@ class ChildProcessInfo // Whether we need this child to pause while the recording is updated. bool mPauseNeeded; // Flags for whether we have received messages from the child indicating it // is crashing. bool mHasBegunFatalError; bool mHasFatalError; void OnIncomingMessage(size_t aChannelId, const Message& aMsg); void OnIncomingRecoveryMessage(const Message& aMsg); void SendNextRecoveryMessage(); Loading Loading
toolkit/recordreplay/ipc/Channel.cpp +1 −0 Original line number Diff line number Diff line Loading @@ -151,6 +151,7 @@ void Channel::SendMessage(const Message& aMsg) { MOZ_RELEASE_ASSERT(NS_IsMainThread() || aMsg.mType == MessageType::BeginFatalError || aMsg.mType == MessageType::FatalError || aMsg.mType == MessageType::MiddlemanCallRequest); Loading
toolkit/recordreplay/ipc/Channel.h +7 −0 Original line number Diff line number Diff line Loading @@ -109,8 +109,13 @@ namespace recordreplay { \ /* A critical error occurred and execution cannot continue. The child will */ \ /* stop executing after sending this message and will wait to be terminated. */ \ /* A minidump for the child has been generated. */ \ _Macro(FatalError) \ \ /* Sent when a fatal error has occurred, but before the minidump has been */ \ /* generated. */ \ _Macro(BeginFatalError) \ \ /* The child's graphics were repainted. */ \ _Macro(Paint) \ \ Loading Loading @@ -371,6 +376,8 @@ struct FatalErrorMessage : public Message const char* Error() const { return Data<FatalErrorMessage, const char>(); } }; typedef EmptyMessage<MessageType::BeginFatalError> BeginFatalErrorMessage; // The format for graphics data which will be sent to the middleman process. // This needs to match the format expected for canvas image data, to avoid // transforming the data before rendering it in the middleman process. Loading
toolkit/recordreplay/ipc/ChildIPC.cpp +6 −1 Original line number Diff line number Diff line Loading @@ -108,8 +108,9 @@ ChannelMessageHandler(Message* aMsg) PrintSpew("Terminate message received, exiting...\n"); _exit(0); } else { MOZ_CRASH("Hanged replaying process"); ReportFatalError(Nothing(), "Hung replaying process"); } break; } case MessageType::SetIsActive: { const SetIsActiveMessage& nmsg = (const SetIsActiveMessage&) *aMsg; Loading Loading @@ -350,6 +351,10 @@ CreateCheckpoint() void ReportFatalError(const Maybe<MinidumpInfo>& aMinidump, const char* aFormat, ...) { // Notify the middleman that we are crashing and are going to try to write a // minidump. gChannel->SendMessage(BeginFatalErrorMessage()); // Unprotect any memory which might be written while producing the minidump. UnrecoverableSnapshotFailure(); Loading
toolkit/recordreplay/ipc/ChildProcess.cpp +23 −6 Original line number Diff line number Diff line Loading @@ -40,6 +40,8 @@ ChildProcessInfo::ChildProcessInfo(UniquePtr<ChildRole> aRole, , mNumRecoveredMessages(0) , mRole(std::move(aRole)) , mPauseNeeded(false) , mHasBegunFatalError(false) , mHasFatalError(false) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); Loading Loading @@ -199,7 +201,11 @@ ChildProcessInfo::OnIncomingMessage(size_t aChannelId, const Message& aMsg) } // Always handle fatal errors in the same way. if (aMsg.mType == MessageType::FatalError) { if (aMsg.mType == MessageType::BeginFatalError) { mHasBegunFatalError = true; return; } else if (aMsg.mType == MessageType::FatalError) { mHasFatalError = true; const FatalErrorMessage& nmsg = static_cast<const FatalErrorMessage&>(aMsg); OnCrash(nmsg.Error()); return; Loading Loading @@ -527,14 +533,25 @@ ChildProcessInfo::OnCrash(const char* aWhy) { MOZ_RELEASE_ASSERT(NS_IsMainThread()); // If a child process crashes or hangs then annotate the crash report and // shut down cleanly so that we don't mask the report with our own crash. // We want the crash to happen quickly so the user doesn't get a hanged tab. // If a child process crashes or hangs then annotate the crash report. CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RecordReplayError, nsAutoCString(aWhy)); // If we received a FatalError message then the child generated a minidump. // Shut down cleanly so that we don't mask the report with our own crash. if (mHasFatalError) { Shutdown(); } // Indicate when we crash if the child tried to send us a fatal error message // but had a problem either unprotecting system memory or generating the // minidump. MOZ_RELEASE_ASSERT(!mHasBegunFatalError); // The child crashed without producing a minidump, produce one ourselves. MOZ_CRASH("Unexpected child crash"); } /////////////////////////////////////////////////////////////////////////////// // Handling Channel Messages /////////////////////////////////////////////////////////////////////////////// Loading Loading @@ -613,7 +630,7 @@ ChildProcessInfo::WaitUntil(const std::function<bool()>& aCallback) sentTerminateMessage = true; } else { // The child is still non-responsive after sending the terminate // message, fail without producing a minidump. // message. OnCrash("Child process non-responsive"); } } Loading
toolkit/recordreplay/ipc/ParentInternal.h +5 −0 Original line number Diff line number Diff line Loading @@ -274,6 +274,11 @@ class ChildProcessInfo // Whether we need this child to pause while the recording is updated. bool mPauseNeeded; // Flags for whether we have received messages from the child indicating it // is crashing. bool mHasBegunFatalError; bool mHasFatalError; void OnIncomingMessage(size_t aChannelId, const Message& aMsg); void OnIncomingRecoveryMessage(const Message& aMsg); void SendNextRecoveryMessage(); Loading