mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 06:09:19 +00:00
Bug 1831092 - Use the new pull-based API for all crash annotations and remove the global annotations table r=jgilbert,necko-reviewers,media-playback-reviewers,profiler-reviewers,win-reviewers,padenot,handyman,afranchuk,valentin,alwu,sotaro
This changes comes with several different refactorings all rolled into one, unfotunately I couldn't find a way to pull them apart: - First of all annotations now can either recorded (that is, we copy the value and have the crash reporting code own the copy) or registered. Several annotations are changed to use this functionality so that we don't need to update them as their value change. - The code in the exception handler is modified to read the annotations from the mozannotation_client crate. This has the unfortunate side-effect that we need three different bits of code to serialize them: one for annotations read from a child process, one for reading annotations from the main process outside of the exception handler and one for reading annotations from the main process within the exception handler. As we move to fully out-of-process crash reporting the last two methods will go away. - The mozannotation_client crate now doesn't record annotation types anymore. I realized as I was working on this that storing types at runtime has two issues: the first one is that buggy code might change the type of an annotation (that is record it under two different types at two different moments), the second issue is that types might become corrupt during a crash, so better enforce them at annotation-writing time. The end result is that the mozannotation_* crates now only store byte buffers, track the format the data is stored in (null-terminated string, fixed size buffer, etc...) but not the type of data each annotation is supposed to contain. - Which brings us to the next change: concrete types for annotations are now enforced when they're written out. If an annotation doesn't match the expected type it's skipped. Storing an annotation with the wrong type will also trigger an assertion in debug builds. Differential Revision: https://phabricator.services.mozilla.com/D195248
This commit is contained in:
parent
42efa58063
commit
aa43fa218e
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3681,7 +3681,6 @@ dependencies = [
|
||||
"mach2",
|
||||
"memoffset 0.8.999",
|
||||
"mozannotation_client",
|
||||
"nsstring",
|
||||
"thin-vec",
|
||||
"thiserror",
|
||||
"winapi",
|
||||
|
@ -1522,8 +1522,8 @@ bool nsAccessibilityService::Init() {
|
||||
NS_ADDREF(gApplicationAccessible); // will release in Shutdown()
|
||||
gApplicationAccessible->Init();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Accessibility,
|
||||
"Active"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::Accessibility, "Active");
|
||||
|
||||
// Now its safe to start platform accessibility.
|
||||
if (XRE_IsParentProcess()) PlatformInit();
|
||||
|
@ -256,7 +256,7 @@ void PlatformRoleChangedEvent(Accessible* aTarget, const a11y::role& aRole,
|
||||
mozilla::Telemetry::ScalarSet(
|
||||
mozilla::Telemetry::ScalarID::A11Y_INSTANTIATORS, client);
|
||||
#endif // defined(MOZ_TELEMETRY_REPORTING)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::AccessibilityClient,
|
||||
NS_ConvertUTF16toUTF8(client));
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ void Compatibility::Init() {
|
||||
// Note we collect some AT statistics/telemetry here for convenience.
|
||||
InitConsumers();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::AccessibilityInProcClient,
|
||||
nsPrintfCString("0x%X", sConsumers));
|
||||
|
||||
|
@ -197,9 +197,8 @@ static void AccumulateInstantiatorTelemetry(const nsAString& aValue) {
|
||||
#if defined(MOZ_TELEMETRY_REPORTING)
|
||||
Telemetry::ScalarSet(Telemetry::ScalarID::A11Y_INSTANTIATORS, aValue);
|
||||
#endif // defined(MOZ_TELEMETRY_REPORTING)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::AccessibilityClient,
|
||||
NS_ConvertUTF16toUTF8(aValue));
|
||||
CrashReporter::RecordAnnotationNSString(
|
||||
CrashReporter::Annotation::AccessibilityClient, aValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "mozilla/Types.h"
|
||||
#include "mozilla/WindowsDllBlocklist.h"
|
||||
|
||||
#include "CrashAnnotations.h"
|
||||
#include "DllBlocklist.h"
|
||||
#include "LoaderPrivateAPI.h"
|
||||
#include "ModuleLoadFrame.h"
|
||||
@ -136,12 +135,8 @@ void NativeNtBlockSet::Write(WritableBuffer& aBuffer) {
|
||||
|
||||
static NativeNtBlockSet gBlockSet;
|
||||
|
||||
extern "C" void MOZ_EXPORT
|
||||
NativeNtBlockSet_Write(CrashReporter::AnnotationWriter& aWriter) {
|
||||
WritableBuffer buffer;
|
||||
gBlockSet.Write(buffer);
|
||||
aWriter.Write(CrashReporter::Annotation::BlockedDllList, buffer.Data(),
|
||||
buffer.Length());
|
||||
extern "C" void MOZ_EXPORT NativeNtBlockSet_Write(WritableBuffer& aBuffer) {
|
||||
gBlockSet.Write(aBuffer);
|
||||
}
|
||||
|
||||
enum class BlockAction {
|
||||
|
@ -38,7 +38,7 @@ void moz_wasm2c_memgrow_failed() {
|
||||
# ifdef WASM_RT_GROW_FAILED_CRASH
|
||||
MOZ_CRASH("wasm2c memory grow failed");
|
||||
# else
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::WasmLibrarySandboxMallocFailed, true);
|
||||
# endif
|
||||
}
|
||||
|
@ -161,6 +161,9 @@ static StaticAutoPtr<BrowsingContextMap> sBrowsingContexts;
|
||||
// Top-level Content BrowsingContexts only, indexed by BrowserId instead of Id
|
||||
static StaticAutoPtr<BrowsingContextMap> sCurrentTopByBrowserId;
|
||||
|
||||
static bool gIPCEnabledAnnotation = false;
|
||||
static bool gFissionEnabledAnnotation = false;
|
||||
|
||||
static void UnregisterBrowserId(BrowsingContext* aBrowsingContext) {
|
||||
if (!aBrowsingContext->IsTopContent() || !sCurrentTopByBrowserId) {
|
||||
return;
|
||||
@ -248,6 +251,11 @@ void BrowsingContext::Init() {
|
||||
sCurrentTopByBrowserId = new BrowsingContextMap();
|
||||
ClearOnShutdown(&sBrowsingContexts);
|
||||
ClearOnShutdown(&sCurrentTopByBrowserId);
|
||||
CrashReporter::RegisterAnnotationBool(
|
||||
CrashReporter::Annotation::DOMIPCEnabled, &gIPCEnabledAnnotation);
|
||||
CrashReporter::RegisterAnnotationBool(
|
||||
CrashReporter::Annotation::DOMFissionEnabled,
|
||||
&gFissionEnabledAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1658,11 +1666,8 @@ NS_IMETHODIMP BrowsingContext::SetRemoteTabs(bool aUseRemoteTabs) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
static bool annotated = false;
|
||||
if (aUseRemoteTabs && !annotated) {
|
||||
annotated = true;
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::DOMIPCEnabled,
|
||||
true);
|
||||
if (aUseRemoteTabs && !gIPCEnabledAnnotation) {
|
||||
gIPCEnabledAnnotation = true;
|
||||
}
|
||||
|
||||
// Don't allow non-remote tabs with remote subframes.
|
||||
@ -1686,11 +1691,8 @@ NS_IMETHODIMP BrowsingContext::SetRemoteSubframes(bool aUseRemoteSubframes) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
static bool annotated = false;
|
||||
if (aUseRemoteSubframes && !annotated) {
|
||||
annotated = true;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::DOMFissionEnabled, true);
|
||||
if (aUseRemoteSubframes && !gFissionEnabledAnnotation) {
|
||||
gFissionEnabledAnnotation = true;
|
||||
}
|
||||
|
||||
// Don't allow non-remote tabs with remote subframes.
|
||||
|
@ -354,13 +354,13 @@ struct EnumSerializer {
|
||||
static bool Read(ConsumerView<U>& aConsumerView, ParamType* aResult) {
|
||||
DataType value;
|
||||
if (!aConsumerView.ReadParam(&value)) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCReadErrorReason, "Bad iter"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::IPCReadErrorReason, "Bad iter");
|
||||
return false;
|
||||
}
|
||||
if (!EnumValidator::IsLegalValue(static_cast<DataType>(value))) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCReadErrorReason, "Illegal value"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::IPCReadErrorReason, "Illegal value");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -233,7 +233,7 @@ bool TouchEvent::PrefEnabled(nsIDocShell* aDocShell) {
|
||||
// The touch screen data seems to be inaccurate in the parent process,
|
||||
// and we really need the crash annotation in child processes.
|
||||
if (firstTime && !XRE_IsParentProcess()) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::HasDeviceTouchScreen, enabled);
|
||||
firstTime = false;
|
||||
}
|
||||
|
@ -814,7 +814,8 @@ mozilla::ipc::IPCResult BrowserChild::RecvLoadURL(
|
||||
}
|
||||
docShell->LoadURI(aLoadState, true);
|
||||
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL, spec);
|
||||
CrashReporter::RecordAnnotationNSCString(CrashReporter::Annotation::URL,
|
||||
spec);
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
@ -3481,8 +3482,8 @@ NS_IMETHODIMP BrowserChild::OnLocationChange(nsIWebProgress* aWebProgress,
|
||||
annotationURI = aLocation;
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL,
|
||||
annotationURI->GetSpecOrDefault());
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::URL, annotationURI->GetSpecOrDefault());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1714,12 +1714,12 @@ mozilla::ipc::IPCResult ContentChild::RecvSetProcessSandbox(
|
||||
DisconnectWindowServer(sandboxEnabled);
|
||||
# endif
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::ContentSandboxEnabled, sandboxEnabled);
|
||||
# if defined(XP_LINUX) && !defined(ANDROID)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::ContentSandboxCapabilities,
|
||||
static_cast<int>(SandboxInfo::Get().AsInteger()));
|
||||
SandboxInfo::Get().AsInteger());
|
||||
# endif /* XP_LINUX && !ANDROID */
|
||||
#endif /* MOZ_SANDBOX */
|
||||
|
||||
@ -2223,9 +2223,8 @@ void ContentChild::ProcessingError(Result aCode, const char* aReason) {
|
||||
MOZ_CRASH("not reached");
|
||||
}
|
||||
|
||||
nsDependentCString reason(aReason);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ipc_channel_error, reason);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ipc_channel_error, aReason);
|
||||
|
||||
MOZ_CRASH("Content child abort due to IPC error");
|
||||
}
|
||||
@ -2677,8 +2676,8 @@ mozilla::ipc::IPCResult ContentChild::RecvRemoteType(
|
||||
}
|
||||
|
||||
// Use the prefix to avoid URIs from Fission isolated processes.
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RemoteType,
|
||||
remoteTypePrefix);
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::RemoteType, remoteTypePrefix);
|
||||
|
||||
// Defer RemoteWorkerService initialization until the child process does
|
||||
// receive its specific remoteType and can become actionable for the
|
||||
@ -2951,8 +2950,7 @@ void ContentChild::ForceKillTimerCallback(nsITimer* aTimer, void* aClosure) {
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentChild::RecvShutdownConfirmedHP() {
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation(
|
||||
"RecvShutdownConfirmedHP entry"_ns);
|
||||
|
||||
// Bug 1755376: If we see "RecvShutdownConfirmedHP entry" often in
|
||||
@ -2963,8 +2961,7 @@ mozilla::ipc::IPCResult ContentChild::RecvShutdownConfirmedHP() {
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentChild::RecvShutdown() {
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState, "RecvShutdown entry"_ns);
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation("RecvShutdown entry"_ns);
|
||||
|
||||
// Signal the ongoing shutdown to AppShutdown, this
|
||||
// will make abort nested SpinEventLoopUntilOrQuit loops
|
||||
@ -2973,8 +2970,7 @@ mozilla::ipc::IPCResult ContentChild::RecvShutdown() {
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation(
|
||||
"content-child-will-shutdown started"_ns);
|
||||
|
||||
os->NotifyObservers(ToSupports(this), "content-child-will-shutdown",
|
||||
@ -2986,8 +2982,7 @@ mozilla::ipc::IPCResult ContentChild::RecvShutdown() {
|
||||
}
|
||||
|
||||
void ContentChild::ShutdownInternal() {
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState, "ShutdownInternal entry"_ns);
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation("ShutdownInternal entry"_ns);
|
||||
|
||||
// If we receive the shutdown message from within a nested event loop, we want
|
||||
// to wait for that event loop to finish. Otherwise we could prematurely
|
||||
@ -3025,8 +3020,7 @@ void ContentChild::ShutdownInternal() {
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
|
||||
if (os) {
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation(
|
||||
"content-child-shutdown started"_ns);
|
||||
os->NotifyObservers(ToSupports(this), "content-child-shutdown", nullptr);
|
||||
}
|
||||
@ -3035,21 +3029,21 @@ void ContentChild::ShutdownInternal() {
|
||||
|
||||
if (mProfilerController) {
|
||||
const bool isProfiling = profiler_is_active();
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
isProfiling ? "Profiling - GrabShutdownProfileAndShutdown"_ns
|
||||
: "Not profiling - GrabShutdownProfileAndShutdown"_ns);
|
||||
isProfiling ? "Profiling - GrabShutdownProfileAndShutdown"
|
||||
: "Not profiling - GrabShutdownProfileAndShutdown");
|
||||
ProfileAndAdditionalInformation shutdownProfileAndAdditionalInformation =
|
||||
mProfilerController->GrabShutdownProfileAndShutdown();
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
isProfiling ? "Profiling - Destroying ChildProfilerController"_ns
|
||||
: "Not profiling - Destroying ChildProfilerController"_ns);
|
||||
isProfiling ? "Profiling - Destroying ChildProfilerController"
|
||||
: "Not profiling - Destroying ChildProfilerController");
|
||||
mProfilerController = nullptr;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
isProfiling ? "Profiling - SendShutdownProfile (sending)"_ns
|
||||
: "Not profiling - SendShutdownProfile (sending)"_ns);
|
||||
isProfiling ? "Profiling - SendShutdownProfile (sending)"
|
||||
: "Not profiling - SendShutdownProfile (sending)");
|
||||
if (const size_t len = shutdownProfileAndAdditionalInformation.SizeOf();
|
||||
len >= size_t(IPC::Channel::kMaximumMessageSize)) {
|
||||
shutdownProfileAndAdditionalInformation.mProfile = nsPrintfCString(
|
||||
@ -3061,13 +3055,12 @@ void ContentChild::ShutdownInternal() {
|
||||
// message channel, which we know will survive for long enough.
|
||||
bool sent =
|
||||
SendShutdownProfile(shutdownProfileAndAdditionalInformation.mProfile);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
sent ? (isProfiling ? "Profiling - SendShutdownProfile (sent)"_ns
|
||||
: "Not profiling - SendShutdownProfile (sent)"_ns)
|
||||
: (isProfiling
|
||||
? "Profiling - SendShutdownProfile (failed)"_ns
|
||||
: "Not profiling - SendShutdownProfile (failed)"_ns));
|
||||
sent ? (isProfiling ? "Profiling - SendShutdownProfile (sent)"
|
||||
: "Not profiling - SendShutdownProfile (sent)")
|
||||
: (isProfiling ? "Profiling - SendShutdownProfile (failed)"
|
||||
: "Not profiling - SendShutdownProfile (failed)"));
|
||||
}
|
||||
|
||||
if (PerfStats::GetCollectionMask() != 0) {
|
||||
@ -3077,12 +3070,10 @@ void ContentChild::ShutdownInternal() {
|
||||
// Start a timer that will ensure we quickly exit after a reasonable period
|
||||
// of time. Prevents shutdown hangs after our connection to the parent
|
||||
// closes or when the parent is too busy to ever kill us.
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState, "StartForceKillTimer"_ns);
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation("StartForceKillTimer"_ns);
|
||||
StartForceKillTimer();
|
||||
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation(
|
||||
"SendFinishShutdown (sending)"_ns);
|
||||
|
||||
// Notify the parent that we are done with shutdown. This is sent with high
|
||||
@ -3094,8 +3085,7 @@ void ContentChild::ShutdownInternal() {
|
||||
// ever process for this ContentChild.
|
||||
bool sent = SendFinishShutdown();
|
||||
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation(
|
||||
sent ? "SendFinishShutdown (sent)"_ns : "SendFinishShutdown (failed)"_ns);
|
||||
}
|
||||
|
||||
@ -4345,8 +4335,8 @@ mozilla::ipc::IPCResult ContentChild::RecvLoadURI(
|
||||
annotationURI = aLoadState->URI();
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL,
|
||||
annotationURI->GetSpecOrDefault());
|
||||
CrashReporter::RecordAnnotationNSCString(CrashReporter::Annotation::URL,
|
||||
annotationURI->GetSpecOrDefault());
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -4379,8 +4369,8 @@ mozilla::ipc::IPCResult ContentChild::RecvInternalLoad(
|
||||
annotationURI = aLoadState->URI();
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL,
|
||||
annotationURI->GetSpecOrDefault());
|
||||
CrashReporter::RecordAnnotationNSCString(CrashReporter::Annotation::URL,
|
||||
annotationURI->GetSpecOrDefault());
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -4441,11 +4441,11 @@ void ContentParent::GeneratePairedMinidump(const char* aReason) {
|
||||
// minidump tagging along, so we have to tell the crash reporter that
|
||||
// it exists and is being appended.
|
||||
nsAutoCString additionalDumps("browser");
|
||||
mCrashReporter->AddAnnotation(
|
||||
mCrashReporter->AddAnnotationNSCString(
|
||||
CrashReporter::Annotation::additional_minidumps, additionalDumps);
|
||||
nsDependentCString reason(aReason);
|
||||
mCrashReporter->AddAnnotation(CrashReporter::Annotation::ipc_channel_error,
|
||||
reason);
|
||||
mCrashReporter->AddAnnotationNSCString(
|
||||
CrashReporter::Annotation::ipc_channel_error, reason);
|
||||
|
||||
// Generate the report and insert into the queue for submittal.
|
||||
if (mCrashReporter->GenerateMinidumpAndPair(this, "browser"_ns)) {
|
||||
|
@ -560,12 +560,10 @@ mozilla::ipc::IPCResult HangMonitorChild::RecvRequestContentJSInterrupt() {
|
||||
// In order to cancel JS execution on shutdown, we expect that
|
||||
// ProcessChild::NotifiedImpendingShutdown has been called before.
|
||||
if (mozilla::ipc::ProcessChild::ExpectingShutdown()) {
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation(
|
||||
"HangMonitorChild::RecvRequestContentJSInterrupt (expected)"_ns);
|
||||
} else {
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation(
|
||||
"HangMonitorChild::RecvRequestContentJSInterrupt (unexpected)"_ns);
|
||||
}
|
||||
JS_RequestInterruptCallback(mContext);
|
||||
|
@ -145,9 +145,9 @@ void JSActorManager::ReceiveRawMessage(
|
||||
Maybe<ipc::StructuredCloneData>&& aStack) {
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
|
||||
|
||||
CrashReporter::AutoAnnotateCrashReport autoActorName(
|
||||
CrashReporter::AutoRecordAnnotation autoActorName(
|
||||
CrashReporter::Annotation::JSActorName, aMetadata.actorName());
|
||||
CrashReporter::AutoAnnotateCrashReport autoMessageName(
|
||||
CrashReporter::AutoRecordAnnotation autoMessageName(
|
||||
CrashReporter::Annotation::JSActorMessage,
|
||||
NS_LossyConvertUTF16toASCII(aMetadata.messageName()));
|
||||
|
||||
@ -239,7 +239,7 @@ void JSActorManager::JSActorWillDestroy() {
|
||||
|
||||
void JSActorManager::JSActorDidDestroy() {
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
|
||||
CrashReporter::AutoAnnotateCrashReport autoMessageName(
|
||||
CrashReporter::AutoRecordAnnotation autoMessageName(
|
||||
CrashReporter::Annotation::JSActorMessage, "<DidDestroy>"_ns);
|
||||
|
||||
// Swap the table with `mJSActors` so that we don't invalidate it while
|
||||
@ -247,7 +247,7 @@ void JSActorManager::JSActorDidDestroy() {
|
||||
const nsRefPtrHashtable<nsCStringHashKey, JSActor> actors =
|
||||
std::move(mJSActors);
|
||||
for (const auto& entry : actors.Values()) {
|
||||
CrashReporter::AutoAnnotateCrashReport autoActorName(
|
||||
CrashReporter::AutoRecordAnnotation autoActorName(
|
||||
CrashReporter::Annotation::JSActorName, entry->Name());
|
||||
// Do not risk to run script very late in shutdown
|
||||
if (!AppShutdown::IsInOrBeyond(ShutdownPhase::XPCOMShutdownFinal)) {
|
||||
|
@ -106,9 +106,9 @@ void JSActorService::RegisterWindowActor(const nsACString& aName,
|
||||
|
||||
void JSActorService::UnregisterWindowActor(const nsACString& aName) {
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
|
||||
CrashReporter::AutoAnnotateCrashReport autoActorName(
|
||||
CrashReporter::AutoRecordAnnotation autoActorName(
|
||||
CrashReporter::Annotation::JSActorName, aName);
|
||||
CrashReporter::AutoAnnotateCrashReport autoMessageName(
|
||||
CrashReporter::AutoRecordAnnotation autoMessageName(
|
||||
CrashReporter::Annotation::JSActorMessage, "<Unregister>"_ns);
|
||||
|
||||
nsAutoCString name(aName);
|
||||
@ -268,9 +268,9 @@ void JSActorService::RegisterProcessActor(const nsACString& aName,
|
||||
|
||||
void JSActorService::UnregisterProcessActor(const nsACString& aName) {
|
||||
MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
|
||||
CrashReporter::AutoAnnotateCrashReport autoActorName(
|
||||
CrashReporter::AutoRecordAnnotation autoActorName(
|
||||
CrashReporter::Annotation::JSActorName, aName);
|
||||
CrashReporter::AutoAnnotateCrashReport autoMessageName(
|
||||
CrashReporter::AutoRecordAnnotation autoMessageName(
|
||||
CrashReporter::Annotation::JSActorMessage, "<Unregister>"_ns);
|
||||
|
||||
nsAutoCString name(aName);
|
||||
|
@ -237,16 +237,15 @@ mozilla::ipc::IPCResult GMPChild::RecvPreloadLibs(const nsCString& aLibs) {
|
||||
bool GMPChild::GetUTF8LibPath(nsACString& aOutLibPath) {
|
||||
nsCOMPtr<nsIFile> libFile;
|
||||
|
||||
#define GMP_PATH_CRASH(explain) \
|
||||
do { \
|
||||
nsAutoString path; \
|
||||
if (!libFile || NS_FAILED(libFile->GetPath(path))) { \
|
||||
path = mPluginPath; \
|
||||
} \
|
||||
CrashReporter::AnnotateCrashReport( \
|
||||
CrashReporter::Annotation::GMPLibraryPath, \
|
||||
NS_ConvertUTF16toUTF8(path)); \
|
||||
MOZ_CRASH(explain); \
|
||||
#define GMP_PATH_CRASH(explain) \
|
||||
do { \
|
||||
nsAutoString path; \
|
||||
if (!libFile || NS_FAILED(libFile->GetPath(path))) { \
|
||||
path = mPluginPath; \
|
||||
} \
|
||||
CrashReporter::RecordAnnotationNSString( \
|
||||
CrashReporter::Annotation::GMPLibraryPath, path); \
|
||||
MOZ_CRASH(explain); \
|
||||
} while (false)
|
||||
|
||||
nsresult rv = NS_NewLocalFile(mPluginPath, true, getter_AddRefs(libFile));
|
||||
@ -514,7 +513,7 @@ mozilla::ipc::IPCResult GMPChild::RecvStartPlugin(const nsString& aAdapter) {
|
||||
|
||||
nsAutoCString libPath;
|
||||
if (!GetUTF8LibPath(libPath)) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::GMPLibraryPath,
|
||||
NS_ConvertUTF16toUTF8(mPluginPath));
|
||||
|
||||
@ -556,7 +555,7 @@ mozilla::ipc::IPCResult GMPChild::RecvStartPlugin(const nsString& aAdapter) {
|
||||
NS_WARNING("Failed to load GMP");
|
||||
#endif
|
||||
delete platformAPI;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::GMPLibraryPath,
|
||||
NS_ConvertUTF16toUTF8(mPluginPath));
|
||||
|
||||
@ -727,21 +726,21 @@ mozilla::ipc::IPCResult GMPChild::RecvShutdown(ShutdownResolver&& aResolver) {
|
||||
}
|
||||
|
||||
const bool isProfiling = profiler_is_active();
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
isProfiling ? "Profiling - GrabShutdownProfileAndShutdown"_ns
|
||||
: "Not profiling - GrabShutdownProfileAndShutdown"_ns);
|
||||
isProfiling ? "Profiling - GrabShutdownProfileAndShutdown"
|
||||
: "Not profiling - GrabShutdownProfileAndShutdown");
|
||||
ProfileAndAdditionalInformation shutdownProfileAndAdditionalInformation =
|
||||
mProfilerController->GrabShutdownProfileAndShutdown();
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
isProfiling ? "Profiling - Destroying ChildProfilerController"_ns
|
||||
: "Not profiling - Destroying ChildProfilerController"_ns);
|
||||
isProfiling ? "Profiling - Destroying ChildProfilerController"
|
||||
: "Not profiling - Destroying ChildProfilerController");
|
||||
mProfilerController = nullptr;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
isProfiling ? "Profiling - SendShutdownProfile (resovling)"_ns
|
||||
: "Not profiling - SendShutdownProfile (resolving)"_ns);
|
||||
isProfiling ? "Profiling - SendShutdownProfile (resovling)"
|
||||
: "Not profiling - SendShutdownProfile (resolving)");
|
||||
if (const size_t len = shutdownProfileAndAdditionalInformation.SizeOf();
|
||||
len >= size_t(IPC::Channel::kMaximumMessageSize)) {
|
||||
shutdownProfileAndAdditionalInformation.mProfile =
|
||||
@ -752,10 +751,10 @@ mozilla::ipc::IPCResult GMPChild::RecvShutdown(ShutdownResolver&& aResolver) {
|
||||
// Send the shutdown profile to the parent process through our own
|
||||
// message channel, which we know will survive for long enough.
|
||||
aResolver(shutdownProfileAndAdditionalInformation.mProfile);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
isProfiling ? "Profiling - SendShutdownProfile (resolved)"_ns
|
||||
: "Not profiling - SendShutdownProfile (resolved)"_ns);
|
||||
isProfiling ? "Profiling - SendShutdownProfile (resolved)"
|
||||
: "Not profiling - SendShutdownProfile (resolved)");
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
|
@ -84,7 +84,7 @@ class PassThroughGMPAdapter : public GMPAdapter {
|
||||
|
||||
bool GMPLoader::Load(const char* aUTF8LibPath, uint32_t aUTF8LibPathLen,
|
||||
const GMPPlatformAPI* aPlatformAPI, GMPAdapter* aAdapter) {
|
||||
CrashReporter::AutoAnnotateCrashReport autoLibPath(
|
||||
CrashReporter::AutoRecordAnnotation autoLibPath(
|
||||
CrashReporter::Annotation::GMPLibraryPath,
|
||||
nsDependentCString(aUTF8LibPath));
|
||||
|
||||
|
@ -770,13 +770,15 @@ bool GMPParent::EnsureProcessLoaded() {
|
||||
|
||||
void GMPParent::AddCrashAnnotations() {
|
||||
if (mCrashReporter) {
|
||||
mCrashReporter->AddAnnotation(CrashReporter::Annotation::GMPPlugin, true);
|
||||
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginFilename,
|
||||
NS_ConvertUTF16toUTF8(mName));
|
||||
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginName,
|
||||
mDisplayName);
|
||||
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginVersion,
|
||||
mVersion);
|
||||
mCrashReporter->AddAnnotationBool(CrashReporter::Annotation::GMPPlugin,
|
||||
true);
|
||||
mCrashReporter->AddAnnotationNSCString(
|
||||
CrashReporter::Annotation::PluginFilename,
|
||||
NS_ConvertUTF16toUTF8(mName));
|
||||
mCrashReporter->AddAnnotationNSCString(
|
||||
CrashReporter::Annotation::PluginName, mDisplayName);
|
||||
mCrashReporter->AddAnnotationNSCString(
|
||||
CrashReporter::Annotation::PluginVersion, mVersion);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,8 +170,8 @@ RefPtr<GenericNonExclusivePromise> RDDProcessManager::LaunchRDDProcess() {
|
||||
}
|
||||
mQueuedPrefs.Clear();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::RDDProcessStatus, "Running"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::RDDProcessStatus, "Running");
|
||||
|
||||
if (!CreateVideoBridge()) {
|
||||
mNumProcessAttempts++;
|
||||
@ -271,8 +271,8 @@ void RDDProcessManager::DestroyProcess() {
|
||||
mRDDChild = nullptr;
|
||||
mQueuedPrefs.Clear();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::RDDProcessStatus, "Destroyed"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::RDDProcessStatus, "Destroyed");
|
||||
}
|
||||
|
||||
bool RDDProcessManager::CreateContentBridge(
|
||||
|
@ -2271,7 +2271,7 @@ void QuotaManager::Shutdown() {
|
||||
quotaManager->mQuotaManagerShutdownSteps.get());
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::QuotaManagerShutdownTimeout, annotation);
|
||||
|
||||
MOZ_CRASH("Quota manager shutdown timed out");
|
||||
|
@ -611,12 +611,11 @@ void GPUProcessManager::OnProcessLaunchComplete(GPUProcessHost* aHost) {
|
||||
}
|
||||
mQueuedPrefs.Clear();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GPUProcessStatus, "Running"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::GPUProcessStatus, "Running");
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GPUProcessLaunchCount,
|
||||
static_cast<int>(mTotalProcessAttempts));
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::GPUProcessLaunchCount, mTotalProcessAttempts);
|
||||
|
||||
ReinitializeRendering();
|
||||
}
|
||||
@ -792,8 +791,9 @@ void GPUProcessManager::NotifyWebRenderError(wr::WebRenderError aError) {
|
||||
Telemetry::Accumulate(Telemetry::DEVICE_RESET_REASON, uint32_t(aReason));
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::DeviceResetReason, int(aReason));
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::DeviceResetReason,
|
||||
static_cast<uint32_t>(aReason));
|
||||
}
|
||||
|
||||
bool GPUProcessManager::OnDeviceReset(bool aTrackThreshold) {
|
||||
@ -1105,8 +1105,8 @@ void GPUProcessManager::DestroyProcess(bool aUnexpectedShutdown) {
|
||||
mBatteryObserver = nullptr;
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GPUProcessStatus, "Destroyed"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::GPUProcessStatus, "Destroyed");
|
||||
}
|
||||
|
||||
already_AddRefed<CompositorSession> GPUProcessManager::CreateTopLevelCompositor(
|
||||
|
@ -141,7 +141,7 @@ void gfx_wr_set_crash_annotation(mozilla::wr::CrashAnnotation aAnnotation,
|
||||
return;
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(annotation, nsDependentCString(aValue));
|
||||
CrashReporter::RecordAnnotationCString(annotation, aValue);
|
||||
}
|
||||
|
||||
void gfx_wr_clear_crash_annotation(mozilla::wr::CrashAnnotation aAnnotation) {
|
||||
@ -150,7 +150,7 @@ void gfx_wr_clear_crash_annotation(mozilla::wr::CrashAnnotation aAnnotation) {
|
||||
return;
|
||||
}
|
||||
|
||||
CrashReporter::RemoveCrashReportAnnotation(annotation);
|
||||
CrashReporter::UnrecordAnnotation(annotation);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1188,7 +1188,8 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvSetDisplayList(
|
||||
IsRootWebRenderBridgeParent());
|
||||
|
||||
if (!IsRootWebRenderBridgeParent()) {
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL, aTxnURL);
|
||||
CrashReporter::RecordAnnotationNSCString(CrashReporter::Annotation::URL,
|
||||
aTxnURL);
|
||||
}
|
||||
|
||||
CompositorBridgeParent* cbp = GetRootCompositorBridgeParent();
|
||||
@ -1330,7 +1331,8 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvEmptyTransaction(
|
||||
IsRootWebRenderBridgeParent());
|
||||
|
||||
if (!IsRootWebRenderBridgeParent()) {
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL, aTxnURL);
|
||||
CrashReporter::RecordAnnotationNSCString(CrashReporter::Annotation::URL,
|
||||
aTxnURL);
|
||||
}
|
||||
|
||||
AUTO_PROFILER_TRACING_MARKER("Paint", "EmptyTransaction", GRAPHICS);
|
||||
|
@ -156,7 +156,7 @@ DriverCrashGuard::~DriverCrashGuard() {
|
||||
dom::ContentChild::GetSingleton()->SendEndDriverCrashGuard(uint32_t(mType));
|
||||
}
|
||||
|
||||
CrashReporter::RemoveCrashReportAnnotation(
|
||||
CrashReporter::UnrecordAnnotation(
|
||||
CrashReporter::Annotation::GraphicsStartupTest);
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ void DriverCrashGuard::ActivateGuard() {
|
||||
// attribute a random parent process crash to a graphics problem in a child
|
||||
// process.
|
||||
if (mMode != Mode::Proxy) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::GraphicsStartupTest, true);
|
||||
}
|
||||
|
||||
|
@ -507,7 +507,7 @@ CGFontRef CTFontEntry::CreateOrCopyFontRef() {
|
||||
return mFontRef;
|
||||
}
|
||||
|
||||
CrashReporter::AutoAnnotateCrashReport autoFontName(
|
||||
CrashReporter::AutoRecordAnnotation autoFontName(
|
||||
CrashReporter::Annotation::FontName, mName);
|
||||
|
||||
// Create a new CGFont; caller will own the only reference to it.
|
||||
@ -676,7 +676,7 @@ bool CTFontEntry::SupportsOpenTypeFeature(Script aScript,
|
||||
return mHasAATSmallCaps;
|
||||
}
|
||||
|
||||
CrashReporter::AutoAnnotateCrashReport autoFontName(
|
||||
CrashReporter::AutoRecordAnnotation autoFontName(
|
||||
CrashReporter::Annotation::FontName, FamilyName());
|
||||
|
||||
AutoCFRelease<CTFontRef> ctFont =
|
||||
@ -1384,7 +1384,7 @@ gfxFontEntry* CoreTextFontList::LookupLocalFont(
|
||||
|
||||
AutoLock lock(mLock);
|
||||
|
||||
CrashReporter::AutoAnnotateCrashReport autoFontName(
|
||||
CrashReporter::AutoRecordAnnotation autoFontName(
|
||||
CrashReporter::Annotation::FontName, aFontName);
|
||||
|
||||
AutoCFRelease<CFStringRef> faceName = CreateCFStringForString(aFontName);
|
||||
@ -1461,7 +1461,7 @@ gfxFontEntry* CoreTextFontList::MakePlatformFont(const nsACString& aFontName,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CrashReporter::AutoAnnotateCrashReport autoFontName(
|
||||
CrashReporter::AutoRecordAnnotation autoFontName(
|
||||
CrashReporter::Annotation::FontName, aFontName);
|
||||
|
||||
AutoCFRelease<CGDataProviderRef> provider =
|
||||
@ -1521,7 +1521,7 @@ class CTFontInfo final : public FontInfoData {
|
||||
};
|
||||
|
||||
void CTFontInfo::LoadFontFamilyData(const nsACString& aFamilyName) {
|
||||
CrashReporter::AutoAnnotateCrashReport autoFontName(
|
||||
CrashReporter::AutoRecordAnnotation autoFontName(
|
||||
CrashReporter::Annotation::FontName, aFamilyName);
|
||||
// Prevent this from running concurrently with CGFont operations on the main
|
||||
// thread, because the macOS font cache is fragile with concurrent access.
|
||||
@ -1743,7 +1743,7 @@ void CoreTextFontList::GetFacesInitDataForFamily(
|
||||
const fontlist::Family* aFamily, nsTArray<fontlist::Face::InitData>& aFaces,
|
||||
bool aLoadCmaps) const {
|
||||
auto name = aFamily->Key().AsString(SharedFontList());
|
||||
CrashReporter::AutoAnnotateCrashReport autoFontName(
|
||||
CrashReporter::AutoRecordAnnotation autoFontName(
|
||||
CrashReporter::Annotation::FontName, name);
|
||||
|
||||
struct Context {
|
||||
|
@ -289,9 +289,8 @@ void CrashStatsLogForwarder::UpdateCrashReport() {
|
||||
<< " (t=" << std::get<2>(it) << ") ";
|
||||
}
|
||||
|
||||
nsCString reportString(message.str().c_str());
|
||||
nsresult annotated =
|
||||
CrashReporter::AnnotateCrashReport(mCrashCriticalKey, reportString);
|
||||
nsresult annotated = CrashReporter::RecordAnnotationCString(
|
||||
mCrashCriticalKey, message.str().c_str());
|
||||
|
||||
if (annotated != NS_OK) {
|
||||
printf("Crash Annotation %s: %s",
|
||||
@ -2693,7 +2692,7 @@ void gfxPlatform::InitWebRenderConfig() {
|
||||
StaticPrefs::GetPrefName_gfx_webrender_batched_upload_threshold()));
|
||||
|
||||
if (WebRenderResourcePathOverride()) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::IsWebRenderResourcePathOverridden, true);
|
||||
}
|
||||
|
||||
|
@ -87,8 +87,8 @@ void VRProcessManager::DestroyProcess() {
|
||||
mProcess = nullptr;
|
||||
mVRChild = nullptr;
|
||||
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::VRProcessStatus,
|
||||
"Destroyed"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::VRProcessStatus, "Destroyed");
|
||||
}
|
||||
|
||||
bool VRProcessManager::EnsureVRReady() {
|
||||
@ -134,8 +134,8 @@ void VRProcessManager::OnProcessLaunchComplete(VRProcessParent* aParent) {
|
||||
}
|
||||
mQueuedPrefs.Clear();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::VRProcessStatus,
|
||||
"Running"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::VRProcessStatus, "Running");
|
||||
}
|
||||
|
||||
void VRProcessManager::OnProcessUnexpectedShutdown(VRProcessParent* aParent) {
|
||||
|
@ -70,6 +70,8 @@ static mozilla::BackgroundHangMonitor* sBackgroundHangMonitor;
|
||||
#ifdef DEBUG
|
||||
static bool sRenderThreadEverStarted = false;
|
||||
#endif
|
||||
size_t RenderThread::sRendererCount = 0;
|
||||
size_t RenderThread::sActiveRendererCount = 0;
|
||||
|
||||
RenderThread::RenderThread(RefPtr<nsIThread> aThread)
|
||||
: mThread(std::move(aThread)),
|
||||
@ -150,6 +152,11 @@ void RenderThread::Start(uint32_t aNamespace) {
|
||||
}
|
||||
|
||||
sRenderThread = new RenderThread(thread);
|
||||
CrashReporter::RegisterAnnotationUSize(
|
||||
CrashReporter::Annotation::GraphicsNumRenderers, &sRendererCount);
|
||||
CrashReporter::RegisterAnnotationUSize(
|
||||
CrashReporter::Annotation::GraphicsNumActiveRenderers,
|
||||
&sActiveRendererCount);
|
||||
#ifdef XP_WIN
|
||||
widget::WinCompositorWindowThread::Start();
|
||||
#endif
|
||||
@ -322,9 +329,7 @@ void RenderThread::AddRenderer(wr::WindowId aWindowId,
|
||||
}
|
||||
|
||||
mRenderers[aWindowId] = std::move(aRenderer);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GraphicsNumRenderers,
|
||||
(unsigned int)mRenderers.size());
|
||||
sRendererCount = mRenderers.size();
|
||||
|
||||
auto windows = mWindowInfos.Lock();
|
||||
windows->emplace(AsUint64(aWindowId), new WindowInfo());
|
||||
@ -342,9 +347,7 @@ void RenderThread::RemoveRenderer(wr::WindowId aWindowId) {
|
||||
}
|
||||
|
||||
mRenderers.erase(aWindowId);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GraphicsNumRenderers,
|
||||
(unsigned int)mRenderers.size());
|
||||
sRendererCount = mRenderers.size();
|
||||
|
||||
if (mRenderers.empty()) {
|
||||
if (mHandlingDeviceReset) {
|
||||
@ -391,7 +394,7 @@ size_t RenderThread::RendererCount() const {
|
||||
return mRenderers.size();
|
||||
}
|
||||
|
||||
size_t RenderThread::ActiveRendererCount() const {
|
||||
void RenderThread::UpdateActiveRendererCount() {
|
||||
MOZ_ASSERT(IsInRenderThread());
|
||||
size_t num_active = 0;
|
||||
for (const auto& it : mRenderers) {
|
||||
@ -399,7 +402,7 @@ size_t RenderThread::ActiveRendererCount() const {
|
||||
num_active++;
|
||||
}
|
||||
}
|
||||
return num_active;
|
||||
sActiveRendererCount = num_active;
|
||||
}
|
||||
|
||||
void RenderThread::WrNotifierEvent_WakeUp(WrWindowId aWindowId,
|
||||
@ -863,9 +866,7 @@ void RenderThread::Pause(wr::WindowId aWindowId) {
|
||||
auto& renderer = it->second;
|
||||
renderer->Pause();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GraphicsNumActiveRenderers,
|
||||
(unsigned int)ActiveRendererCount());
|
||||
UpdateActiveRendererCount();
|
||||
}
|
||||
|
||||
bool RenderThread::Resume(wr::WindowId aWindowId) {
|
||||
@ -882,9 +883,7 @@ bool RenderThread::Resume(wr::WindowId aWindowId) {
|
||||
auto& renderer = it->second;
|
||||
bool resumed = renderer->Resume();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GraphicsNumActiveRenderers,
|
||||
(unsigned int)ActiveRendererCount());
|
||||
UpdateActiveRendererCount();
|
||||
|
||||
return resumed;
|
||||
}
|
||||
|
@ -293,7 +293,8 @@ class RenderThread final {
|
||||
bool SyncObjectNeeded();
|
||||
|
||||
size_t RendererCount() const;
|
||||
size_t ActiveRendererCount() const;
|
||||
size_t ActiveRendererCount() const { return sActiveRendererCount; };
|
||||
void UpdateActiveRendererCount();
|
||||
|
||||
void BeginRecordingForWindow(wr::WindowId aWindowId,
|
||||
const TimeStamp& aRecordingStart,
|
||||
@ -307,6 +308,9 @@ class RenderThread final {
|
||||
bool GetPowerIsCharging();
|
||||
|
||||
private:
|
||||
static size_t sRendererCount;
|
||||
static size_t sActiveRendererCount;
|
||||
|
||||
enum class RenderTextureOp {
|
||||
PrepareForUse,
|
||||
NotifyForUse,
|
||||
|
@ -138,9 +138,8 @@ void BackgroundChildImpl::ProcessingError(Result aCode, const char* aReason) {
|
||||
MOZ_CRASH("Unknown error code!");
|
||||
}
|
||||
|
||||
nsDependentCString reason(aReason);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ipc_channel_error, reason);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ipc_channel_error, aReason);
|
||||
|
||||
MOZ_CRASH_UNSAFE_PRINTF("%s: %s", abortMessage.get(), aReason);
|
||||
}
|
||||
|
@ -148,8 +148,8 @@ void BackgroundParentImpl::ProcessingError(Result aCode, const char* aReason) {
|
||||
GetIPCChannel()->InduceConnectionError();
|
||||
}
|
||||
} else {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ipc_channel_error, reason);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ipc_channel_error, aReason);
|
||||
|
||||
MOZ_CRASH("in-process BackgroundParent abort due to IPC error");
|
||||
}
|
||||
|
@ -153,27 +153,26 @@ void CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType,
|
||||
getter_AddRefs(promise));
|
||||
}
|
||||
|
||||
void CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey,
|
||||
bool aValue) {
|
||||
void CrashReporterHost::AddAnnotationBool(CrashReporter::Annotation aKey,
|
||||
bool aValue) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == CrashReporter::AnnotationType::Boolean,
|
||||
"Wrong annotation type");
|
||||
mExtraAnnotations[aKey] = aValue ? "1"_ns : "0"_ns;
|
||||
}
|
||||
|
||||
void CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey,
|
||||
int aValue) {
|
||||
void CrashReporterHost::AddAnnotationU32(CrashReporter::Annotation aKey,
|
||||
uint32_t aValue) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == CrashReporter::AnnotationType::U32,
|
||||
"Wrong annotation type");
|
||||
nsAutoCString valueString;
|
||||
valueString.AppendInt(aValue);
|
||||
mExtraAnnotations[aKey] = valueString;
|
||||
}
|
||||
|
||||
void CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey,
|
||||
unsigned int aValue) {
|
||||
nsAutoCString valueString;
|
||||
valueString.AppendInt(aValue);
|
||||
mExtraAnnotations[aKey] = valueString;
|
||||
}
|
||||
|
||||
void CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey,
|
||||
const nsACString& aValue) {
|
||||
void CrashReporterHost::AddAnnotationNSCString(CrashReporter::Annotation aKey,
|
||||
const nsACString& aValue) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == CrashReporter::AnnotationType::String,
|
||||
"Wrong annotation type");
|
||||
mExtraAnnotations[aKey] = aValue;
|
||||
}
|
||||
|
||||
|
@ -84,10 +84,10 @@ class CrashReporterHost {
|
||||
return CrashReporter::GetIDFromMinidump(targetDump, mDumpID);
|
||||
}
|
||||
|
||||
void AddAnnotation(CrashReporter::Annotation aKey, bool aValue);
|
||||
void AddAnnotation(CrashReporter::Annotation aKey, int aValue);
|
||||
void AddAnnotation(CrashReporter::Annotation aKey, unsigned int aValue);
|
||||
void AddAnnotation(CrashReporter::Annotation aKey, const nsACString& aValue);
|
||||
void AddAnnotationBool(CrashReporter::Annotation aKey, bool aValue);
|
||||
void AddAnnotationU32(CrashReporter::Annotation aKey, uint32_t aValue);
|
||||
void AddAnnotationNSCString(CrashReporter::Annotation aKey,
|
||||
const nsACString& aValue);
|
||||
|
||||
bool HasMinidump() const { return !mDumpID.IsEmpty(); }
|
||||
const nsString& MinidumpID() const {
|
||||
|
@ -65,12 +65,12 @@ struct EnumSerializer {
|
||||
static bool Read(MessageReader* aReader, paramType* aResult) {
|
||||
uintParamType value;
|
||||
if (!ReadParam(aReader, &value)) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCReadErrorReason, "Bad iter"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::IPCReadErrorReason, "Bad iter");
|
||||
return false;
|
||||
} else if (!EnumValidator::IsLegalValue(value)) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCReadErrorReason, "Illegal value"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::IPCReadErrorReason, "Illegal value");
|
||||
return false;
|
||||
}
|
||||
*aResult = paramType(value);
|
||||
|
@ -473,9 +473,8 @@ MessageChannel::~MessageChannel() {
|
||||
// would be unsafe to invoke our listener's callbacks, and we may be being
|
||||
// destroyed on a thread other than `mWorkerThread`.
|
||||
if (!IsClosedLocked()) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCFatalErrorProtocol,
|
||||
nsDependentCString(mName));
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::IPCFatalErrorProtocol, mName);
|
||||
switch (mChannelState) {
|
||||
case ChannelConnected:
|
||||
MOZ_CRASH(
|
||||
|
@ -98,12 +98,10 @@ void PortLink::SendMessage(UniquePtr<Message> aMessage) {
|
||||
mChan->mMonitor->AssertCurrentThreadOwns();
|
||||
|
||||
if (aMessage->size() > IPC::Channel::kMaximumMessageSize) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCMessageName,
|
||||
nsDependentCString(aMessage->name()));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCMessageSize,
|
||||
static_cast<unsigned int>(aMessage->size()));
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::IPCMessageName, aMessage->name());
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::IPCMessageSize, aMessage->size());
|
||||
MOZ_CRASH("IPC message size is too large");
|
||||
}
|
||||
aMessage->AssertAsLargeAsHeader();
|
||||
|
@ -170,12 +170,10 @@ void NodeChannel::AcceptInvite(const NodeName& aRealName,
|
||||
|
||||
void NodeChannel::SendMessage(UniquePtr<IPC::Message> aMessage) {
|
||||
if (aMessage->size() > IPC::Channel::kMaximumMessageSize) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCMessageName,
|
||||
nsDependentCString(aMessage->name()));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCMessageSize,
|
||||
static_cast<unsigned int>(aMessage->size()));
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::IPCMessageName, aMessage->name());
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::IPCMessageSize, aMessage->size());
|
||||
MOZ_CRASH("IPC message size is too large");
|
||||
}
|
||||
aMessage->AssertAsLargeAsHeader();
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
#include "nsAppRunner.h"
|
||||
#include "mozilla/AppShutdown.h"
|
||||
#include "mozilla/ipc/CrashReporterClient.h"
|
||||
#include "mozilla/ipc/IOThreadChild.h"
|
||||
#include "mozilla/GeckoArgs.h"
|
||||
|
||||
@ -29,6 +28,8 @@ namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
ProcessChild* ProcessChild::gProcessChild;
|
||||
StaticMutex ProcessChild::gIPCShutdownStateLock;
|
||||
nsCString ProcessChild::gIPCShutdownStateAnnotation;
|
||||
|
||||
static Atomic<bool> sExpectingShutdown(false);
|
||||
|
||||
@ -39,6 +40,9 @@ ProcessChild::ProcessChild(ProcessId aParentPid, const nsID& aMessageChannelId)
|
||||
mMessageChannelId(aMessageChannelId) {
|
||||
MOZ_ASSERT(mUILoop, "UILoop should be created by now");
|
||||
MOZ_ASSERT(!gProcessChild, "should only be one ProcessChild");
|
||||
CrashReporter::RegisterAnnotationNSCString(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
&gIPCShutdownStateAnnotation);
|
||||
gProcessChild = this;
|
||||
}
|
||||
|
||||
@ -101,14 +105,14 @@ ProcessChild::~ProcessChild() {
|
||||
// we'll get into late IPC shutdown with processes still running.
|
||||
SleepIfEnv("MOZ_TEST_CHILD_EXIT_HANG");
|
||||
#endif
|
||||
gIPCShutdownStateAnnotation = ""_ns;
|
||||
gProcessChild = nullptr;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void ProcessChild::NotifiedImpendingShutdown() {
|
||||
sExpectingShutdown = true;
|
||||
CrashReporter::AppendToCrashReportAnnotation(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
ProcessChild::AppendToIPCShutdownStateAnnotation(
|
||||
"NotifiedImpendingShutdown"_ns);
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,12 @@ class ProcessChild : public ChildProcess {
|
||||
|
||||
static bool ExpectingShutdown();
|
||||
|
||||
static void AppendToIPCShutdownStateAnnotation(const nsCString& aStr) {
|
||||
StaticMutexAutoLock lock(gIPCShutdownStateLock);
|
||||
gIPCShutdownStateAnnotation.Append(" - "_ns);
|
||||
gIPCShutdownStateAnnotation.Append(aStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit *now*. Do not shut down XPCOM, do not pass Go, do not run
|
||||
* static destructors, do not collect $200.
|
||||
@ -63,6 +69,9 @@ class ProcessChild : public ChildProcess {
|
||||
|
||||
private:
|
||||
static ProcessChild* gProcessChild;
|
||||
static StaticMutex gIPCShutdownStateLock;
|
||||
static nsCString gIPCShutdownStateAnnotation
|
||||
MOZ_GUARDED_BY(gIPCShutdownStateLock);
|
||||
|
||||
MessageLoop* mUILoop;
|
||||
ProcessId mParentPid;
|
||||
|
@ -74,22 +74,21 @@ IPCResult IPCResult::FailImpl(NotNull<IProtocol*> actor, const char* where,
|
||||
}
|
||||
|
||||
void AnnotateSystemError() {
|
||||
int64_t error = 0;
|
||||
uint32_t error = 0;
|
||||
#if defined(XP_WIN)
|
||||
error = ::GetLastError();
|
||||
#else
|
||||
error = errno;
|
||||
#endif
|
||||
if (error) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCSystemError,
|
||||
nsPrintfCString("%" PRId64, error));
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::IPCSystemError, error);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
void AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error) {
|
||||
CrashReporter::AnnotateCrashReport(tag, error);
|
||||
CrashReporter::RecordAnnotationU32(tag, static_cast<uint32_t>(error));
|
||||
}
|
||||
#endif // defined(XP_MACOSX)
|
||||
|
||||
@ -191,8 +190,8 @@ void FatalError(const char* aMsg, bool aIsParent) {
|
||||
// this process if we're off the main thread.
|
||||
formattedMessage.AppendLiteral("\". Intentionally crashing.");
|
||||
NS_ERROR(formattedMessage.get());
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCFatalErrorMsg, nsDependentCString(aMsg));
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::IPCFatalErrorMsg, aMsg);
|
||||
AnnotateSystemError();
|
||||
#ifndef FUZZING
|
||||
MOZ_CRASH("IPC FatalError in the parent process!");
|
||||
|
@ -214,8 +214,8 @@ RefPtr<GenericNonExclusivePromise> UtilityProcessManager::LaunchProcess(
|
||||
}
|
||||
p->mQueuedPrefs.Clear();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::UtilityProcessStatus, "Running"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::UtilityProcessStatus, "Running");
|
||||
|
||||
return GenericNonExclusivePromise::CreateAndResolve(true, __func__);
|
||||
},
|
||||
@ -592,8 +592,8 @@ void UtilityProcessManager::DestroyProcess(SandboxingKind aSandbox) {
|
||||
|
||||
mProcesses[aSandbox] = nullptr;
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::UtilityProcessStatus, "Destroyed"_ns);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::UtilityProcessStatus, "Destroyed");
|
||||
|
||||
if (NoMoreProcesses()) {
|
||||
sSingleton = nullptr;
|
||||
|
@ -148,7 +148,7 @@ void UtilityProcessParent::ActorDestroy(ActorDestroyReason aWhy) {
|
||||
actorsName += ", "_ns + GetUtilityActorName(actor);
|
||||
}
|
||||
}
|
||||
mCrashReporter->AddAnnotation(
|
||||
mCrashReporter->AddAnnotationNSCString(
|
||||
CrashReporter::Annotation::UtilityActorsName, actorsName);
|
||||
}
|
||||
#endif
|
||||
|
@ -39,7 +39,7 @@ static void AnnotateCrashReportWithJSException(JSContext* aCx,
|
||||
aURI, file.get(), line, column,
|
||||
NS_ConvertUTF16toUTF8(msg).get());
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::JSModuleLoadError, errorString);
|
||||
}
|
||||
}
|
||||
|
@ -292,8 +292,8 @@ void nsStandardURL::SanityCheck() {
|
||||
(uint32_t)mExtension.mPos, (int32_t)mExtension.mLen,
|
||||
(uint32_t)mQuery.mPos, (int32_t)mQuery.mLen, (uint32_t)mRef.mPos,
|
||||
(int32_t)mRef.mLen);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URLSegments,
|
||||
msg);
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::URLSegments, msg);
|
||||
|
||||
MOZ_CRASH("nsStandardURL::SanityCheck failed");
|
||||
}
|
||||
|
@ -10,15 +10,15 @@
|
||||
|
||||
#include "ipc/EnumSerializer.h"
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "ipc/IPCMessageUtilsSpecializations.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "nsIDNSService.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsITRRSkipReason.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsString.h"
|
||||
#include "prio.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
#include "ipc/IPCMessageUtilsSpecializations.h"
|
||||
#include "nsITRRSkipReason.h"
|
||||
#include "nsIDNSService.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
@ -92,9 +92,9 @@ struct ParamTraits<mozilla::net::NetAddr> {
|
||||
#endif
|
||||
} else {
|
||||
if (XRE_IsParentProcess()) {
|
||||
nsPrintfCString msg("%d", aParam.raw.family);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::UnknownNetAddrSocketFamily, msg);
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::UnknownNetAddrSocketFamily,
|
||||
aParam.raw.family);
|
||||
}
|
||||
|
||||
MOZ_CRASH("Unknown socket family");
|
||||
|
@ -104,10 +104,9 @@ nsIXULRuntime::ContentWin32kLockdownState GetContentWin32kLockdownState() {
|
||||
static auto getLockdownState = [] {
|
||||
auto state = GetWin32kLockdownState();
|
||||
|
||||
const char* stateStr = ContentWin32kLockdownStateToString(state);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ContentSandboxWin32kState,
|
||||
nsDependentCString(stateStr));
|
||||
ContentWin32kLockdownStateToString(state));
|
||||
|
||||
return state;
|
||||
};
|
||||
|
@ -727,7 +727,7 @@ Service::Observe(nsISupports*, const char* aTopic, const char16_t*) {
|
||||
if (!connections[i]->isClosed()) {
|
||||
// getFilename is only the leaf name for the database file,
|
||||
// so it shouldn't contain privacy-sensitive information.
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::StorageConnectionNotClosed,
|
||||
connections[i]->getFilename());
|
||||
printf_stderr("Storage connection not closed: %s",
|
||||
|
@ -606,9 +606,7 @@ void nsTerminator::UpdateTelemetry() {
|
||||
|
||||
void nsTerminator::UpdateCrashReport(const char* aTopic) {
|
||||
// In case of crash, we wish to know where in shutdown we are
|
||||
nsAutoCString report(aTopic);
|
||||
|
||||
Unused << CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ShutdownProgress, report);
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ShutdownProgress, aTopic);
|
||||
}
|
||||
} // namespace mozilla
|
||||
|
@ -49,6 +49,16 @@ const AnnotationSkipValue kSkipIfList[] = {
|
||||
${skiplist}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the type of a crash annotation.
|
||||
*
|
||||
* @param aAnnotation a crash annotation
|
||||
* @returns The type of this annotation
|
||||
*/
|
||||
static inline AnnotationType TypeOfAnnotation(Annotation aAnnotation) {
|
||||
return kAnnotationTypes[static_cast<uint32_t>(aAnnotation)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string representation of a crash annotation.
|
||||
*
|
||||
@ -97,9 +107,17 @@ class AnnotationWriter {
|
||||
public:
|
||||
virtual void Write(Annotation aAnnotation, const char* aValue,
|
||||
size_t aLen = 0) = 0;
|
||||
virtual void Write(Annotation aAnnotation, bool aValue) = 0;
|
||||
virtual void Write(Annotation aAnnotation, uint64_t aValue) = 0;
|
||||
};
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
||||
extern void RecordDllAnnotations(bool* aBlocklistInitFailed,
|
||||
bool* aUser32BeforeBlocklist);
|
||||
|
||||
#endif // XP_WIN
|
||||
|
||||
} // namespace CrashReporter
|
||||
|
||||
#endif // CrashAnnotations_h
|
||||
|
@ -66,7 +66,8 @@ a ``google_breakpad::ExceptionHandler`` instance and it's stored as
|
||||
As the application runs, various other systems may write *annotations*
|
||||
or *notes* to the crash reporter to indicate state of the application,
|
||||
help with possible reasons for a current or future crash, etc. These are
|
||||
performed via ``CrashReporter::AnnotateCrashReport()`` and
|
||||
performed via ``CrashReporter::RecordAnnotation*()``,
|
||||
``CrashReporter::RegisterAnnotation*()`` functions and
|
||||
``CrashReporter::AppendAppNotesToCrashReport()`` from
|
||||
``nsExceptionHandler.h``.
|
||||
|
||||
|
@ -3,30 +3,53 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use nsstring::nsCString;
|
||||
use std::{ffi::c_void, sync::Mutex};
|
||||
use std::{
|
||||
alloc::{self, Layout},
|
||||
cmp::min,
|
||||
ffi::{c_char, c_void, CStr},
|
||||
ptr::{copy_nonoverlapping, null_mut},
|
||||
sync::Mutex,
|
||||
};
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
use std::arch::global_asm;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum AnnotationContents {
|
||||
Empty,
|
||||
NSCString,
|
||||
NSCStringPointer,
|
||||
CStringPointer,
|
||||
CString,
|
||||
CharBuffer,
|
||||
USize,
|
||||
ByteBuffer(u32),
|
||||
OwnedByteBuffer(u32),
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Annotation {
|
||||
pub id: u32,
|
||||
pub contents: AnnotationContents,
|
||||
pub address: usize,
|
||||
}
|
||||
|
||||
impl Drop for Annotation {
|
||||
fn drop(&mut self) {
|
||||
match self.contents {
|
||||
AnnotationContents::OwnedByteBuffer(len) => {
|
||||
if (self.address != 0) && (len > 0) {
|
||||
let align = min(usize::next_power_of_two(len as usize), 32);
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align_unchecked(len as usize, align);
|
||||
alloc::dealloc(self.address as *mut u8, layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Nothing to do
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AnnotationTable {
|
||||
data: Vec<Annotation>,
|
||||
magic_number: u32,
|
||||
@ -222,98 +245,126 @@ pub struct MozAnnotationNote {
|
||||
pub ehdr: isize,
|
||||
}
|
||||
|
||||
/// Register an annotation containing an nsCString.
|
||||
/// Returns false if the annotation is already present (and doesn't change it).
|
||||
///
|
||||
/// This function will be exposed to C++
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mozannotation_register_nscstring(id: u32, address: *const nsCString) -> bool {
|
||||
fn store_annotation<T>(id: u32, contents: AnnotationContents, address: *const T) -> *const T {
|
||||
let address = match contents {
|
||||
AnnotationContents::OwnedByteBuffer(len) => {
|
||||
if !address.is_null() && (len > 0) {
|
||||
// Copy the contents of this annotation, we'll own the copy
|
||||
let len = len as usize;
|
||||
let align = min(usize::next_power_of_two(len), 32);
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align_unchecked(len as usize, align);
|
||||
let src = address as *mut u8;
|
||||
let dst = alloc::alloc(layout);
|
||||
copy_nonoverlapping(src, dst, len);
|
||||
dst
|
||||
}
|
||||
} else {
|
||||
null_mut()
|
||||
}
|
||||
}
|
||||
_ => address as *mut u8,
|
||||
};
|
||||
|
||||
let annotations = &mut MOZANNOTATIONS.lock().unwrap().data;
|
||||
let old = if let Some(existing) = annotations.iter_mut().find(|e| e.id == id) {
|
||||
let old = match existing.contents {
|
||||
AnnotationContents::OwnedByteBuffer(len) => {
|
||||
// If we owned the previous value of this annotation we must free it.
|
||||
if (existing.address != 0) && (len > 0) {
|
||||
let len = len as usize;
|
||||
let align = min(usize::next_power_of_two(len), 32);
|
||||
unsafe {
|
||||
let layout = Layout::from_size_align_unchecked(len, align);
|
||||
alloc::dealloc(existing.address as *mut u8, layout);
|
||||
}
|
||||
}
|
||||
null_mut::<T>()
|
||||
}
|
||||
_ => existing.address as *mut T,
|
||||
};
|
||||
|
||||
if annotations.iter().any(|e| e.id == id) {
|
||||
return false;
|
||||
}
|
||||
existing.contents = contents;
|
||||
existing.address = address as usize;
|
||||
old
|
||||
} else {
|
||||
annotations.push(Annotation {
|
||||
id,
|
||||
contents,
|
||||
address: address as usize,
|
||||
});
|
||||
null_mut::<T>()
|
||||
};
|
||||
|
||||
annotations.push(Annotation {
|
||||
id,
|
||||
contents: AnnotationContents::NSCString,
|
||||
address: address as usize,
|
||||
});
|
||||
|
||||
true
|
||||
old
|
||||
}
|
||||
|
||||
/// Register an annotation containing a null-terminated string.
|
||||
/// Returns false if the annotation is already present (and doesn't change it).
|
||||
/// Register a pointer to an nsCString string.
|
||||
///
|
||||
/// Returns the value of the previously registered annotation or null.
|
||||
///
|
||||
/// This function will be exposed to C++
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mozannotation_register_cstring(
|
||||
pub extern "C" fn mozannotation_register_nscstring(
|
||||
id: u32,
|
||||
address: *const *const std::ffi::c_char,
|
||||
) -> bool {
|
||||
let annotations = &mut MOZANNOTATIONS.lock().unwrap().data;
|
||||
|
||||
if annotations.iter().any(|e| e.id == id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
annotations.push(Annotation {
|
||||
id,
|
||||
contents: AnnotationContents::CString,
|
||||
address: address as usize,
|
||||
});
|
||||
|
||||
true
|
||||
address: *const nsCString,
|
||||
) -> *const nsCString {
|
||||
store_annotation(id, AnnotationContents::NSCStringPointer, address)
|
||||
}
|
||||
|
||||
/// Register an annotation pointing to a buffer holding a null-terminated string.
|
||||
/// Returns false if the annotation is already present (and doesn't change it).
|
||||
/// Create a copy of the provided string with a specified size that will be
|
||||
/// owned by the crate, and register a pointer to it.
|
||||
///
|
||||
/// This function will be exposed to C++
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mozannotation_register_char_buffer(
|
||||
pub extern "C" fn mozannotation_record_nscstring_from_raw_parts(
|
||||
id: u32,
|
||||
address: *const std::ffi::c_char,
|
||||
) -> bool {
|
||||
let annotations = &mut MOZANNOTATIONS.lock().unwrap().data;
|
||||
|
||||
if annotations.iter().any(|e| e.id == id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
annotations.push(Annotation {
|
||||
address: *const u8,
|
||||
size: usize,
|
||||
) {
|
||||
store_annotation(
|
||||
id,
|
||||
contents: AnnotationContents::CharBuffer,
|
||||
address: address as usize,
|
||||
});
|
||||
|
||||
true
|
||||
AnnotationContents::OwnedByteBuffer(size as u32),
|
||||
address,
|
||||
);
|
||||
}
|
||||
|
||||
/// Register an annotation pointing to a variable of type usize.
|
||||
/// Returns false if the annotation is already present (and doesn't change it).
|
||||
/// Register a pointer to a pointer to a nul-terminated string.
|
||||
///
|
||||
/// Returns the value of the previously registered annotation or null.
|
||||
///
|
||||
/// This function will be exposed to C++
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mozannotation_register_usize(id: u32, address: *const usize) -> bool {
|
||||
let annotations = &mut MOZANNOTATIONS.lock().unwrap().data;
|
||||
|
||||
if annotations.iter().any(|e| e.id == id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
annotations.push(Annotation {
|
||||
id,
|
||||
contents: AnnotationContents::USize,
|
||||
address: address as usize,
|
||||
});
|
||||
|
||||
true
|
||||
pub extern "C" fn mozannotation_register_cstring_ptr(
|
||||
id: u32,
|
||||
address: *const *const c_char,
|
||||
) -> *const *const c_char {
|
||||
store_annotation(id, AnnotationContents::CStringPointer, address)
|
||||
}
|
||||
|
||||
/// Register an annotation pointing to a fixed size buffer.
|
||||
/// Returns false if the annotation is already present (and doesn't change it).
|
||||
/// Register a pointer to a nul-terminated string.
|
||||
///
|
||||
/// Returns the value of the previously registered annotation or null.
|
||||
///
|
||||
/// This function will be exposed to C++
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mozannotation_register_cstring(id: u32, address: *const c_char) -> *const c_char {
|
||||
store_annotation(id, AnnotationContents::CString, address)
|
||||
}
|
||||
|
||||
/// Create a copy of the provided nul-terminated string which will be owned by
|
||||
/// the crate, and register a pointer to it.
|
||||
///
|
||||
/// This function will be exposed to C++
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mozannotation_record_cstring(id: u32, address: *const c_char) {
|
||||
let len = unsafe { CStr::from_ptr(address).to_bytes().len() };
|
||||
store_annotation(id, AnnotationContents::OwnedByteBuffer(len as u32), address);
|
||||
}
|
||||
|
||||
/// Register a pointer to a fixed size buffer.
|
||||
///
|
||||
/// Returns the value of the previously registered annotation or null.
|
||||
///
|
||||
/// This function will be exposed to C++
|
||||
#[no_mangle]
|
||||
@ -321,34 +372,50 @@ pub extern "C" fn mozannotation_register_bytebuffer(
|
||||
id: u32,
|
||||
address: *const c_void,
|
||||
size: u32,
|
||||
) -> bool {
|
||||
let annotations = &mut MOZANNOTATIONS.lock().unwrap().data;
|
||||
|
||||
if annotations.iter().any(|e| e.id == id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
annotations.push(Annotation {
|
||||
id,
|
||||
contents: AnnotationContents::ByteBuffer(size),
|
||||
address: address as usize,
|
||||
});
|
||||
|
||||
true
|
||||
) -> *const c_void {
|
||||
store_annotation(id, AnnotationContents::ByteBuffer(size), address)
|
||||
}
|
||||
|
||||
/// Unregister a crash annotation. Returns false if the annotation is not present.
|
||||
/// Create a copy of the provided buffer which will be owned by the crate, and
|
||||
/// register a pointer to it.
|
||||
///
|
||||
/// This function will be exposed to C++
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mozannotation_unregister(id: u32) -> bool {
|
||||
let annotations = &mut MOZANNOTATIONS.lock().unwrap().data;
|
||||
let index = annotations.iter().position(|e| e.id == id);
|
||||
pub extern "C" fn mozannotation_record_bytebuffer(id: u32, address: *const c_void, size: u32) {
|
||||
store_annotation(id, AnnotationContents::OwnedByteBuffer(size), address);
|
||||
}
|
||||
|
||||
if let Some(index) = index {
|
||||
annotations.remove(index);
|
||||
return true;
|
||||
/// Unregister a crash annotation. Returns the previously registered pointer or
|
||||
/// null if none was present. Return null also if the crate owned the
|
||||
/// annotations' buffer.
|
||||
///
|
||||
/// This function will be exposed to C++
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mozannotation_unregister(id: u32) -> *const c_void {
|
||||
store_annotation(id, AnnotationContents::Empty, null_mut())
|
||||
}
|
||||
|
||||
/// Returns the raw address of an annotation if it has been registered or NULL
|
||||
/// if it hasn't.
|
||||
///
|
||||
/// This function will be exposed to C++
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mozannotation_get_contents(id: u32, contents: *mut AnnotationContents) -> usize {
|
||||
let annotations = &MOZANNOTATIONS.lock().unwrap().data;
|
||||
if let Some(annotation) = annotations.iter().find(|e| e.id == id) {
|
||||
if annotation.contents == AnnotationContents::Empty {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsafe { *contents = annotation.contents };
|
||||
return annotation.address;
|
||||
}
|
||||
|
||||
false
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn mozannotation_clear_all() {
|
||||
let annotations = &mut MOZANNOTATIONS.lock().unwrap().data;
|
||||
annotations.clear();
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ license = "MPL-2.0"
|
||||
goblin = { version = "0.7", features = ["elf32", "elf64", "pe32", "pe64"] }
|
||||
memoffset = "0.8"
|
||||
mozannotation_client = { path = "../mozannotation_client/" }
|
||||
nsstring = { path = "../../../xpcom/rust/nsstring/" }
|
||||
thin-vec = { version = "0.2.7", features = ["gecko-ffi"] }
|
||||
thiserror = "1.0.38"
|
||||
|
||||
|
@ -9,22 +9,21 @@ use crate::errors::*;
|
||||
use process_reader::ProcessReader;
|
||||
|
||||
use mozannotation_client::{Annotation, AnnotationContents, AnnotationMutex};
|
||||
use nsstring::nsCString;
|
||||
use std::cmp::min;
|
||||
use std::iter::FromIterator;
|
||||
use std::mem::size_of;
|
||||
use std::mem::{size_of, ManuallyDrop};
|
||||
use std::ptr::null_mut;
|
||||
use thin_vec::ThinVec;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub enum AnnotationData {
|
||||
Empty,
|
||||
UsizeData(usize),
|
||||
NSCStringData(nsCString),
|
||||
ByteBuffer(ThinVec<u8>),
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct CAnnotation {
|
||||
id: u32,
|
||||
data: AnnotationData,
|
||||
@ -100,33 +99,33 @@ pub fn retrieve_annotations(
|
||||
|
||||
// Read an annotation from the given address
|
||||
fn read_annotation(reader: &ProcessReader, address: usize) -> Result<CAnnotation, ReadError> {
|
||||
let raw_annotation = reader.copy_object::<Annotation>(address)?;
|
||||
let raw_annotation = ManuallyDrop::new(reader.copy_object::<Annotation>(address)?);
|
||||
let mut annotation = CAnnotation {
|
||||
id: raw_annotation.id,
|
||||
data: AnnotationData::Empty,
|
||||
};
|
||||
|
||||
if raw_annotation.address == 0 {
|
||||
return Ok(annotation);
|
||||
}
|
||||
|
||||
match raw_annotation.contents {
|
||||
AnnotationContents::Empty => {}
|
||||
AnnotationContents::NSCString => {
|
||||
AnnotationContents::NSCStringPointer => {
|
||||
let string = copy_nscstring(reader, raw_annotation.address)?;
|
||||
annotation.data = AnnotationData::NSCStringData(string);
|
||||
annotation.data = AnnotationData::ByteBuffer(string);
|
||||
}
|
||||
AnnotationContents::CStringPointer => {
|
||||
let buffer = copy_null_terminated_string_pointer(reader, raw_annotation.address)?;
|
||||
annotation.data = AnnotationData::ByteBuffer(buffer);
|
||||
}
|
||||
AnnotationContents::CString => {
|
||||
let string = copy_null_terminated_string_pointer(reader, raw_annotation.address)?;
|
||||
annotation.data = AnnotationData::NSCStringData(string);
|
||||
let buffer = copy_null_terminated_string(reader, raw_annotation.address)?;
|
||||
annotation.data = AnnotationData::ByteBuffer(buffer);
|
||||
}
|
||||
AnnotationContents::CharBuffer => {
|
||||
let string = copy_null_terminated_string(reader, raw_annotation.address)?;
|
||||
annotation.data = AnnotationData::NSCStringData(string);
|
||||
}
|
||||
AnnotationContents::USize => {
|
||||
let value = reader.copy_object::<usize>(raw_annotation.address)?;
|
||||
annotation.data = AnnotationData::UsizeData(value);
|
||||
}
|
||||
AnnotationContents::ByteBuffer(size) => {
|
||||
let value = copy_bytebuffer(reader, raw_annotation.address, size)?;
|
||||
annotation.data = AnnotationData::ByteBuffer(value);
|
||||
AnnotationContents::ByteBuffer(size) | AnnotationContents::OwnedByteBuffer(size) => {
|
||||
let buffer = copy_bytebuffer(reader, raw_annotation.address, size)?;
|
||||
annotation.data = AnnotationData::ByteBuffer(buffer);
|
||||
}
|
||||
};
|
||||
|
||||
@ -136,7 +135,7 @@ fn read_annotation(reader: &ProcessReader, address: usize) -> Result<CAnnotation
|
||||
fn copy_null_terminated_string_pointer(
|
||||
reader: &ProcessReader,
|
||||
address: usize,
|
||||
) -> Result<nsCString, ReadError> {
|
||||
) -> Result<ThinVec<u8>, ReadError> {
|
||||
let buffer_address = reader.copy_object::<usize>(address)?;
|
||||
copy_null_terminated_string(reader, buffer_address)
|
||||
}
|
||||
@ -144,7 +143,7 @@ fn copy_null_terminated_string_pointer(
|
||||
fn copy_null_terminated_string(
|
||||
reader: &ProcessReader,
|
||||
address: usize,
|
||||
) -> Result<nsCString, ReadError> {
|
||||
) -> Result<ThinVec<u8>, ReadError> {
|
||||
// Try copying the string word-by-word first, this is considerably faster
|
||||
// than one byte at a time.
|
||||
if let Ok(string) = copy_null_terminated_string_word_by_word(reader, address) {
|
||||
@ -155,7 +154,7 @@ fn copy_null_terminated_string(
|
||||
// at a time. It's slow but it might work in situations where the string
|
||||
// alignment causes word-by-word access to straddle page boundaries.
|
||||
let mut length = 0;
|
||||
let mut string = Vec::<u8>::new();
|
||||
let mut string = ThinVec::<u8>::new();
|
||||
|
||||
loop {
|
||||
let char = reader.copy_object::<u8>(address + length)?;
|
||||
@ -167,33 +166,34 @@ fn copy_null_terminated_string(
|
||||
}
|
||||
}
|
||||
|
||||
Ok(nsCString::from(&string[..length]))
|
||||
Ok(string)
|
||||
}
|
||||
|
||||
fn copy_null_terminated_string_word_by_word(
|
||||
reader: &ProcessReader,
|
||||
address: usize,
|
||||
) -> Result<nsCString, ReadError> {
|
||||
) -> Result<ThinVec<u8>, ReadError> {
|
||||
const WORD_SIZE: usize = size_of::<usize>();
|
||||
let mut length = 0;
|
||||
let mut string = Vec::<u8>::new();
|
||||
let mut string = ThinVec::<u8>::new();
|
||||
|
||||
loop {
|
||||
let mut array = reader.copy_array::<u8>(address + length, WORD_SIZE)?;
|
||||
let array = reader.copy_array::<u8>(address + length, WORD_SIZE)?;
|
||||
let null_terminator = array.iter().position(|&e| e == 0);
|
||||
length += null_terminator.unwrap_or(WORD_SIZE);
|
||||
string.append(&mut array);
|
||||
string.extend(array.into_iter());
|
||||
|
||||
if null_terminator.is_some() {
|
||||
string.truncate(length);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(nsCString::from(&string[..length]))
|
||||
Ok(string)
|
||||
}
|
||||
|
||||
fn copy_nscstring(reader: &ProcessReader, address: usize) -> Result<nsCString, ReadError> {
|
||||
// HACK: This assumes the layout of the string
|
||||
fn copy_nscstring(reader: &ProcessReader, address: usize) -> Result<ThinVec<u8>, ReadError> {
|
||||
// HACK: This assumes the layout of the nsCString object
|
||||
let length_address = address + size_of::<usize>();
|
||||
let length = reader.copy_object::<u32>(length_address)?;
|
||||
|
||||
@ -201,9 +201,9 @@ fn copy_nscstring(reader: &ProcessReader, address: usize) -> Result<nsCString, R
|
||||
let data_address = reader.copy_object::<usize>(address)?;
|
||||
reader
|
||||
.copy_array::<u8>(data_address, length as _)
|
||||
.map(nsCString::from)
|
||||
.map(ThinVec::from)
|
||||
} else {
|
||||
Ok(nsCString::new())
|
||||
Ok(ThinVec::<u8>::new())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,10 +4,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "nsExceptionHandlerUtils.h"
|
||||
|
||||
namespace CrashReporter {
|
||||
|
||||
@ -38,41 +35,71 @@ nsresult SetupExtraData(nsIFile* aAppDataDirectory,
|
||||
|
||||
nsresult UnsetExceptionHandler() { return NS_ERROR_NOT_IMPLEMENTED; }
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, bool data) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
const bool* RegisterAnnotationBool(Annotation aKey, const bool* aData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, int data) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
const uint32_t* RegisterAnnotationU32(Annotation aKey, const uint32_t* aData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, unsigned int data) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
const uint64_t* RegisterAnnotationU64(Annotation aKey, const uint64_t* aData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, const nsACString& data) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
const size_t* RegisterAnnotationUSize(Annotation aKey, const size_t* aData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult AppendToCrashReportAnnotation(Annotation key, const nsACString& data) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
const char* RegisterAnnotationCString(Annotation aKey, const char* aData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsresult RemoveCrashReportAnnotation(Annotation key) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
const nsCString* RegisterAnnotationNSCString(Annotation aKey,
|
||||
const nsCString* aData) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
AutoAnnotateCrashReport::AutoAnnotateCrashReport(Annotation key, bool data) {}
|
||||
nsresult RecordAnnotationBool(Annotation aKey, bool aData) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoAnnotateCrashReport::AutoAnnotateCrashReport(Annotation key, int data) {}
|
||||
nsresult RecordAnnotationU32(Annotation aKey, uint32_t aData) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoAnnotateCrashReport::AutoAnnotateCrashReport(Annotation key,
|
||||
unsigned data) {}
|
||||
nsresult RecordAnnotationU64(Annotation aKey, uint64_t aData) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoAnnotateCrashReport::AutoAnnotateCrashReport(Annotation key,
|
||||
const nsACString& data) {}
|
||||
nsresult RecordAnnotationUSize(Annotation aKey, size_t aData) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
AutoAnnotateCrashReport::~AutoAnnotateCrashReport() {}
|
||||
nsresult RecordAnnotationCString(Annotation aKey, const char* aData) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult RecordAnnotationNSCString(Annotation aKey, const nsACString& aData) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult RecordAnnotationNSString(Annotation aKey, const nsAString& aData) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult UnrecordAnnotation(Annotation aKey) { return NS_ERROR_FAILURE; }
|
||||
|
||||
AutoRecordAnnotation::AutoRecordAnnotation(Annotation key, bool data) {}
|
||||
|
||||
AutoRecordAnnotation::AutoRecordAnnotation(Annotation key, int data) {}
|
||||
|
||||
AutoRecordAnnotation::AutoRecordAnnotation(Annotation key, unsigned data) {}
|
||||
|
||||
AutoRecordAnnotation::AutoRecordAnnotation(Annotation key,
|
||||
const nsACString& data) {}
|
||||
|
||||
AutoRecordAnnotation::~AutoRecordAnnotation() {}
|
||||
|
||||
void MergeCrashAnnotations(AnnotationTable& aDst, const AnnotationTable& aSrc) {
|
||||
}
|
||||
|
@ -201,6 +201,7 @@ static const char kCrashMainID[] = "crash.main.3\n";
|
||||
|
||||
static google_breakpad::ExceptionHandler* gExceptionHandler = nullptr;
|
||||
static mozilla::Atomic<bool> gEncounteredChildException(false);
|
||||
static nsCString gServerURL;
|
||||
|
||||
static xpstring pendingDirectory;
|
||||
static xpstring crashReporterPath;
|
||||
@ -232,9 +233,7 @@ static const char* androidStartServiceCommand = nullptr;
|
||||
#endif
|
||||
|
||||
// this holds additional data sent via the API
|
||||
static Mutex* crashReporterAPILock;
|
||||
static Mutex* notesFieldLock;
|
||||
static AnnotationTable crashReporterAPIData_Table;
|
||||
static nsCString* notesField = nullptr;
|
||||
static bool isGarbageCollecting;
|
||||
static uint32_t eventloopNestingLevel = 0;
|
||||
@ -656,11 +655,17 @@ class JSONAnnotationWriter : public AnnotationWriter {
|
||||
size_t len = aLen ? aLen : my_strlen(aValue);
|
||||
const char* annotationStr = AnnotationToString(aAnnotation);
|
||||
|
||||
WritePrefix();
|
||||
mWriter.WriteBuffer(annotationStr, my_strlen(annotationStr));
|
||||
WriteSeparator();
|
||||
WriteEscapedString(aValue, len);
|
||||
WriteSuffix();
|
||||
if (len && CrashReporter::ShouldIncludeAnnotation(aAnnotation, aValue)) {
|
||||
WritePrefix();
|
||||
mWriter.WriteBuffer(annotationStr, my_strlen(annotationStr));
|
||||
WriteSeparator();
|
||||
WriteEscapedString(aValue, len);
|
||||
WriteSuffix();
|
||||
}
|
||||
};
|
||||
|
||||
void Write(Annotation aAnnotation, bool aValue) override {
|
||||
Write(aAnnotation, aValue ? "1" : "0", 1);
|
||||
};
|
||||
|
||||
void Write(Annotation aAnnotation, uint64_t aValue) override {
|
||||
@ -789,8 +794,10 @@ static void WritePHCAddrInfo(AnnotationWriter& writer,
|
||||
break;
|
||||
}
|
||||
writer.Write(Annotation::PHCKind, kindString);
|
||||
writer.Write(Annotation::PHCBaseAddress, uintptr_t(aAddrInfo->mBaseAddr));
|
||||
writer.Write(Annotation::PHCUsableSize, aAddrInfo->mUsableSize);
|
||||
writer.Write(Annotation::PHCBaseAddress,
|
||||
reinterpret_cast<uint64_t>(aAddrInfo->mBaseAddr));
|
||||
writer.Write(Annotation::PHCUsableSize,
|
||||
static_cast<uint64_t>(aAddrInfo->mUsableSize));
|
||||
|
||||
WritePHCStackTrace(writer, Annotation::PHCAllocStack,
|
||||
aAddrInfo->mAllocStack);
|
||||
@ -879,7 +886,8 @@ static void AnnotateMemoryStatus(AnnotationWriter& aWriter) {
|
||||
MEMORYSTATUSEX statex;
|
||||
statex.dwLength = sizeof(statex);
|
||||
if (GlobalMemoryStatusEx(&statex)) {
|
||||
aWriter.Write(Annotation::SystemMemoryUsePercentage, statex.dwMemoryLoad);
|
||||
aWriter.Write(Annotation::SystemMemoryUsePercentage,
|
||||
static_cast<uint64_t>(statex.dwMemoryLoad));
|
||||
aWriter.Write(Annotation::TotalVirtualMemory, statex.ullTotalVirtual);
|
||||
aWriter.Write(Annotation::AvailableVirtualMemory, statex.ullAvailVirtual);
|
||||
aWriter.Write(Annotation::TotalPhysicalMemory, statex.ullTotalPhys);
|
||||
@ -888,9 +896,11 @@ static void AnnotateMemoryStatus(AnnotationWriter& aWriter) {
|
||||
|
||||
PERFORMANCE_INFORMATION info;
|
||||
if (K32GetPerformanceInfo(&info, sizeof(info))) {
|
||||
aWriter.Write(Annotation::TotalPageFile, info.CommitLimit * info.PageSize);
|
||||
aWriter.Write(Annotation::TotalPageFile,
|
||||
static_cast<uint64_t>(info.CommitLimit * info.PageSize));
|
||||
aWriter.Write(Annotation::AvailablePageFile,
|
||||
(info.CommitLimit - info.CommitTotal) * info.PageSize);
|
||||
static_cast<uint64_t>((info.CommitLimit - info.CommitTotal) *
|
||||
info.PageSize));
|
||||
}
|
||||
}
|
||||
#elif XP_MACOSX
|
||||
@ -916,9 +926,9 @@ static void WriteAvailableMemoryStatus(AnnotationWriter& aWriter) {
|
||||
if (host_statistics64(host, HOST_VM_INFO64, (host_info64_t)&stats, &count) ==
|
||||
KERN_SUCCESS) {
|
||||
aWriter.Write(Annotation::AvailablePhysicalMemory,
|
||||
stats.free_count * vm_page_size);
|
||||
static_cast<uint64_t>(stats.free_count * vm_page_size));
|
||||
aWriter.Write(Annotation::PurgeablePhysicalMemory,
|
||||
stats.purgeable_count * vm_page_size);
|
||||
static_cast<uint64_t>(stats.purgeable_count * vm_page_size));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1199,7 +1209,8 @@ static void AnnotateMemoryStatus(AnnotationWriter& aWriter) {
|
||||
pointOfInterest.dest->value = value;
|
||||
}
|
||||
if (pointOfInterest.annotation != Annotation::Count) {
|
||||
aWriter.Write(pointOfInterest.annotation, value);
|
||||
aWriter.Write(pointOfInterest.annotation,
|
||||
static_cast<uint64_t>(value));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1224,7 +1235,8 @@ static void AnnotateMemoryStatus(AnnotationWriter& aWriter) {
|
||||
}
|
||||
if (memTotal.found && swapTotal.found) {
|
||||
// If available, attempt to determine the available virtual memory.
|
||||
aWriter.Write(Annotation::TotalPageFile, memTotal.value + swapTotal.value);
|
||||
aWriter.Write(Annotation::TotalPageFile,
|
||||
static_cast<uint64_t>(memTotal.value + swapTotal.value));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1356,40 +1368,6 @@ static bool LaunchCrashHandlerService(const XP_CHAR* aProgramPath,
|
||||
|
||||
#endif
|
||||
|
||||
static void WriteMainThreadRunnableName(AnnotationWriter& aWriter) {
|
||||
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
|
||||
// Only try to collect this information if the main thread is crashing.
|
||||
if (!SignalSafeIsMainThread()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: Use `my_memchr` over `strlen` to ensure we don't run off the end of
|
||||
// the buffer if it contains no null bytes. This is used instead of `strnlen`,
|
||||
// as breakpad's linux support library doesn't export a `my_strnlen` function.
|
||||
const char* buf = nsThread::sMainThreadRunnableName.begin();
|
||||
size_t len = nsThread::kRunnableNameBufSize;
|
||||
if (const void* end = my_memchr(buf, '\0', len)) {
|
||||
len = static_cast<const char*>(end) - buf;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
aWriter.Write(Annotation::MainThreadRunnableName, buf, len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void WriteOOMAllocationSize(AnnotationWriter& aWriter) {
|
||||
if (gOOMAllocationSize) {
|
||||
aWriter.Write(Annotation::OOMAllocationSize, gOOMAllocationSize);
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteMozCrashReason(AnnotationWriter& aWriter) {
|
||||
if (gMozCrashReason != nullptr) {
|
||||
aWriter.Write(Annotation::MozCrashReason, gMozCrashReason);
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteAnnotations(AnnotationWriter& aWriter,
|
||||
const AnnotationTable& aAnnotations) {
|
||||
for (auto key : MakeEnumeratedRange(Annotation::Count)) {
|
||||
@ -1408,13 +1386,65 @@ static void WriteAnnotationsForMainProcessCrash(PlatformWriter& pw,
|
||||
const phc::AddrInfo* addrInfo,
|
||||
time_t crashTime) {
|
||||
JSONAnnotationWriter writer(pw);
|
||||
WriteAnnotations(writer, crashReporterAPIData_Table);
|
||||
|
||||
for (auto key : MakeEnumeratedRange(Annotation::Count)) {
|
||||
AnnotationContents contents = {};
|
||||
size_t address =
|
||||
mozannotation_get_contents(static_cast<uint32_t>(key), &contents);
|
||||
if (address != 0) {
|
||||
switch (TypeOfAnnotation(key)) {
|
||||
case AnnotationType::String:
|
||||
switch (contents.tag) {
|
||||
case AnnotationContents::Tag::NSCStringPointer: {
|
||||
const nsCString* string =
|
||||
reinterpret_cast<const nsCString*>(address);
|
||||
writer.Write(key, string->Data(), string->Length());
|
||||
} break;
|
||||
case AnnotationContents::Tag::CStringPointer:
|
||||
address = *(reinterpret_cast<size_t*>(address));
|
||||
if (address == 0) {
|
||||
break;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case AnnotationContents::Tag::CString: {
|
||||
writer.Write(key, reinterpret_cast<const char*>(address));
|
||||
} break;
|
||||
case AnnotationContents::Tag::ByteBuffer:
|
||||
writer.Write(key, reinterpret_cast<const char*>(address),
|
||||
static_cast<size_t>(contents.byte_buffer._0));
|
||||
break;
|
||||
case AnnotationContents::Tag::OwnedByteBuffer:
|
||||
writer.Write(key, reinterpret_cast<const char*>(address),
|
||||
static_cast<size_t>(contents.owned_byte_buffer._0));
|
||||
break;
|
||||
case AnnotationContents::Tag::Empty:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AnnotationType::Boolean:
|
||||
writer.Write(key, *reinterpret_cast<const bool*>(address));
|
||||
break;
|
||||
case AnnotationType::U32:
|
||||
writer.Write(key, static_cast<uint64_t>(
|
||||
*reinterpret_cast<uint32_t*>(address)));
|
||||
break;
|
||||
case AnnotationType::U64:
|
||||
writer.Write(key, *reinterpret_cast<uint64_t*>(address));
|
||||
break;
|
||||
case AnnotationType::USize:
|
||||
writer.Write(
|
||||
key, static_cast<uint64_t>(*reinterpret_cast<size_t*>(address)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WriteSynthesizedAnnotations(writer);
|
||||
writer.Write(Annotation::CrashTime, uint64_t(crashTime));
|
||||
|
||||
if (inactiveStateStart) {
|
||||
writer.Write(Annotation::LastInteractionDuration,
|
||||
crashTime - inactiveStateStart);
|
||||
static_cast<uint64_t>(crashTime - inactiveStateStart));
|
||||
}
|
||||
|
||||
double uptimeTS = (TimeStamp::NowLoRes() - TimeStamp::ProcessCreation())
|
||||
@ -1427,34 +1457,14 @@ static void WriteAnnotationsForMainProcessCrash(PlatformWriter& pw,
|
||||
if (lastCrashTime != 0) {
|
||||
uint64_t timeSinceLastCrash = crashTime - lastCrashTime;
|
||||
|
||||
if (timeSinceLastCrash != 0) {
|
||||
writer.Write(Annotation::SecondsSinceLastCrash, timeSinceLastCrash);
|
||||
}
|
||||
}
|
||||
|
||||
if (isGarbageCollecting) {
|
||||
writer.Write(Annotation::IsGarbageCollecting, "1");
|
||||
}
|
||||
|
||||
if (eventloopNestingLevel > 0) {
|
||||
writer.Write(Annotation::EventLoopNestingLevel, eventloopNestingLevel);
|
||||
writer.Write(Annotation::SecondsSinceLastCrash, timeSinceLastCrash);
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) && defined(HAS_DLL_BLOCKLIST)
|
||||
// HACK: The DLL blocklist code will manually write its annotations as JSON
|
||||
DllBlocklist_WriteNotes(writer);
|
||||
DllBlocklist_WriteNotes();
|
||||
#endif // defined(XP_WIN) && defined(HAS_DLL_BLOCKLIST)
|
||||
|
||||
WriteMozCrashReason(writer);
|
||||
|
||||
WriteMainThreadRunnableName(writer);
|
||||
|
||||
WriteOOMAllocationSize(writer);
|
||||
|
||||
if (gTexturesSize) {
|
||||
writer.Write(Annotation::TextureUsage, gTexturesSize);
|
||||
}
|
||||
|
||||
#ifdef MOZ_PHC
|
||||
WritePHCAddrInfo(writer, addrInfo);
|
||||
#endif
|
||||
@ -1889,19 +1899,50 @@ static nsresult LocateExecutable(nsIFile* aXREDirectory, const nsAString& aName,
|
||||
|
||||
#endif // !defined(MOZ_WIDGET_ANDROID)
|
||||
|
||||
static void InitializeAnnotationFacilities() {
|
||||
crashReporterAPILock = new Mutex("crashReporterAPILock");
|
||||
static void InitializeAppNotes() {
|
||||
notesFieldLock = new Mutex("notesFieldLock");
|
||||
notesField = new nsCString();
|
||||
}
|
||||
|
||||
static void TeardownAnnotationFacilities() {
|
||||
std::fill(crashReporterAPIData_Table.begin(),
|
||||
crashReporterAPIData_Table.end(), ""_ns);
|
||||
|
||||
delete crashReporterAPILock;
|
||||
crashReporterAPILock = nullptr;
|
||||
// Register crash annotations that are present in both main and child processes
|
||||
static void RegisterAnnotations() {
|
||||
mozannotation_register_cstring_ptr(
|
||||
static_cast<uint32_t>(Annotation::MozCrashReason), &gMozCrashReason);
|
||||
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
|
||||
mozannotation_register_cstring(
|
||||
static_cast<uint32_t>(Annotation::MainThreadRunnableName),
|
||||
&nsThread::sMainThreadRunnableName[0]);
|
||||
#endif
|
||||
mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(Annotation::EventLoopNestingLevel),
|
||||
&eventloopNestingLevel, sizeof(uint32_t));
|
||||
mozannotation_register_nscstring(static_cast<uint32_t>(Annotation::Notes),
|
||||
notesField);
|
||||
mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(Annotation::OOMAllocationSize), &gOOMAllocationSize,
|
||||
sizeof(size_t));
|
||||
mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(Annotation::IsGarbageCollecting),
|
||||
&isGarbageCollecting, sizeof(bool));
|
||||
mozannotation_register_nscstring(static_cast<uint32_t>(Annotation::ServerURL),
|
||||
&gServerURL);
|
||||
mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(Annotation::TextureUsage), &gTexturesSize,
|
||||
sizeof(size_t));
|
||||
#if defined(XP_WIN) && defined(HAS_DLL_BLOCKLIST)
|
||||
mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(Annotation::BlocklistInitFailed),
|
||||
DllBlocklist_GetBlocklistInitFailedPointer(), sizeof(bool));
|
||||
mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(Annotation::User32BeforeBlocklist),
|
||||
DllBlocklist_GetUser32BeforeBlocklistPointer(), sizeof(bool));
|
||||
mozannotation_register_cstring(
|
||||
static_cast<uint32_t>(Annotation::BlockedDllList),
|
||||
DllBlocklist_GetBlocklistWriterData());
|
||||
#endif // defined(XP_WIN) && defined(HAS_DLL_BLOCKLIST)
|
||||
}
|
||||
|
||||
static void TeardownAppNotes() {
|
||||
delete notesFieldLock;
|
||||
notesFieldLock = nullptr;
|
||||
|
||||
@ -1929,7 +1970,8 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory, bool force /*=false*/) {
|
||||
doReport = ShouldReport();
|
||||
|
||||
RegisterRuntimeExceptionModule();
|
||||
InitializeAnnotationFacilities();
|
||||
InitializeAppNotes();
|
||||
RegisterAnnotations();
|
||||
|
||||
#if !defined(MOZ_WIDGET_ANDROID)
|
||||
// Locate the crash reporter executable
|
||||
@ -2055,10 +2097,8 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory, bool force /*=false*/) {
|
||||
#endif
|
||||
|
||||
// store application start time
|
||||
char timeString[32];
|
||||
time_t startupTime = time(nullptr);
|
||||
XP_TTOA(startupTime, timeString);
|
||||
AnnotateCrashReport(Annotation::StartupTime, nsDependentCString(timeString));
|
||||
RecordAnnotationU64(Annotation::StartupTime,
|
||||
static_cast<uint64_t>(time(nullptr)));
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// On OS X, many testers like to see the OS crash reporting dialog
|
||||
@ -2259,8 +2299,9 @@ nsresult SetupExtraData(nsIFile* aAppDataDirectory,
|
||||
|
||||
nsAutoCString data;
|
||||
if (NS_SUCCEEDED(GetOrInit(dataDirectory, "InstallTime"_ns + aBuildID, data,
|
||||
InitInstallTime)))
|
||||
AnnotateCrashReport(Annotation::InstallTime, data);
|
||||
InitInstallTime))) {
|
||||
RecordAnnotationNSCString(Annotation::InstallTime, data);
|
||||
}
|
||||
|
||||
// this is a little different, since we can't init it with anything,
|
||||
// since it's stored at crash time, and we can't annotate the
|
||||
@ -2314,7 +2355,8 @@ nsresult UnsetExceptionHandler() {
|
||||
|
||||
delete gExceptionHandler;
|
||||
|
||||
TeardownAnnotationFacilities();
|
||||
gServerURL = "";
|
||||
TeardownAppNotes();
|
||||
|
||||
if (!gExceptionHandler) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
@ -2330,73 +2372,201 @@ nsresult UnsetExceptionHandler() {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, bool data) {
|
||||
return AnnotateCrashReport(key, data ? "1"_ns : "0"_ns);
|
||||
const bool* RegisterAnnotationBool(Annotation aKey, const bool* aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::Boolean,
|
||||
"Wrong annotation type");
|
||||
|
||||
if (!GetEnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<const bool*>(mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(aKey), aData, sizeof(bool)));
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, int data) {
|
||||
nsAutoCString dataString;
|
||||
dataString.AppendInt(data);
|
||||
const uint32_t* RegisterAnnotationU32(Annotation aKey, const uint32_t* aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::U32,
|
||||
"Wrong annotation type");
|
||||
|
||||
return AnnotateCrashReport(key, dataString);
|
||||
if (!GetEnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<const uint32_t*>(mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(aKey), aData, sizeof(uint32_t)));
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, unsigned int data) {
|
||||
nsAutoCString dataString;
|
||||
dataString.AppendInt(data);
|
||||
const uint64_t* RegisterAnnotationU64(Annotation aKey, const uint64_t* aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::U64,
|
||||
"Wrong annotation type");
|
||||
|
||||
return AnnotateCrashReport(key, dataString);
|
||||
if (!GetEnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<const uint64_t*>(mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(aKey), aData, sizeof(uint64_t)));
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, const nsACString& data) {
|
||||
if (!GetEnabled()) return NS_ERROR_NOT_INITIALIZED;
|
||||
const size_t* RegisterAnnotationUSize(Annotation aKey, const size_t* aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::USize,
|
||||
"Wrong annotation type");
|
||||
|
||||
MutexAutoLock lock(*crashReporterAPILock);
|
||||
crashReporterAPIData_Table[key] = data;
|
||||
if (!GetEnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return reinterpret_cast<const size_t*>(mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(aKey), aData, sizeof(size_t)));
|
||||
}
|
||||
|
||||
const char* RegisterAnnotationCString(Annotation aKey, const char* aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::String,
|
||||
"Wrong annotation type");
|
||||
|
||||
if (!GetEnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mozannotation_register_cstring(static_cast<uint32_t>(aKey), aData);
|
||||
}
|
||||
|
||||
const nsCString* RegisterAnnotationNSCString(Annotation aKey,
|
||||
const nsCString* aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::String,
|
||||
"Wrong annotation type");
|
||||
|
||||
if (!GetEnabled()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return mozannotation_register_nscstring(static_cast<uint32_t>(aKey), aData);
|
||||
}
|
||||
|
||||
nsresult RecordAnnotationBool(Annotation aKey, bool aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::Boolean,
|
||||
"Wrong annotation type");
|
||||
|
||||
if (!GetEnabled()) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
mozannotation_record_bytebuffer(static_cast<uint32_t>(aKey), &aData,
|
||||
sizeof(bool));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult AppendToCrashReportAnnotation(Annotation key, const nsACString& data) {
|
||||
if (!GetEnabled()) return NS_ERROR_NOT_INITIALIZED;
|
||||
nsresult RecordAnnotationU32(Annotation aKey, uint32_t aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::U32,
|
||||
"Wrong annotation type");
|
||||
|
||||
MutexAutoLock lock(*crashReporterAPILock);
|
||||
nsAutoCString newString(crashReporterAPIData_Table[key]);
|
||||
newString.Append(" - "_ns);
|
||||
newString.Append(data);
|
||||
crashReporterAPIData_Table[key] = newString;
|
||||
if (!GetEnabled()) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
mozannotation_record_bytebuffer(static_cast<uint32_t>(aKey), &aData,
|
||||
sizeof(uint32_t));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RemoveCrashReportAnnotation(Annotation key) {
|
||||
return AnnotateCrashReport(key, ""_ns);
|
||||
nsresult RecordAnnotationU64(Annotation aKey, uint64_t aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::U64,
|
||||
"Wrong annotation type");
|
||||
|
||||
if (!GetEnabled()) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
mozannotation_record_bytebuffer(static_cast<uint64_t>(aKey), &aData,
|
||||
sizeof(uint64_t));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AutoAnnotateCrashReport::AutoAnnotateCrashReport(Annotation key, bool data)
|
||||
: AutoAnnotateCrashReport(key, data ? "1"_ns : "0"_ns) {}
|
||||
nsresult RecordAnnotationUSize(Annotation aKey, size_t aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::USize,
|
||||
"Wrong annotation type");
|
||||
|
||||
AutoAnnotateCrashReport::AutoAnnotateCrashReport(Annotation key, int data)
|
||||
: AutoAnnotateCrashReport(key, nsPrintfCString("%d", data)) {}
|
||||
if (!GetEnabled()) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
AutoAnnotateCrashReport::AutoAnnotateCrashReport(Annotation key, unsigned data)
|
||||
: AutoAnnotateCrashReport(key, nsPrintfCString("%u", data)) {}
|
||||
mozannotation_record_bytebuffer(static_cast<size_t>(aKey), &aData,
|
||||
sizeof(size_t));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AutoAnnotateCrashReport::AutoAnnotateCrashReport(Annotation key,
|
||||
const nsACString& data)
|
||||
: mKey(key) {
|
||||
nsresult RecordAnnotationCString(Annotation aKey, const char* aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::String,
|
||||
"Wrong annotation type");
|
||||
|
||||
if (!GetEnabled()) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
mozannotation_record_cstring(static_cast<uint32_t>(aKey), aData);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RecordAnnotationNSCString(Annotation aKey, const nsACString& aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::String,
|
||||
"Wrong annotation type");
|
||||
|
||||
if (!GetEnabled()) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
mozannotation_record_nscstring_from_raw_parts(
|
||||
static_cast<uint32_t>(aKey),
|
||||
reinterpret_cast<const uint8_t*>(aData.Data()), aData.Length());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RecordAnnotationNSString(Annotation aKey, const nsAString& aData) {
|
||||
MOZ_ASSERT(TypeOfAnnotation(aKey) == AnnotationType::String,
|
||||
"Wrong annotation type");
|
||||
|
||||
if (!GetEnabled()) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
nsAutoCString data = NS_ConvertUTF16toUTF8(aData);
|
||||
RecordAnnotationNSCString(aKey, data);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult UnrecordAnnotation(Annotation aKey) {
|
||||
if (!GetEnabled()) {
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
mozannotation_unregister(static_cast<uint32_t>(aKey));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// TODO: The first three methods here should be migrated to use native
|
||||
// types instead of turning the values into strings. They're not currently
|
||||
// used in mozilla-central so it doesn't really matter in the short term.
|
||||
AutoRecordAnnotation::AutoRecordAnnotation(Annotation key, bool data)
|
||||
: AutoRecordAnnotation(key, data ? "1"_ns : "0"_ns) {}
|
||||
|
||||
AutoRecordAnnotation::AutoRecordAnnotation(Annotation key, int data)
|
||||
: AutoRecordAnnotation(key, nsPrintfCString("%d", data)) {}
|
||||
|
||||
AutoRecordAnnotation::AutoRecordAnnotation(Annotation key, unsigned data)
|
||||
: AutoRecordAnnotation(key, nsPrintfCString("%u", data)) {}
|
||||
|
||||
AutoRecordAnnotation::AutoRecordAnnotation(Annotation key,
|
||||
const nsACString& data)
|
||||
: mKey(key), mCurrent(data) {
|
||||
if (GetEnabled()) {
|
||||
MutexAutoLock lock(*crashReporterAPILock);
|
||||
auto& entry = crashReporterAPIData_Table[mKey];
|
||||
mPrevious = std::move(entry);
|
||||
entry = data;
|
||||
mPrevious =
|
||||
mozannotation_register_nscstring(static_cast<uint32_t>(key), &mCurrent);
|
||||
}
|
||||
}
|
||||
|
||||
AutoAnnotateCrashReport::~AutoAnnotateCrashReport() {
|
||||
AutoRecordAnnotation::~AutoRecordAnnotation() {
|
||||
if (GetEnabled()) {
|
||||
MutexAutoLock lock(*crashReporterAPILock);
|
||||
crashReporterAPIData_Table[mKey] = std::move(mPrevious);
|
||||
Unused << mozannotation_register_nscstring(static_cast<uint32_t>(mKey),
|
||||
mPrevious);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2409,11 +2579,6 @@ void MergeCrashAnnotations(AnnotationTable& aDst, const AnnotationTable& aSrc) {
|
||||
}
|
||||
}
|
||||
|
||||
static void MergeContentCrashAnnotations(AnnotationTable& aDst) {
|
||||
MutexAutoLock lock(*crashReporterAPILock);
|
||||
MergeCrashAnnotations(aDst, crashReporterAPIData_Table);
|
||||
}
|
||||
|
||||
// Adds crash time, uptime and memory report annotations
|
||||
static void AddCommonAnnotations(AnnotationTable& aAnnotations) {
|
||||
const time_t crashTime = time(nullptr);
|
||||
@ -2461,23 +2626,8 @@ nsresult AppendAppNotesToCrashReport(const nsACString& data) {
|
||||
if (!GetEnabled()) return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
MutexAutoLock lock(*notesFieldLock);
|
||||
|
||||
notesField->Append(data);
|
||||
return AnnotateCrashReport(Annotation::Notes, *notesField);
|
||||
}
|
||||
|
||||
// Returns true if found, false if not found.
|
||||
static bool GetAnnotation(CrashReporter::Annotation key, nsACString& data) {
|
||||
if (!gExceptionHandler) return false;
|
||||
|
||||
MutexAutoLock lock(*crashReporterAPILock);
|
||||
const nsCString& entry = crashReporterAPIData_Table[key];
|
||||
if (entry.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = entry;
|
||||
return true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RegisterAppMemory(void* ptr, size_t length) {
|
||||
@ -2513,15 +2663,19 @@ void SetIncludeContextHeap(bool aValue) {
|
||||
}
|
||||
|
||||
bool GetServerURL(nsACString& aServerURL) {
|
||||
if (!gExceptionHandler) return false;
|
||||
if (!gExceptionHandler) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return GetAnnotation(CrashReporter::Annotation::ServerURL, aServerURL);
|
||||
aServerURL = gServerURL;
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult SetServerURL(const nsACString& aServerURL) {
|
||||
// store server URL with the API data
|
||||
// the client knows to handle this specially
|
||||
return AnnotateCrashReport(Annotation::ServerURL, aServerURL);
|
||||
// Store the server URL as an annotation, the crash reporter client knows how
|
||||
// to handle this specially.
|
||||
gServerURL = aServerURL;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult SetRestartArgs(int argc, char** argv) {
|
||||
@ -3107,12 +3261,89 @@ bool WriteExtraFile(const nsAString& id, const AnnotationTable& annotations) {
|
||||
return WriteExtraFile(pw, annotations);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool IsFixedSizeAnnotation(AnnotationContents& contents) {
|
||||
return ((contents.tag == AnnotationContents::Tag::ByteBuffer) &&
|
||||
(contents.byte_buffer._0 == sizeof(T))) ||
|
||||
((contents.tag == AnnotationContents::Tag::OwnedByteBuffer) &&
|
||||
(contents.owned_byte_buffer._0 == sizeof(T)));
|
||||
}
|
||||
|
||||
// This adds annotations that were populated in the main process but are not
|
||||
// present among the ones that were passed in. Additionally common annotations
|
||||
// which are present in every crash report are added, including crash time,
|
||||
// uptime, etc...
|
||||
static void AddSharedAnnotations(AnnotationTable& aAnnotations) {
|
||||
MergeContentCrashAnnotations(aAnnotations);
|
||||
for (auto key : MakeEnumeratedRange(Annotation::Count)) {
|
||||
AnnotationContents contents = {};
|
||||
nsAutoCString value;
|
||||
size_t address =
|
||||
mozannotation_get_contents(static_cast<uint32_t>(key), &contents);
|
||||
|
||||
if (address) {
|
||||
switch (TypeOfAnnotation(key)) {
|
||||
case AnnotationType::String:
|
||||
switch (contents.tag) {
|
||||
case AnnotationContents::Tag::Empty:
|
||||
break;
|
||||
case AnnotationContents::Tag::CStringPointer:
|
||||
address = *reinterpret_cast<size_t*>(address);
|
||||
if (address == 0) {
|
||||
break;
|
||||
}
|
||||
// FALLTHROUGH
|
||||
case AnnotationContents::Tag::CString:
|
||||
value.Assign(reinterpret_cast<const char*>(address));
|
||||
break;
|
||||
case AnnotationContents::Tag::NSCStringPointer:
|
||||
value.Assign(*reinterpret_cast<nsCString*>(address));
|
||||
break;
|
||||
case AnnotationContents::Tag::ByteBuffer:
|
||||
value.Assign(reinterpret_cast<const char*>(address),
|
||||
contents.byte_buffer._0);
|
||||
break;
|
||||
case AnnotationContents::Tag::OwnedByteBuffer:
|
||||
value.Assign(reinterpret_cast<const char*>(address),
|
||||
contents.owned_byte_buffer._0);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case AnnotationType::Boolean:
|
||||
if (IsFixedSizeAnnotation<bool>(contents)) {
|
||||
value.Assign(*reinterpret_cast<const bool*>(address) ? "1" : "0");
|
||||
}
|
||||
break;
|
||||
case AnnotationType::U32:
|
||||
if (IsFixedSizeAnnotation<uint32_t>(contents)) {
|
||||
value.AppendInt(*reinterpret_cast<const uint32_t*>(address));
|
||||
}
|
||||
break;
|
||||
case AnnotationType::U64:
|
||||
if (IsFixedSizeAnnotation<uint64_t>(contents)) {
|
||||
value.AppendInt(*reinterpret_cast<const uint64_t*>(address));
|
||||
}
|
||||
break;
|
||||
case AnnotationType::USize:
|
||||
if (IsFixedSizeAnnotation<size_t>(contents)) {
|
||||
#ifdef XP_MACOSX
|
||||
// macOS defines size_t as unsigned long, which causes ambiguity
|
||||
// when it comes to function overload, use a 64-bit integer instead
|
||||
value.AppendInt(*reinterpret_cast<const uint64_t*>(address));
|
||||
#else
|
||||
value.AppendInt(*reinterpret_cast<const size_t*>(address));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!value.IsEmpty() && aAnnotations[key].IsEmpty() &&
|
||||
ShouldIncludeAnnotation(key, value.get())) {
|
||||
aAnnotations[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AddCommonAnnotations(aAnnotations);
|
||||
}
|
||||
|
||||
@ -3126,54 +3357,71 @@ static void AddChildProcessAnnotations(
|
||||
}
|
||||
|
||||
for (const auto& annotation : *aChildAnnotations) {
|
||||
switch (annotation.data.tag) {
|
||||
case AnnotationData::Tag::Empty:
|
||||
break;
|
||||
Annotation id = static_cast<Annotation>(annotation.id);
|
||||
const AnnotationData& data = annotation.data;
|
||||
|
||||
case AnnotationData::Tag::UsizeData:
|
||||
if (annotation.id ==
|
||||
static_cast<uint32_t>(Annotation::OOMAllocationSize)) {
|
||||
// We need to special-case OOMAllocationSize here because it should
|
||||
// not be added if its value is 0. We'll come up with a more general
|
||||
// method of skipping ignored values for crash annotations in the
|
||||
// follow-ups.
|
||||
if (annotation.data.usize_data._0 != 0) {
|
||||
aAnnotations[static_cast<Annotation>(annotation.id)] =
|
||||
nsPrintfCString("%zu", annotation.data.usize_data._0);
|
||||
}
|
||||
} else {
|
||||
aAnnotations[static_cast<Annotation>(annotation.id)] =
|
||||
nsPrintfCString("%zu", annotation.data.usize_data._0);
|
||||
}
|
||||
break;
|
||||
|
||||
case AnnotationData::Tag::NSCStringData: {
|
||||
const auto& string = annotation.data.nsc_string_data._0;
|
||||
if (!string.IsEmpty()) {
|
||||
aAnnotations[static_cast<Annotation>(annotation.id)] =
|
||||
annotation.data.nsc_string_data._0;
|
||||
}
|
||||
} break;
|
||||
|
||||
case AnnotationData::Tag::ByteBuffer: {
|
||||
if (annotation.id ==
|
||||
static_cast<uint32_t>(Annotation::PHCBaseAddress)) {
|
||||
if ((id == Annotation::PHCBaseAddress) &&
|
||||
(data.tag == AnnotationData::Tag::ByteBuffer)) {
|
||||
// PHC is special for now, let's deal with it here
|
||||
#ifdef MOZ_PHC
|
||||
const auto& buffer = annotation.data.byte_buffer._0;
|
||||
mozilla::phc::AddrInfo addr_info;
|
||||
memcpy(&addr_info, buffer.Elements(), sizeof(addr_info));
|
||||
PopulatePHCAnnotations(aAnnotations, &addr_info);
|
||||
const auto& buffer = data.byte_buffer._0;
|
||||
mozilla::phc::AddrInfo addr_info;
|
||||
memcpy(&addr_info, buffer.Elements(), sizeof(addr_info));
|
||||
PopulatePHCAnnotations(aAnnotations, &addr_info);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
if (data.tag == AnnotationData::Tag::Empty) {
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoCString value;
|
||||
const uint8_t* buffer = data.byte_buffer._0.Elements();
|
||||
const size_t length = data.byte_buffer._0.Length();
|
||||
|
||||
switch (TypeOfAnnotation(id)) {
|
||||
case AnnotationType::String:
|
||||
value.Assign(reinterpret_cast<const char*>(buffer), length);
|
||||
break;
|
||||
case AnnotationType::Boolean:
|
||||
if (length == sizeof(bool)) {
|
||||
value.Assign(*reinterpret_cast<const bool*>(buffer) ? "1" : "0");
|
||||
}
|
||||
break;
|
||||
case AnnotationType::U32:
|
||||
if (length == sizeof(uint32_t)) {
|
||||
value.AppendInt(*reinterpret_cast<const uint32_t*>(buffer));
|
||||
}
|
||||
break;
|
||||
case AnnotationType::U64:
|
||||
if (length == sizeof(uint64_t)) {
|
||||
value.AppendInt(*reinterpret_cast<const uint64_t*>(buffer));
|
||||
}
|
||||
break;
|
||||
case AnnotationType::USize:
|
||||
if (length == sizeof(size_t)) {
|
||||
#ifdef XP_MACOSX
|
||||
// macOS defines size_t as unsigned long, which causes ambiguity
|
||||
// when it comes to function overload, use a 64-bit integer instead
|
||||
value.AppendInt(*reinterpret_cast<const uint64_t*>(buffer));
|
||||
#else
|
||||
value.AppendInt(*reinterpret_cast<const size_t*>(buffer));
|
||||
#endif
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!value.IsEmpty() && ShouldIncludeAnnotation(id, value.get())) {
|
||||
aAnnotations[id] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It really only makes sense to call this function when
|
||||
// ShouldReport() is true.
|
||||
// Uses dumpFile's filename to generate memoryReport's filename (same name with
|
||||
// a different extension)
|
||||
// Uses dumpFile's filename to generate memoryReport's filename (same name
|
||||
// with a different extension)
|
||||
static bool MoveToPending(nsIFile* dumpFile, nsIFile* extraFile,
|
||||
nsIFile* memoryReport) {
|
||||
nsCOMPtr<nsIFile> pendingDir;
|
||||
@ -3480,44 +3728,15 @@ bool CreateNotificationPipeForChild(int* childCrashFd, int* childCrashRemapFd) {
|
||||
bool SetRemoteExceptionHandler(const char* aCrashPipe) {
|
||||
MOZ_ASSERT(!gExceptionHandler, "crash client already init'd");
|
||||
RegisterRuntimeExceptionModule();
|
||||
InitializeAnnotationFacilities();
|
||||
for (auto key : MakeEnumeratedRange(Annotation::Count)) {
|
||||
switch (key) {
|
||||
case Annotation::MozCrashReason:
|
||||
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
|
||||
case Annotation::MainThreadRunnableName:
|
||||
#endif
|
||||
case Annotation::OOMAllocationSize:
|
||||
#ifdef MOZ_PHC
|
||||
case Annotation::PHCBaseAddress:
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
mozannotation_register_nscstring(static_cast<uint32_t>(key),
|
||||
&crashReporterAPIData_Table[key]);
|
||||
}
|
||||
}
|
||||
|
||||
mozannotation_register_cstring(
|
||||
static_cast<uint32_t>(Annotation::MozCrashReason), &gMozCrashReason);
|
||||
|
||||
#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
|
||||
mozannotation_register_char_buffer(
|
||||
static_cast<uint32_t>(Annotation::MainThreadRunnableName),
|
||||
&nsThread::sMainThreadRunnableName[0]);
|
||||
#endif
|
||||
|
||||
mozannotation_register_usize(
|
||||
static_cast<uint32_t>(Annotation::OOMAllocationSize),
|
||||
&gOOMAllocationSize);
|
||||
InitializeAppNotes();
|
||||
RegisterAnnotations();
|
||||
|
||||
#ifdef MOZ_PHC
|
||||
// HACK: We're using the PHCBaseAddress annotation to point to the actual
|
||||
// PHC address information object. This is because we currently have no
|
||||
// difference between the internal representation of annotations and their
|
||||
// external representation. Once we remove the old annotation API this will
|
||||
// be properly addressed.
|
||||
// external representation. Once we remove the old annotation API this
|
||||
// will be properly addressed.
|
||||
mozannotation_register_bytebuffer(
|
||||
static_cast<uint32_t>(Annotation::PHCBaseAddress),
|
||||
&mozilla::phc::gAddrInfo, sizeof(mozilla::phc::gAddrInfo));
|
||||
@ -3876,7 +4095,8 @@ bool UnsetRemoteExceptionHandler(bool wasSet) {
|
||||
gExceptionHandler = nullptr;
|
||||
}
|
||||
#endif
|
||||
TeardownAnnotationFacilities();
|
||||
gServerURL = "";
|
||||
TeardownAppNotes();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -3894,9 +4114,9 @@ void SetNotificationPipeForChild(int childCrashFd) {
|
||||
// Bionic introduced support for getgrgid_r() and getgrnam_r() only in version
|
||||
// 24 (that is Android Nougat / 7.1.2). Since GeckoView is built by version 16
|
||||
// (32-bit) or 21 (64-bit), those functions aren't defined, but nix needs them
|
||||
// and minidump-writer relies on nix. These functions should never be called in
|
||||
// practice hence we implement them only to satisfy nix linking requirements but
|
||||
// we crash if we accidentally enter them.
|
||||
// and minidump-writer relies on nix. These functions should never be called
|
||||
// in practice hence we implement them only to satisfy nix linking
|
||||
// requirements but we crash if we accidentally enter them.
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
@ -18,12 +18,12 @@
|
||||
|
||||
#include "CrashAnnotations.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "nsError.h"
|
||||
#include "nsString.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "prio.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(XP_WIN)
|
||||
# ifdef WIN32_LEAN_AND_MEAN
|
||||
@ -95,30 +95,42 @@ nsresult SetMinidumpPath(const nsAString& aPath);
|
||||
// child processes. Annotations added in the main process will be included in
|
||||
// child process crashes too unless the child process sets its own annotations.
|
||||
// If it does the child-provided annotation overrides the one set in the parent.
|
||||
nsresult AnnotateCrashReport(Annotation key, bool data);
|
||||
nsresult AnnotateCrashReport(Annotation key, int data);
|
||||
nsresult AnnotateCrashReport(Annotation key, unsigned int data);
|
||||
nsresult AnnotateCrashReport(Annotation key, const nsACString& data);
|
||||
nsresult AppendToCrashReportAnnotation(Annotation key, const nsACString& data);
|
||||
nsresult RemoveCrashReportAnnotation(Annotation key);
|
||||
const bool* RegisterAnnotationBool(Annotation aKey, const bool* aData);
|
||||
const uint32_t* RegisterAnnotationU32(Annotation aKey, const uint32_t* aData);
|
||||
const uint64_t* RegisterAnnotationU64(Annotation aKey, const uint64_t* aData);
|
||||
const size_t* RegisterAnnotationUSize(Annotation aKey, const size_t* aData);
|
||||
const char* RegisterAnnotationCString(Annotation aKey, const char* aData);
|
||||
const nsCString* RegisterAnnotationNSCString(Annotation aKey,
|
||||
const nsCString* aData);
|
||||
|
||||
nsresult RecordAnnotationBool(Annotation aKey, bool aData);
|
||||
nsresult RecordAnnotationU32(Annotation aKey, uint32_t aData);
|
||||
nsresult RecordAnnotationU64(Annotation aKey, uint64_t aData);
|
||||
nsresult RecordAnnotationUSize(Annotation aKey, size_t aData);
|
||||
nsresult RecordAnnotationCString(Annotation aKey, const char* aData);
|
||||
nsresult RecordAnnotationNSCString(Annotation aKey, const nsACString& aData);
|
||||
nsresult RecordAnnotationNSString(Annotation aKey, const nsAString& aData);
|
||||
nsresult UnrecordAnnotation(Annotation aKey);
|
||||
|
||||
nsresult AppendAppNotesToCrashReport(const nsACString& data);
|
||||
|
||||
// RAII class for setting a crash annotation during a limited scope of time.
|
||||
// Will reset the named annotation to its previous value when destroyed.
|
||||
//
|
||||
// This type's behavior is identical to that of AnnotateCrashReport().
|
||||
class MOZ_RAII AutoAnnotateCrashReport final {
|
||||
// This type's behavior is identical to that of RecordAnnotation().
|
||||
class MOZ_RAII AutoRecordAnnotation final {
|
||||
public:
|
||||
AutoAnnotateCrashReport(Annotation key, bool data);
|
||||
AutoAnnotateCrashReport(Annotation key, int data);
|
||||
AutoAnnotateCrashReport(Annotation key, unsigned int data);
|
||||
AutoAnnotateCrashReport(Annotation key, const nsACString& data);
|
||||
~AutoAnnotateCrashReport();
|
||||
AutoRecordAnnotation(Annotation key, bool data);
|
||||
AutoRecordAnnotation(Annotation key, int data);
|
||||
AutoRecordAnnotation(Annotation key, unsigned int data);
|
||||
AutoRecordAnnotation(Annotation key, const nsACString& data);
|
||||
~AutoRecordAnnotation();
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
private:
|
||||
Annotation mKey;
|
||||
nsCString mPrevious;
|
||||
const nsCString mCurrent;
|
||||
const nsCString* mPrevious;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -156,6 +156,9 @@ async function handleMinidump(callback) {
|
||||
registerCleanupFunction(cleanup);
|
||||
|
||||
Assert.ok(extrafile.exists());
|
||||
let data = await IOUtils.read(extrafile.path);
|
||||
let decoder = new TextDecoder("ascii");
|
||||
console.log("data = " + decoder.decode(data));
|
||||
let extra = await IOUtils.readJSON(extrafile.path);
|
||||
|
||||
if (callback) {
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "BaseProfiler.h"
|
||||
#include "nsWindowsDllInterceptor.h"
|
||||
#include "mozilla/CmdLineAndEnvUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/StackWalk_windows.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
@ -44,9 +43,6 @@ glue::detail::DllServicesBase* gDllServices;
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
using CrashReporter::Annotation;
|
||||
using CrashReporter::AnnotationWriter;
|
||||
|
||||
#define DLL_BLOCKLIST_ENTRY(name, ...) {name, __VA_ARGS__},
|
||||
#define DLL_BLOCKLIST_STRING_TYPE const char*
|
||||
#include "mozilla/WindowsDllBlocklistLegacyDefs.h"
|
||||
@ -54,10 +50,13 @@ using CrashReporter::AnnotationWriter;
|
||||
// define this for very verbose dll load debug spew
|
||||
#undef DEBUG_very_verbose
|
||||
|
||||
using WritableBuffer = mozilla::glue::detail::WritableBuffer<1024>;
|
||||
|
||||
static uint32_t sInitFlags;
|
||||
static bool sBlocklistInitAttempted;
|
||||
static bool sBlocklistInitFailed;
|
||||
static bool sUser32BeforeBlocklist;
|
||||
static WritableBuffer sBlocklistWriter;
|
||||
|
||||
typedef MOZ_NORETURN_PTR void(__fastcall* BaseThreadInitThunk_func)(
|
||||
BOOL aIsInitialThread, void* aStartAddress, void* aThreadParam);
|
||||
@ -174,8 +173,6 @@ class ReentrancySentinel {
|
||||
|
||||
std::map<DWORD, const char*>* ReentrancySentinel::sThreadMap;
|
||||
|
||||
using WritableBuffer = mozilla::glue::detail::WritableBuffer<1024>;
|
||||
|
||||
/**
|
||||
* This is a linked list of DLLs that have been blocked. It doesn't use
|
||||
* mozilla::LinkedList because this is an append-only list and doesn't need
|
||||
@ -673,22 +670,11 @@ MFBT_API void DllBlocklist_Initialize(uint32_t aInitFlags) {
|
||||
MFBT_API void DllBlocklist_Shutdown() {}
|
||||
#endif // DEBUG
|
||||
|
||||
static void InternalWriteNotes(AnnotationWriter& aWriter) {
|
||||
WritableBuffer buffer;
|
||||
DllBlockSet::Write(buffer);
|
||||
|
||||
aWriter.Write(Annotation::BlockedDllList, buffer.Data(), buffer.Length());
|
||||
|
||||
if (sBlocklistInitFailed) {
|
||||
aWriter.Write(Annotation::BlocklistInitFailed, "1");
|
||||
}
|
||||
|
||||
if (sUser32BeforeBlocklist) {
|
||||
aWriter.Write(Annotation::User32BeforeBlocklist, "1");
|
||||
}
|
||||
static void InternalWriteNotes(WritableBuffer& aBuffer) {
|
||||
DllBlockSet::Write(aBuffer);
|
||||
}
|
||||
|
||||
using WriterFn = void (*)(AnnotationWriter&);
|
||||
using WriterFn = void (*)(WritableBuffer& aBuffer);
|
||||
static WriterFn gWriterFn = &InternalWriteNotes;
|
||||
|
||||
static void GetNativeNtBlockSetWriter() {
|
||||
@ -699,16 +685,25 @@ static void GetNativeNtBlockSetWriter() {
|
||||
}
|
||||
}
|
||||
|
||||
MFBT_API void DllBlocklist_WriteNotes(AnnotationWriter& aWriter) {
|
||||
MOZ_ASSERT(gWriterFn);
|
||||
gWriterFn(aWriter);
|
||||
}
|
||||
MFBT_API void DllBlocklist_WriteNotes() { gWriterFn(sBlocklistWriter); }
|
||||
|
||||
MFBT_API bool DllBlocklist_CheckStatus() {
|
||||
if (sBlocklistInitFailed || sUser32BeforeBlocklist) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
MFBT_API bool* DllBlocklist_GetBlocklistInitFailedPointer() {
|
||||
return &sBlocklistInitFailed;
|
||||
}
|
||||
|
||||
MFBT_API bool* DllBlocklist_GetUser32BeforeBlocklistPointer() {
|
||||
return &sUser32BeforeBlocklist;
|
||||
}
|
||||
|
||||
MFBT_API const char* DllBlocklist_GetBlocklistWriterData() {
|
||||
return sBlocklistWriter.Data();
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// This section is for DLL Services
|
||||
// ============================================================================
|
||||
|
@ -10,10 +10,9 @@
|
||||
(defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64))
|
||||
|
||||
# include <windows.h>
|
||||
# include "CrashAnnotations.h"
|
||||
# include "mozilla/Attributes.h"
|
||||
# include "mozilla/ProcessType.h"
|
||||
# include "mozilla/Types.h"
|
||||
# include <algorithm>
|
||||
|
||||
# define HAS_DLL_BLOCKLIST
|
||||
|
||||
@ -47,9 +46,13 @@ extern uint32_t gBlocklistInitFlags;
|
||||
|
||||
MFBT_API void DllBlocklist_Initialize(
|
||||
uint32_t aInitFlags = eDllBlocklistInitFlagDefault);
|
||||
MFBT_API void DllBlocklist_WriteNotes(CrashReporter::AnnotationWriter& aWriter);
|
||||
MFBT_API void DllBlocklist_WriteNotes();
|
||||
MFBT_API bool DllBlocklist_CheckStatus();
|
||||
|
||||
MFBT_API bool* DllBlocklist_GetBlocklistInitFailedPointer();
|
||||
MFBT_API bool* DllBlocklist_GetUser32BeforeBlocklistPointer();
|
||||
MFBT_API const char* DllBlocklist_GetBlocklistWriterData();
|
||||
|
||||
// This export intends to clean up after DllBlocklist_Initialize().
|
||||
// It's disabled in release builds for performance and to limit callers' ability
|
||||
// to interfere with dll blocking.
|
||||
|
@ -1797,7 +1797,8 @@ nsXULAppInfo::AnnotateCrashReport(const nsACString& key,
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return CrashReporter::AnnotateCrashReport(annotation, data);
|
||||
CrashReporter::RecordAnnotationNSCString(annotation, data);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1808,7 +1809,8 @@ nsXULAppInfo::RemoveCrashReportAnnotation(const nsACString& key) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return CrashReporter::RemoveCrashReportAnnotation(annotation);
|
||||
CrashReporter::UnrecordAnnotation(annotation);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -2316,7 +2318,7 @@ static void SetupLauncherProcessPref() {
|
||||
if (enabledState.isOk()) {
|
||||
gLauncherProcessState = Some(enabledState.unwrap());
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::LauncherProcessState,
|
||||
static_cast<uint32_t>(enabledState.unwrap()));
|
||||
|
||||
@ -3846,7 +3848,7 @@ static void MaybeAddCPUMicrocodeCrashAnnotation() {
|
||||
}
|
||||
|
||||
if (cpuUpdateRevision > 0) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::CPUMicrocodeVersion,
|
||||
nsPrintfCString("0x%" PRIx32, cpuUpdateRevision));
|
||||
}
|
||||
@ -4106,46 +4108,52 @@ int XREMain::XRE_mainInit(bool* aExitFlag) {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CrashReporter::SetUserAppDataDirectory(file);
|
||||
}
|
||||
if (mAppData->crashReporterURL)
|
||||
if (mAppData->crashReporterURL) {
|
||||
CrashReporter::SetServerURL(
|
||||
nsDependentCString(mAppData->crashReporterURL));
|
||||
}
|
||||
|
||||
// We overwrite this once we finish starting up.
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::StartupCrash,
|
||||
true);
|
||||
CrashReporter::RecordAnnotationBool(CrashReporter::Annotation::StartupCrash,
|
||||
true);
|
||||
|
||||
// pass some basic info from the app data
|
||||
if (mAppData->vendor)
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Vendor,
|
||||
nsDependentCString(mAppData->vendor));
|
||||
if (mAppData->name)
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProductName,
|
||||
nsDependentCString(mAppData->name));
|
||||
if (mAppData->ID)
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProductID,
|
||||
nsDependentCString(mAppData->ID));
|
||||
if (mAppData->version)
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Version,
|
||||
nsDependentCString(mAppData->version));
|
||||
if (mAppData->buildID)
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::BuildID,
|
||||
nsDependentCString(mAppData->buildID));
|
||||
if (mAppData->vendor) {
|
||||
CrashReporter::RecordAnnotationCString(CrashReporter::Annotation::Vendor,
|
||||
mAppData->vendor);
|
||||
}
|
||||
if (mAppData->name) {
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProductName, mAppData->name);
|
||||
}
|
||||
if (mAppData->ID) {
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProductID, mAppData->ID);
|
||||
}
|
||||
if (mAppData->version) {
|
||||
CrashReporter::RecordAnnotationCString(CrashReporter::Annotation::Version,
|
||||
mAppData->version);
|
||||
}
|
||||
if (mAppData->buildID) {
|
||||
CrashReporter::RecordAnnotationCString(CrashReporter::Annotation::BuildID,
|
||||
mAppData->buildID);
|
||||
}
|
||||
|
||||
nsDependentCString releaseChannel(MOZ_STRINGIFY(MOZ_UPDATE_CHANNEL));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::ReleaseChannel, releaseChannel);
|
||||
|
||||
#ifdef XP_WIN
|
||||
nsAutoString appInitDLLs;
|
||||
if (widget::WinUtils::GetAppInitDLLs(appInitDLLs)) {
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AppInitDLLs,
|
||||
NS_ConvertUTF16toUTF8(appInitDLLs));
|
||||
CrashReporter::RecordAnnotationNSString(
|
||||
CrashReporter::Annotation::AppInitDLLs, appInitDLLs);
|
||||
}
|
||||
|
||||
nsString packageFamilyName = widget::WinUtils::GetPackageFamilyName();
|
||||
if (StringBeginsWith(packageFamilyName, u"Mozilla."_ns) ||
|
||||
StringBeginsWith(packageFamilyName, u"MozillaCorporation."_ns)) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::WindowsPackageFamilyName,
|
||||
NS_ConvertUTF16toUTF8(packageFamilyName));
|
||||
}
|
||||
@ -4156,15 +4164,15 @@ int XREMain::XRE_mainInit(bool* aExitFlag) {
|
||||
Maybe<nsCString> backgroundTasks = BackgroundTasks::GetBackgroundTasks();
|
||||
if (backgroundTasks.isSome()) {
|
||||
isBackgroundTaskMode = true;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::BackgroundTaskName, backgroundTasks.ref());
|
||||
}
|
||||
#endif
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::BackgroundTaskMode, isBackgroundTaskMode);
|
||||
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::HeadlessMode,
|
||||
gfxPlatform::IsHeadless());
|
||||
CrashReporter::RecordAnnotationBool(CrashReporter::Annotation::HeadlessMode,
|
||||
gfxPlatform::IsHeadless());
|
||||
|
||||
CrashReporter::SetRestartArgs(gArgc, gArgv);
|
||||
|
||||
@ -4300,8 +4308,8 @@ int XREMain::XRE_mainInit(bool* aExitFlag) {
|
||||
gSafeMode = safeModeRequested.value();
|
||||
|
||||
MaybeAddCPUMicrocodeCrashAnnotation();
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::SafeMode,
|
||||
gSafeMode);
|
||||
CrashReporter::RegisterAnnotationBool(CrashReporter::Annotation::SafeMode,
|
||||
&gSafeMode);
|
||||
|
||||
#if defined(MOZ_HAS_REMOTE)
|
||||
// Handle --no-remote and --new-instance command line arguments. Setup
|
||||
@ -5148,7 +5156,7 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) {
|
||||
|
||||
bool lastStartupWasCrash = CheckLastStartupWasCrash();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::LastStartupWasCrash, lastStartupWasCrash);
|
||||
|
||||
if (CheckArg("purgecaches") || PR_GetEnv("MOZ_PURGE_CACHES") ||
|
||||
@ -5156,7 +5164,7 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) {
|
||||
cachesOK = false;
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::StartupCacheValid, cachesOK && versionOK);
|
||||
|
||||
// Every time a profile is loaded by a build with a different version,
|
||||
@ -5211,45 +5219,30 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) {
|
||||
|
||||
#if defined(MOZ_SANDBOX)
|
||||
void AddSandboxAnnotations() {
|
||||
{
|
||||
// Include the sandbox content level, regardless of platform
|
||||
int level = GetEffectiveContentSandboxLevel();
|
||||
|
||||
nsAutoCString levelString;
|
||||
levelString.AppendInt(level);
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ContentSandboxLevel, levelString);
|
||||
}
|
||||
|
||||
{
|
||||
int level = GetEffectiveGpuSandboxLevel();
|
||||
|
||||
nsAutoCString levelString;
|
||||
levelString.AppendInt(level);
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GpuSandboxLevel, levelString);
|
||||
}
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::ContentSandboxLevel,
|
||||
GetEffectiveContentSandboxLevel());
|
||||
CrashReporter::RecordAnnotationU32(CrashReporter::Annotation::GpuSandboxLevel,
|
||||
GetEffectiveGpuSandboxLevel());
|
||||
|
||||
// Include whether or not this instance is capable of content sandboxing
|
||||
bool sandboxCapable = false;
|
||||
bool sSandboxCapable = false;
|
||||
|
||||
# if defined(XP_WIN)
|
||||
// All supported Windows versions support some level of content sandboxing
|
||||
sandboxCapable = true;
|
||||
sSandboxCapable = true;
|
||||
# elif defined(XP_MACOSX)
|
||||
// All supported OS X versions are capable
|
||||
sandboxCapable = true;
|
||||
sSandboxCapable = true;
|
||||
# elif defined(XP_LINUX)
|
||||
sandboxCapable = SandboxInfo::Get().CanSandboxContent();
|
||||
sSandboxCapable = SandboxInfo::Get().CanSandboxContent();
|
||||
# elif defined(__OpenBSD__)
|
||||
sandboxCapable = true;
|
||||
sSandboxCapable = true;
|
||||
StartOpenBSDSandbox(GeckoProcessType_Default);
|
||||
# endif
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ContentSandboxCapable, sandboxCapable);
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::ContentSandboxCapable, sSandboxCapable);
|
||||
}
|
||||
#endif /* MOZ_SANDBOX */
|
||||
|
||||
@ -5297,7 +5290,7 @@ nsresult XREMain::XRE_mainRun() {
|
||||
nsAutoCString sval;
|
||||
rv = defaultPrefBranch->GetCharPref("app.update.channel", sval);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::ReleaseChannel, sval);
|
||||
}
|
||||
}
|
||||
@ -5489,7 +5482,7 @@ nsresult XREMain::XRE_mainRun() {
|
||||
|
||||
nsCString userAgentLocale;
|
||||
LocaleService::GetInstance()->GetAppLocaleAsBCP47(userAgentLocale);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::useragent_locale, userAgentLocale);
|
||||
|
||||
if (!AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
|
||||
@ -5627,7 +5620,7 @@ nsresult XREMain::XRE_mainRun() {
|
||||
|
||||
(void)appStartup->DoneStartingUp();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::StartupCrash, false);
|
||||
|
||||
AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed);
|
||||
@ -5680,11 +5673,10 @@ nsresult XREMain::XRE_mainRun() {
|
||||
sandboxInfo.Test(SandboxInfo::kEnabledForContent));
|
||||
Telemetry::Accumulate(Telemetry::SANDBOX_MEDIA_ENABLED,
|
||||
sandboxInfo.Test(SandboxInfo::kEnabledForMedia));
|
||||
nsAutoCString flagsString;
|
||||
flagsString.AppendInt(sandboxInfo.AsInteger());
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ContentSandboxCapabilities, flagsString);
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::ContentSandboxCapabilities,
|
||||
sandboxInfo.AsInteger());
|
||||
#endif /* MOZ_SANDBOX && XP_LINUX */
|
||||
|
||||
#if defined(XP_WIN)
|
||||
|
@ -207,13 +207,13 @@ void SetTaskbarGroupId(const nsString& aId) {
|
||||
#if defined(MOZ_SANDBOX)
|
||||
void AddContentSandboxLevelAnnotation() {
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
int level = GetEffectiveContentSandboxLevel();
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ContentSandboxLevel, level);
|
||||
uint32_t contentSandboxLevel = GetEffectiveContentSandboxLevel();
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::ContentSandboxLevel, contentSandboxLevel);
|
||||
} else if (XRE_GetProcessType() == GeckoProcessType_GPU) {
|
||||
int level = GetEffectiveGpuSandboxLevel();
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GpuSandboxLevel, level);
|
||||
uint32_t gpuSandboxLevel = GetEffectiveGpuSandboxLevel();
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::GpuSandboxLevel, gpuSandboxLevel);
|
||||
}
|
||||
}
|
||||
#endif /* MOZ_SANDBOX */
|
||||
|
@ -77,9 +77,9 @@ void ChildProfilerController::ShutdownAndMaybeGrabShutdownProfileFirst(
|
||||
}
|
||||
if (profilerChildThread) {
|
||||
if (profiler_is_active()) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
"Profiling - Dispatching ShutdownProfilerChild"_ns);
|
||||
"Profiling - Dispatching ShutdownProfilerChild");
|
||||
profilerChildThread->Dispatch(
|
||||
NewRunnableMethod<ProfileAndAdditionalInformation*>(
|
||||
"ChildProfilerController::ShutdownProfilerChild", this,
|
||||
@ -90,9 +90,9 @@ void ChildProfilerController::ShutdownAndMaybeGrabShutdownProfileFirst(
|
||||
// (including the ShutdownProfilerChild runnable) have been processed.
|
||||
profilerChildThread->Shutdown();
|
||||
} else {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
"Not profiling - Running ShutdownProfilerChild"_ns);
|
||||
"Not profiling - Running ShutdownProfilerChild");
|
||||
// If we're not profiling, this operation will be very quick, so it can be
|
||||
// done synchronously. This avoids having to manually shutdown the thread,
|
||||
// which runs a risky inner event loop, see bug 1613798.
|
||||
@ -148,23 +148,24 @@ void ChildProfilerController::ShutdownProfilerChild(
|
||||
ProfileAndAdditionalInformation* aOutShutdownProfileInformation) {
|
||||
const bool isProfiling = profiler_is_active();
|
||||
if (aOutShutdownProfileInformation) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
isProfiling ? "Profiling - GrabShutdownProfile"_ns
|
||||
: "Not profiling - GrabShutdownProfile"_ns);
|
||||
isProfiling ? "Profiling - GrabShutdownProfile"
|
||||
: "Not profiling - GrabShutdownProfile");
|
||||
*aOutShutdownProfileInformation = mProfilerChild->GrabShutdownProfile();
|
||||
}
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
isProfiling ? "Profiling - Destroying ProfilerChild"_ns
|
||||
: "Not profiling - Destroying ProfilerChild"_ns);
|
||||
isProfiling ? "Profiling - Destroying ProfilerChild"
|
||||
: "Not profiling - Destroying ProfilerChild");
|
||||
mProfilerChild->Destroy();
|
||||
mProfilerChild = nullptr;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationCString(
|
||||
CrashReporter::Annotation::ProfilerChildShutdownPhase,
|
||||
isProfiling
|
||||
? "Profiling - ShutdownProfilerChild complete, waiting for thread shutdown"_ns
|
||||
: "Not Profiling - ShutdownProfilerChild complete, waiting for thread shutdown"_ns);
|
||||
isProfiling ? "Profiling - ShutdownProfilerChild complete, waiting for "
|
||||
"thread shutdown"
|
||||
: "Not Profiling - ShutdownProfilerChild complete, waiting "
|
||||
"for thread shutdown");
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -350,11 +350,11 @@ GfxInfo::GetDrmRenderDevice(nsACString& aDrmRenderDevice) {
|
||||
}
|
||||
|
||||
void GfxInfo::AddCrashReportAnnotations() {
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
|
||||
mGLStrings->Vendor());
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
|
||||
mGLStrings->Renderer());
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::AdapterVendorID, mGLStrings->Vendor());
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::AdapterDeviceID, mGLStrings->Renderer());
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::AdapterDriverVersion, mGLStrings->Version());
|
||||
}
|
||||
|
||||
|
@ -221,7 +221,7 @@ bool HandleUncaughtException(JNIEnv* aEnv) {
|
||||
bool ReportException(JNIEnv* aEnv, jthrowable aExc, jstring aStack) {
|
||||
bool result = true;
|
||||
|
||||
result &= NS_SUCCEEDED(CrashReporter::AnnotateCrashReport(
|
||||
result &= NS_SUCCEEDED(CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::JavaStackTrace,
|
||||
String::Ref::From(aStack)->ToCString()));
|
||||
|
||||
|
@ -419,21 +419,17 @@ GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) { return NS_ERROR_FAILURE; }
|
||||
|
||||
void GfxInfo::AddCrashReportAnnotations() {
|
||||
nsString deviceID, vendorID, driverVersion;
|
||||
nsAutoCString narrowDeviceID, narrowVendorID, narrowDriverVersion;
|
||||
|
||||
GetAdapterDeviceID(deviceID);
|
||||
CopyUTF16toUTF8(deviceID, narrowDeviceID);
|
||||
GetAdapterVendorID(vendorID);
|
||||
CopyUTF16toUTF8(vendorID, narrowVendorID);
|
||||
GetAdapterDriverVersion(driverVersion);
|
||||
CopyUTF16toUTF8(driverVersion, narrowDriverVersion);
|
||||
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
|
||||
narrowVendorID);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
|
||||
narrowDeviceID);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::AdapterDriverVersion, narrowDriverVersion);
|
||||
CrashReporter::RecordAnnotationNSString(
|
||||
CrashReporter::Annotation::AdapterVendorID, vendorID);
|
||||
CrashReporter::RecordAnnotationNSString(
|
||||
CrashReporter::Annotation::AdapterDeviceID, deviceID);
|
||||
CrashReporter::RecordAnnotationNSString(
|
||||
CrashReporter::Annotation::AdapterDriverVersion, driverVersion);
|
||||
}
|
||||
|
||||
// We don't support checking driver versions on Mac.
|
||||
|
@ -75,17 +75,17 @@ nsresult GfxInfo::Init() {
|
||||
}
|
||||
|
||||
void GfxInfo::AddCrashReportAnnotations() {
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
|
||||
mVendorId);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
|
||||
mDeviceId);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::AdapterVendorID, mVendorId);
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::AdapterDeviceID, mDeviceId);
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::AdapterDriverVendor, mDriverVendor);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::AdapterDriverVersion, mDriverVersion);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IsWayland,
|
||||
mIsWayland);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(CrashReporter::Annotation::IsWayland,
|
||||
mIsWayland);
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::DesktopEnvironment,
|
||||
GetDesktopEnvironmentIdentifier());
|
||||
|
||||
|
@ -1092,25 +1092,20 @@ void GfxInfo::AddCrashReportAnnotations() {
|
||||
}
|
||||
|
||||
nsString deviceID, vendorID, driverVersion, subsysID;
|
||||
nsCString narrowDeviceID, narrowVendorID, narrowDriverVersion, narrowSubsysID;
|
||||
|
||||
GetAdapterDeviceID(deviceID);
|
||||
CopyUTF16toUTF8(deviceID, narrowDeviceID);
|
||||
GetAdapterVendorID(vendorID);
|
||||
CopyUTF16toUTF8(vendorID, narrowVendorID);
|
||||
GetAdapterDriverVersion(driverVersion);
|
||||
CopyUTF16toUTF8(driverVersion, narrowDriverVersion);
|
||||
GetAdapterSubsysID(subsysID);
|
||||
CopyUTF16toUTF8(subsysID, narrowSubsysID);
|
||||
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
|
||||
narrowVendorID);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
|
||||
narrowDeviceID);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::AdapterDriverVersion, narrowDriverVersion);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterSubsysID,
|
||||
narrowSubsysID);
|
||||
CrashReporter::RecordAnnotationNSString(
|
||||
CrashReporter::Annotation::AdapterVendorID, vendorID);
|
||||
CrashReporter::RecordAnnotationNSString(
|
||||
CrashReporter::Annotation::AdapterDeviceID, deviceID);
|
||||
CrashReporter::RecordAnnotationNSString(
|
||||
CrashReporter::Annotation::AdapterDriverVersion, driverVersion);
|
||||
CrashReporter::RecordAnnotationNSString(
|
||||
CrashReporter::Annotation::AdapterSubsysID, subsysID);
|
||||
|
||||
/* Add an App Note, this contains extra information. */
|
||||
nsAutoCString note;
|
||||
|
@ -40,11 +40,8 @@ WinFileDialogChild::~WinFileDialogChild() {
|
||||
template <size_t N>
|
||||
WinFileDialogChild::IPCResult WinFileDialogChild::MakeIpcFailure(
|
||||
HRESULT hr, const char (&what)[N]) {
|
||||
// The crash-report annotator stringifies integer values anyway. We do so
|
||||
// eagerly here to avoid questions about C int/long conversion semantics.
|
||||
nsPrintfCString data("%lu", hr);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::WindowsFileDialogErrorCode, data);
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::WindowsFileDialogErrorCode, hr);
|
||||
|
||||
return IPC_FAIL(this, what);
|
||||
}
|
||||
|
@ -294,7 +294,7 @@ void LogProcessingError(LogModule* aModule, ipc::IProtocol* aCaller,
|
||||
ipc::SandboxingKind::WINDOWS_FILE_DIALOG);
|
||||
} else {
|
||||
// ... which (presumably) is us
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::AutoRecordAnnotation(
|
||||
CrashReporter::Annotation::ipc_channel_error, reason);
|
||||
|
||||
MOZ_CRASH("IPC error");
|
||||
|
@ -309,32 +309,32 @@ bool AppShutdown::IsRestarting() {
|
||||
|
||||
void AppShutdown::AnnotateShutdownReason(AppShutdownReason aReason) {
|
||||
auto key = CrashReporter::Annotation::ShutdownReason;
|
||||
nsCString reasonStr;
|
||||
const char* reasonStr;
|
||||
switch (aReason) {
|
||||
case AppShutdownReason::AppClose:
|
||||
reasonStr = "AppClose"_ns;
|
||||
reasonStr = "AppClose";
|
||||
break;
|
||||
case AppShutdownReason::AppRestart:
|
||||
reasonStr = "AppRestart"_ns;
|
||||
reasonStr = "AppRestart";
|
||||
break;
|
||||
case AppShutdownReason::OSForceClose:
|
||||
reasonStr = "OSForceClose"_ns;
|
||||
reasonStr = "OSForceClose";
|
||||
break;
|
||||
case AppShutdownReason::OSSessionEnd:
|
||||
reasonStr = "OSSessionEnd"_ns;
|
||||
reasonStr = "OSSessionEnd";
|
||||
break;
|
||||
case AppShutdownReason::OSShutdown:
|
||||
reasonStr = "OSShutdown"_ns;
|
||||
reasonStr = "OSShutdown";
|
||||
break;
|
||||
case AppShutdownReason::WinUnexpectedMozQuit:
|
||||
reasonStr = "WinUnexpectedMozQuit"_ns;
|
||||
reasonStr = "WinUnexpectedMozQuit";
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("We should know the given reason for shutdown.");
|
||||
reasonStr = "Unknown"_ns;
|
||||
reasonStr = "Unknown";
|
||||
break;
|
||||
}
|
||||
CrashReporter::AnnotateCrashReport(key, reasonStr);
|
||||
CrashReporter::RecordAnnotationCString(key, reasonStr);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -206,7 +206,7 @@ void nsAvailableMemoryWatcher::HandleLowMemory() {
|
||||
|
||||
void nsAvailableMemoryWatcher::UpdateCrashAnnotation(const MutexAutoLock&)
|
||||
MOZ_REQUIRES(mMutex) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationBool(
|
||||
CrashReporter::Annotation::LinuxUnderMemoryPressure,
|
||||
mUnderMemoryPressure);
|
||||
}
|
||||
|
@ -95,11 +95,11 @@ class nsAvailableMemoryWatcher final : public nsITimerCallback,
|
||||
|
||||
void AddParentAnnotation(CrashReporter::Annotation aAnnotation,
|
||||
nsAutoCString aString) {
|
||||
CrashReporter::AnnotateCrashReport(aAnnotation, aString);
|
||||
CrashReporter::RecordAnnotationNSCString(aAnnotation, aString);
|
||||
}
|
||||
void AddParentAnnotation(CrashReporter::Annotation aAnnotation,
|
||||
uint32_t aData) {
|
||||
CrashReporter::AnnotateCrashReport(aAnnotation, aData);
|
||||
CrashReporter::RecordAnnotationU32(aAnnotation, aData);
|
||||
}
|
||||
|
||||
void LowMemoryResponse();
|
||||
@ -251,18 +251,18 @@ nsresult nsAvailableMemoryWatcher::Init() {
|
||||
// Set the initial state of all annotations for parent crash reports.
|
||||
// Content process crash reports are set when a crash occurs and
|
||||
// AddChildAnnotations() is called.
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::MacMemoryPressure, mLevelStr);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::MacMemoryPressureNormalTime, mNormalTimeStr);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::MacMemoryPressureWarningTime, mWarningTimeStr);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::MacMemoryPressureCriticalTime,
|
||||
mCriticalTimeStr);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::MacMemoryPressureSysctl, mLevelSysctl);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationU32(
|
||||
CrashReporter::Annotation::MacAvailableMemorySysctl, mAvailMemSysctl);
|
||||
|
||||
// To support running experiments, handle pref
|
||||
@ -441,18 +441,18 @@ void nsAvailableMemoryWatcher::OnMemoryPressureChangedInternal(
|
||||
// Add all annotations to the provided crash reporter instance.
|
||||
void nsAvailableMemoryWatcher::AddChildAnnotations(
|
||||
const UniquePtr<ipc::CrashReporterHost>& aCrashReporter) {
|
||||
aCrashReporter->AddAnnotation(CrashReporter::Annotation::MacMemoryPressure,
|
||||
mLevelStr);
|
||||
aCrashReporter->AddAnnotation(
|
||||
aCrashReporter->AddAnnotationNSCString(
|
||||
CrashReporter::Annotation::MacMemoryPressure, mLevelStr);
|
||||
aCrashReporter->AddAnnotationNSCString(
|
||||
CrashReporter::Annotation::MacMemoryPressureNormalTime, mNormalTimeStr);
|
||||
aCrashReporter->AddAnnotation(
|
||||
aCrashReporter->AddAnnotationNSCString(
|
||||
CrashReporter::Annotation::MacMemoryPressureWarningTime, mWarningTimeStr);
|
||||
aCrashReporter->AddAnnotation(
|
||||
aCrashReporter->AddAnnotationNSCString(
|
||||
CrashReporter::Annotation::MacMemoryPressureCriticalTime,
|
||||
mCriticalTimeStr);
|
||||
aCrashReporter->AddAnnotation(
|
||||
aCrashReporter->AddAnnotationU32(
|
||||
CrashReporter::Annotation::MacMemoryPressureSysctl, mLevelSysctl);
|
||||
aCrashReporter->AddAnnotation(
|
||||
aCrashReporter->AddAnnotationU32(
|
||||
CrashReporter::Annotation::MacAvailableMemorySysctl, mAvailMemSysctl);
|
||||
}
|
||||
|
||||
|
@ -121,6 +121,12 @@ nsresult nsAvailableMemoryWatcher::Init() {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
static_assert(sizeof(sNumLowPhysicalMemEvents) == sizeof(uint32_t));
|
||||
|
||||
CrashReporter::RegisterAnnotationU32(
|
||||
CrashReporter::Annotation::LowPhysicalMemoryEvents,
|
||||
reinterpret_cast<uint32_t*>(&sNumLowPhysicalMemEvents));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -172,9 +178,6 @@ VOID CALLBACK nsAvailableMemoryWatcher::LowMemoryCallback(PVOID aContext,
|
||||
// static
|
||||
void nsAvailableMemoryWatcher::RecordLowMemoryEvent() {
|
||||
sNumLowPhysicalMemEvents++;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::LowPhysicalMemoryEvents,
|
||||
sNumLowPhysicalMemEvents);
|
||||
}
|
||||
|
||||
bool nsAvailableMemoryWatcher::RegisterMemoryResourceHandler(
|
||||
|
@ -1793,8 +1793,8 @@ void CycleCollectedJSRuntime::AnnotateAndSetOutOfMemory(OOMState* aStatePtr,
|
||||
? CrashReporter::Annotation::JSOutOfMemory
|
||||
: CrashReporter::Annotation::JSLargeAllocationFailure;
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
annotation, nsDependentCString(OOMStateToString(aNewState)));
|
||||
CrashReporter::RecordAnnotationCString(annotation,
|
||||
OOMStateToString(aNewState));
|
||||
}
|
||||
|
||||
void CycleCollectedJSRuntime::OnGC(JSContext* aContext, JSGCStatus aStatus,
|
||||
|
@ -628,8 +628,8 @@ void PtrInfo::AnnotatedReleaseAssert(bool aCondition, const char* aMessage) {
|
||||
}
|
||||
nsPrintfCString msg("%s, for class %s", aMessage, piName);
|
||||
NS_WARNING(msg.get());
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::CycleCollector,
|
||||
msg);
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::CycleCollector, msg);
|
||||
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
@ -452,13 +452,12 @@ NS_DebugBreak(uint32_t aSeverity, const char* aStr, const char* aExpr,
|
||||
if (XRE_IsParentProcess()) {
|
||||
// Don't include the PID in the crash report annotation to
|
||||
// allow faceting on crash-stats.mozilla.org.
|
||||
nsCString note("xpcom_runtime_abort(");
|
||||
nsAutoCString note("xpcom_runtime_abort(");
|
||||
note += nonPIDBuf.buffer;
|
||||
note += ")";
|
||||
CrashReporter::AppendAppNotesToCrashReport(note);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::AbortMessage,
|
||||
nsDependentCString(nonPIDBuf.buffer));
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::AbortMessage, note);
|
||||
}
|
||||
|
||||
#if defined(DEBUG) && defined(_WIN32)
|
||||
|
@ -672,11 +672,11 @@ void AutoNestedEventLoopAnnotation::AnnotateXPCOMSpinEventLoopStack(
|
||||
if (aStack.Length() > 0) {
|
||||
nsCString prefixedStack(XRE_GetProcessTypeString());
|
||||
prefixedStack += ": "_ns + aStack;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::RecordAnnotationNSCString(
|
||||
CrashReporter::Annotation::XPCOMSpinEventLoopStack, prefixedStack);
|
||||
} else {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::XPCOMSpinEventLoopStack, ""_ns);
|
||||
CrashReporter::UnrecordAnnotation(
|
||||
CrashReporter::Annotation::XPCOMSpinEventLoopStack);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user