зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1348273 - Convert crash annotations into a machine-readable list of constants; r=ted.mielczarek,njn,dholbert,mak,cpearce,mcmanus,froydnj,Dexter,jrmuizel,jchen,jimm,bz,surkov
This introduces the machinery needed to generate crash annotations from a YAML file. The relevant C++ functions are updated to take a typed enum. JavaScript calls are unaffected but they will throw if the string argument does not correspond to one of the known entries in the C++ enum. The existing whitelists and blacklists of annotations are also generated from the YAML file and all duplicate code related to them has been consolidated. Once written out to the .extra file the annotations are converted in string form and are no different than the existing ones. All existing annotations have been included in the list (and some obsolete ones have been removed) and all call sites have been updated including tests where appropriate. --HG-- extra : source : 4f6c43f2830701ec5552e08e3f1b06fe6d045860
This commit is contained in:
Родитель
bf2bee5c8e
Коммит
15adf94f4d
|
@ -1393,7 +1393,7 @@ nsAccessibilityService::Init()
|
|||
gApplicationAccessible->Init();
|
||||
|
||||
CrashReporter::
|
||||
AnnotateCrashReport(NS_LITERAL_CSTRING("Accessibility"),
|
||||
AnnotateCrashReport(CrashReporter::Annotation::Accessibility,
|
||||
NS_LITERAL_CSTRING("Active"));
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
|
|
@ -242,7 +242,7 @@ Compatibility::Init()
|
|||
InitConsumers();
|
||||
|
||||
CrashReporter::
|
||||
AnnotateCrashReport(NS_LITERAL_CSTRING("AccessibilityInProcClient"),
|
||||
AnnotateCrashReport(CrashReporter::Annotation::AccessibilityInProcClient,
|
||||
nsPrintfCString("0x%X", sConsumers));
|
||||
|
||||
// Gather telemetry
|
||||
|
@ -436,8 +436,9 @@ UseIAccessibleProxyStub()
|
|||
// If we reach this point then something is seriously wrong with the
|
||||
// IAccessible configuration in the computer's registry. Let's annotate this
|
||||
// so that we can easily determine this condition during crash analysis.
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IAccessibleConfig"),
|
||||
NS_LITERAL_CSTRING("NoSystemTypeLibOrPS"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IAccessibleConfig,
|
||||
NS_LITERAL_CSTRING("NoSystemTypeLibOrPS"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include "nsAccessibilityService.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "RootAccessibleWrap.h"
|
||||
|
|
|
@ -358,7 +358,7 @@ AccumulateInstantiatorTelemetry(const nsAString& aValue)
|
|||
#endif // defined(MOZ_TELEMETRY_REPORTING)
|
||||
#if defined(MOZ_CRASHREPORTER)
|
||||
CrashReporter::
|
||||
AnnotateCrashReport(NS_LITERAL_CSTRING("AccessibilityClient"),
|
||||
AnnotateCrashReport(CrashReporter::Annotation::AccessibilityClient,
|
||||
NS_ConvertUTF16toUTF8(aValue));
|
||||
#endif // defined(MOZ_CRASHREPORTER)
|
||||
}
|
||||
|
|
|
@ -1700,8 +1700,8 @@ NS_IMETHODIMP
|
|||
nsDocShell::SetRemoteTabs(bool aUseRemoteTabs)
|
||||
{
|
||||
if (aUseRemoteTabs) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("DOMIPCEnabled"),
|
||||
NS_LITERAL_CSTRING("1"));
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::DOMIPCEnabled,
|
||||
true);
|
||||
}
|
||||
|
||||
mUseRemoteTabs = aUseRemoteTabs;
|
||||
|
|
|
@ -276,10 +276,8 @@ 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(NS_LITERAL_CSTRING("HasDeviceTouchScreen"),
|
||||
enabled ?
|
||||
NS_LITERAL_CSTRING("1") :
|
||||
NS_LITERAL_CSTRING("0"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::HasDeviceTouchScreen, enabled);
|
||||
firstTime = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1777,16 +1777,13 @@ ContentChild::RecvSetProcessSandbox(const MaybeFileDesc& aBroker)
|
|||
#endif
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("ContentSandboxEnabled"),
|
||||
sandboxEnabled? NS_LITERAL_CSTRING("1") : NS_LITERAL_CSTRING("0"));
|
||||
CrashReporter::Annotation::ContentSandboxEnabled, sandboxEnabled);
|
||||
#if defined(XP_LINUX) && !defined(OS_ANDROID)
|
||||
nsAutoCString flagsString;
|
||||
flagsString.AppendInt(SandboxInfo::Get().AsInteger());
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("ContentSandboxCapabilities"), flagsString);
|
||||
CrashReporter::Annotation::ContentSandboxCapabilities,
|
||||
static_cast<int>(SandboxInfo::Get().AsInteger()));
|
||||
#endif /* XP_LINUX && !OS_ANDROID */
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("RemoteType"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::RemoteType,
|
||||
NS_ConvertUTF16toUTF8(GetRemoteType()));
|
||||
#endif /* MOZ_CONTENT_SANDBOX */
|
||||
|
||||
|
@ -2448,7 +2445,8 @@ ContentChild::ProcessingError(Result aCode, const char* aReason)
|
|||
}
|
||||
|
||||
nsDependentCString reason(aReason);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ipc_channel_error"), reason);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ipc_channel_error, reason);
|
||||
|
||||
MOZ_CRASH("Content child abort due to IPC error");
|
||||
}
|
||||
|
@ -3123,8 +3121,9 @@ ContentChild::ShutdownInternal()
|
|||
// to wait for that event loop to finish. Otherwise we could prematurely
|
||||
// terminate an "unload" or "pagehide" event handler (which might be doing a
|
||||
// sync XHR, for example).
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"),
|
||||
NS_LITERAL_CSTRING("RecvShutdown"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
NS_LITERAL_CSTRING("RecvShutdown"));
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
RefPtr<nsThread> mainThread = nsThreadManager::get().GetCurrentThread();
|
||||
|
@ -3182,10 +3181,11 @@ ContentChild::ShutdownInternal()
|
|||
// parent closes.
|
||||
StartForceKillTimer();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"),
|
||||
NS_LITERAL_CSTRING("SendFinishShutdown (sending)"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCShutdownState,
|
||||
NS_LITERAL_CSTRING("SendFinishShutdown (sending)"));
|
||||
bool sent = SendFinishShutdown();
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCShutdownState"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IPCShutdownState,
|
||||
sent ? NS_LITERAL_CSTRING("SendFinishShutdown (sent)")
|
||||
: NS_LITERAL_CSTRING("SendFinishShutdown (failed)"));
|
||||
}
|
||||
|
|
|
@ -3370,13 +3370,11 @@ ContentParent::KillHard(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->AddNote(
|
||||
NS_LITERAL_CSTRING("additional_minidumps"),
|
||||
additionalDumps);
|
||||
mCrashReporter->AddAnnotation(
|
||||
CrashReporter::Annotation::additional_minidumps, additionalDumps);
|
||||
nsDependentCString reason(aReason);
|
||||
mCrashReporter->AddNote(
|
||||
NS_LITERAL_CSTRING("ipc_channel_error"),
|
||||
reason);
|
||||
mCrashReporter->AddAnnotation(CrashReporter::Annotation::ipc_channel_error,
|
||||
reason);
|
||||
|
||||
Telemetry::Accumulate(Telemetry::SUBPROCESS_KILL_HARD, reason, 1);
|
||||
|
||||
|
|
|
@ -1163,7 +1163,7 @@ TabChild::RecvLoadURL(const nsCString& aURI,
|
|||
NS_WARNING("WebNavigation()->LoadURI failed. Eating exception, what else can I do?");
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("URL"), aURI);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URL, aURI);
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
|
|
@ -560,8 +560,9 @@ GMPChild::AnswerStartPlugin(const nsString& aAdapter)
|
|||
|
||||
nsCString libPath;
|
||||
if (!GetUTF8LibPath(libPath)) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GMPLibraryPath"),
|
||||
NS_ConvertUTF16toUTF8(mPluginPath));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GMPLibraryPath,
|
||||
NS_ConvertUTF16toUTF8(mPluginPath));
|
||||
|
||||
#ifdef XP_WIN
|
||||
return IPC_FAIL(
|
||||
|
@ -615,8 +616,9 @@ GMPChild::AnswerStartPlugin(const nsString& aAdapter)
|
|||
adapter)) {
|
||||
NS_WARNING("Failed to load GMP");
|
||||
delete platformAPI;
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GMPLibraryPath"),
|
||||
NS_ConvertUTF16toUTF8(mPluginPath));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GMPLibraryPath,
|
||||
NS_ConvertUTF16toUTF8(mPluginPath));
|
||||
|
||||
#ifdef XP_WIN
|
||||
return IPC_FAIL(
|
||||
|
|
|
@ -463,10 +463,13 @@ GMPParent::EnsureProcessLoaded()
|
|||
void
|
||||
GMPParent::WriteExtraDataForMinidump()
|
||||
{
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("GMPPlugin"), NS_LITERAL_CSTRING("1"));
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginFilename"), NS_ConvertUTF16toUTF8(mName));
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginName"), mDisplayName);
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginVersion"), mVersion);
|
||||
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);
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include <cstdlib>
|
||||
#include <stdio.h>
|
||||
#include "prio.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "nsNPAPIPlugin.h"
|
||||
#include "nsNPAPIPluginStreamListener.h"
|
||||
#include "nsNPAPIPluginInstance.h"
|
||||
|
|
|
@ -410,28 +410,6 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// Don't load "fbplugin" or any plugins whose name starts with "fbplugin_"
|
||||
// (Facebook plugins) if we're running on OS X 10.10 (Yosemite) or later.
|
||||
// A "fbplugin" file crashes on load, in the call to LoadPlugin() below.
|
||||
// See bug 1086977.
|
||||
if (nsCocoaFeatures::OnYosemiteOrLater()) {
|
||||
if (fileName.EqualsLiteral("fbplugin") ||
|
||||
StringBeginsWith(fileName, NS_LITERAL_CSTRING("fbplugin_"))) {
|
||||
nsAutoCString msg;
|
||||
msg.AppendPrintf("Preventing load of %s (see bug 1086977)",
|
||||
fileName.get());
|
||||
NS_WARNING(msg.get());
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// The block above assumes that "fbplugin" is the filename of the plugin
|
||||
// to be blocked, or that the filename starts with "fbplugin_". But we
|
||||
// don't yet know for sure if this is always true. So for the time being
|
||||
// record extra information in our crash logs.
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"),
|
||||
fileName);
|
||||
}
|
||||
|
||||
// It's possible that our plugin has 2 entry points that'll give us mime type
|
||||
// info. Quicktime does this to get around the need of having admin rights to
|
||||
// change mime info in the resource fork. We need to use this info instead of
|
||||
|
@ -440,13 +418,6 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
|
|||
// Sadly we have to load the library for this to work.
|
||||
rv = LoadPlugin(outLibrary);
|
||||
|
||||
if (nsCocoaFeatures::OnYosemiteOrLater()) {
|
||||
// If we didn't crash in LoadPlugin(), change the previous annotation so we
|
||||
// don't sow confusion.
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Bug_1086977"),
|
||||
NS_LITERAL_CSTRING("Didn't crash, please ignore"));
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
|
|
|
@ -738,26 +738,36 @@ PluginModuleChromeParent::WriteExtraDataForMinidump()
|
|||
filePos = 0;
|
||||
else
|
||||
filePos++;
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginFilename"), cstring(pluginFile.substr(filePos).c_str()));
|
||||
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginName"), mPluginName);
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginVersion"), mPluginVersion);
|
||||
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginFilename,
|
||||
cstring(pluginFile.substr(filePos).c_str()));
|
||||
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginName,
|
||||
mPluginName);
|
||||
mCrashReporter->AddAnnotation(CrashReporter::Annotation::PluginVersion,
|
||||
mPluginVersion);
|
||||
|
||||
if (mCrashReporter) {
|
||||
#ifdef XP_WIN
|
||||
if (mPluginCpuUsageOnHang.Length() > 0) {
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("NumberOfProcessors"),
|
||||
nsPrintfCString("%d", PR_GetNumberOfProcessors()));
|
||||
mCrashReporter->AddAnnotation(
|
||||
CrashReporter::Annotation::NumberOfProcessors,
|
||||
PR_GetNumberOfProcessors());
|
||||
|
||||
nsCString cpuUsageStr;
|
||||
cpuUsageStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[0] * 100) / 100);
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginCpuUsage"), cpuUsageStr);
|
||||
mCrashReporter->AddAnnotation(
|
||||
CrashReporter::Annotation::PluginCpuUsage,
|
||||
cpuUsageStr);
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER_INJECTOR
|
||||
for (uint32_t i=1; i<mPluginCpuUsageOnHang.Length(); ++i) {
|
||||
for (uint32_t i = 1; i < mPluginCpuUsageOnHang.Length(); ++i) {
|
||||
nsCString tempStr;
|
||||
tempStr.AppendFloat(std::ceil(mPluginCpuUsageOnHang[i] * 100) / 100);
|
||||
mCrashReporter->AddNote(nsPrintfCString("CpuUsageFlashProcess%d", i), tempStr);
|
||||
// HACK: There can only be at most two flash processes hence
|
||||
// the hardcoded annotations
|
||||
CrashReporter::Annotation annotation =
|
||||
(i == 1) ? CrashReporter::Annotation::CpuUsageFlashProcess1
|
||||
: CrashReporter::Annotation::CpuUsageFlashProcess2;
|
||||
mCrashReporter->AddAnnotation(annotation, tempStr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1244,8 +1254,8 @@ PluginModuleChromeParent::OnTakeFullMinidumpComplete(bool aReportsReady,
|
|||
}
|
||||
}
|
||||
}
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("additional_minidumps"),
|
||||
additionalDumps);
|
||||
mCrashReporter->AddAnnotation(Annotation::additional_minidumps,
|
||||
additionalDumps);
|
||||
|
||||
mTakeFullMinidumpCallback.Invoke(mCrashReporter->MinidumpID());
|
||||
} else {
|
||||
|
@ -1306,18 +1316,15 @@ PluginModuleChromeParent::TerminateChildProcessOnDumpComplete(MessageLoop* aMsgL
|
|||
mTerminateChildProcessCallback.Invoke(true);
|
||||
return;
|
||||
}
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("PluginHang"),
|
||||
NS_LITERAL_CSTRING("1"));
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("HangMonitorDescription"),
|
||||
aMonitorDescription);
|
||||
mCrashReporter->AddAnnotation(Annotation::PluginHang, true);
|
||||
mCrashReporter->AddAnnotation(Annotation::HangMonitorDescription,
|
||||
aMonitorDescription);
|
||||
#ifdef XP_WIN
|
||||
if (mHangUIParent) {
|
||||
unsigned int hangUIDuration = mHangUIParent->LastShowDurationMs();
|
||||
if (hangUIDuration) {
|
||||
nsPrintfCString strHangUIDuration("%u", hangUIDuration);
|
||||
mCrashReporter->AddNote(
|
||||
NS_LITERAL_CSTRING("PluginHangUIDuration"),
|
||||
strHangUIDuration);
|
||||
mCrashReporter->AddAnnotation(Annotation::PluginHangUIDuration,
|
||||
hangUIDuration);
|
||||
}
|
||||
}
|
||||
#endif // XP_WIN
|
||||
|
@ -1583,7 +1590,8 @@ PluginModuleChromeParent::ProcessFirstMinidump()
|
|||
NS_ConvertUTF16toUTF8(mCrashReporter->MinidumpID()).get()));
|
||||
|
||||
if (!flashProcessType.IsEmpty()) {
|
||||
mCrashReporter->AddNote(NS_LITERAL_CSTRING("FlashProcessDump"), flashProcessType);
|
||||
mCrashReporter->AddAnnotation(Annotation::FlashProcessDump,
|
||||
flashProcessType);
|
||||
}
|
||||
mCrashReporter->FinalizeCrashReport();
|
||||
}
|
||||
|
|
|
@ -380,12 +380,11 @@ GPUProcessManager::OnProcessLaunchComplete(GPUProcessHost* aHost)
|
|||
mGPUChild->SendInitVsyncBridge(std::move(vsyncParent));
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("GPUProcessStatus"),
|
||||
NS_LITERAL_CSTRING("Running"));
|
||||
CrashReporter::Annotation::GPUProcessStatus, NS_LITERAL_CSTRING("Running"));
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("GPUProcessLaunchCount"),
|
||||
nsPrintfCString("%d", mNumProcessAttempts));
|
||||
CrashReporter::Annotation::GPUProcessLaunchCount,
|
||||
static_cast<int>(mNumProcessAttempts));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -727,7 +726,7 @@ GPUProcessManager::DestroyProcess()
|
|||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("GPUProcessStatus"),
|
||||
CrashReporter::Annotation::GPUProcessStatus,
|
||||
NS_LITERAL_CSTRING("Destroyed"));
|
||||
}
|
||||
|
||||
|
|
|
@ -165,9 +165,8 @@ DriverCrashGuard::~DriverCrashGuard()
|
|||
dom::ContentChild::GetSingleton()->SendEndDriverCrashGuard(uint32_t(mType));
|
||||
}
|
||||
|
||||
// Remove the crash report annotation.
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GraphicsStartupTest"),
|
||||
NS_LITERAL_CSTRING(""));
|
||||
CrashReporter::RemoveCrashReportAnnotation(
|
||||
CrashReporter::Annotation::GraphicsStartupTest);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -210,8 +209,8 @@ DriverCrashGuard::ActivateGuard()
|
|||
// attribute a random parent process crash to a graphics problem in a child
|
||||
// process.
|
||||
if (mMode != Mode::Proxy) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("GraphicsStartupTest"),
|
||||
NS_LITERAL_CSTRING("1"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::GraphicsStartupTest, true);
|
||||
}
|
||||
|
||||
// If we're in the content process, the rest of the guarding is handled
|
||||
|
|
|
@ -885,10 +885,8 @@ DeviceManagerDx::MaybeResetAndReacquireDevices()
|
|||
Telemetry::Accumulate(Telemetry::DEVICE_RESET_REASON, uint32_t(resetReason));
|
||||
}
|
||||
|
||||
nsPrintfCString reasonString("%d", int(resetReason));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("DeviceResetReason"),
|
||||
reasonString);
|
||||
CrashReporter::Annotation::DeviceResetReason, int(resetReason));
|
||||
|
||||
bool createCompositorDevice = !!mCompositorDevice;
|
||||
bool createContentDevice = !!mContentDevice;
|
||||
|
|
|
@ -199,7 +199,7 @@ public:
|
|||
class CrashStatsLogForwarder: public mozilla::gfx::LogForwarder
|
||||
{
|
||||
public:
|
||||
explicit CrashStatsLogForwarder(const char* aKey);
|
||||
explicit CrashStatsLogForwarder(CrashReporter::Annotation aKey);
|
||||
void Log(const std::string& aString) override;
|
||||
void CrashAction(LogReason aReason) override;
|
||||
bool UpdateStringsVector(const std::string& aString) override;
|
||||
|
@ -214,13 +214,13 @@ private:
|
|||
|
||||
private:
|
||||
LoggingRecord mBuffer;
|
||||
nsCString mCrashCriticalKey;
|
||||
CrashReporter::Annotation mCrashCriticalKey;
|
||||
uint32_t mMaxCapacity;
|
||||
int32_t mIndex;
|
||||
Mutex mMutex;
|
||||
};
|
||||
|
||||
CrashStatsLogForwarder::CrashStatsLogForwarder(const char* aKey)
|
||||
CrashStatsLogForwarder::CrashStatsLogForwarder(CrashReporter::Annotation aKey)
|
||||
: mBuffer()
|
||||
, mCrashCriticalKey(aKey)
|
||||
, mMaxCapacity(0)
|
||||
|
@ -298,11 +298,13 @@ void CrashStatsLogForwarder::UpdateCrashReport()
|
|||
}
|
||||
|
||||
nsCString reportString(message.str().c_str());
|
||||
nsresult annotated = CrashReporter::AnnotateCrashReport(mCrashCriticalKey, reportString);
|
||||
nsresult annotated = CrashReporter::AnnotateCrashReport(mCrashCriticalKey,
|
||||
reportString);
|
||||
|
||||
if (annotated != NS_OK) {
|
||||
printf("Crash Annotation %s: %s",
|
||||
mCrashCriticalKey.get(), message.str().c_str());
|
||||
CrashReporter::AnnotationToString(mCrashCriticalKey),
|
||||
message.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -922,7 +924,8 @@ gfxPlatform::MaxAllocSize()
|
|||
/* static */ void
|
||||
gfxPlatform::InitMoz2DLogging()
|
||||
{
|
||||
auto fwd = new CrashStatsLogForwarder("GraphicsCriticalError");
|
||||
auto fwd = new CrashStatsLogForwarder(
|
||||
CrashReporter::Annotation::GraphicsCriticalError);
|
||||
fwd->SetCircularBufferSize(gfxPrefs::GfxLoggingCrashLength());
|
||||
|
||||
mozilla::gfx::Config cfg;
|
||||
|
|
|
@ -248,13 +248,15 @@ bool Channel::ChannelImpl::CreatePipe(const std::wstring& channel_id,
|
|||
if (mode == MODE_SERVER) {
|
||||
int pipe_fds[2];
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) {
|
||||
mozilla::ipc::AnnotateCrashReportWithErrno("IpcCreatePipeSocketPairErrno", errno);
|
||||
mozilla::ipc::AnnotateCrashReportWithErrno(
|
||||
CrashReporter::Annotation::IpcCreatePipeSocketPairErrno, errno);
|
||||
return false;
|
||||
}
|
||||
// Set both ends to be non-blocking.
|
||||
if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 ||
|
||||
fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) {
|
||||
mozilla::ipc::AnnotateCrashReportWithErrno("IpcCreatePipeFcntlErrno", errno);
|
||||
mozilla::ipc::AnnotateCrashReportWithErrno(
|
||||
CrashReporter::Annotation::IpcCreatePipeFcntlErrno, errno);
|
||||
IGNORE_EINTR(close(pipe_fds[0]));
|
||||
IGNORE_EINTR(close(pipe_fds[1]));
|
||||
return false;
|
||||
|
@ -262,7 +264,8 @@ bool Channel::ChannelImpl::CreatePipe(const std::wstring& channel_id,
|
|||
|
||||
if (!SetCloseOnExec(pipe_fds[0]) ||
|
||||
!SetCloseOnExec(pipe_fds[1])) {
|
||||
mozilla::ipc::AnnotateCrashReportWithErrno("IpcCreatePipeCloExecErrno", errno);
|
||||
mozilla::ipc::AnnotateCrashReportWithErrno(
|
||||
CrashReporter::Annotation::IpcCreatePipeCloExecErrno, errno);
|
||||
IGNORE_EINTR(close(pipe_fds[0]));
|
||||
IGNORE_EINTR(close(pipe_fds[1]));
|
||||
return false;
|
||||
|
|
|
@ -26,7 +26,8 @@ CrashReporterClient::~CrashReporterClient()
|
|||
}
|
||||
|
||||
void
|
||||
CrashReporterClient::AnnotateCrashReport(const nsCString& aKey, const nsCString& aData)
|
||||
CrashReporterClient::AnnotateCrashReport(CrashReporter::Annotation aKey,
|
||||
const nsCString& aData)
|
||||
{
|
||||
StaticMutexAutoLock lock(sLock);
|
||||
mMetadata->AnnotateCrashReport(aKey, aData);
|
||||
|
|
|
@ -65,7 +65,8 @@ public:
|
|||
static void DestroySingleton();
|
||||
static RefPtr<CrashReporterClient> GetSingleton();
|
||||
|
||||
void AnnotateCrashReport(const nsCString& aKey, const nsCString& aData);
|
||||
void AnnotateCrashReport(CrashReporter::Annotation aKey,
|
||||
const nsCString& aData);
|
||||
void AppendAppNotes(const nsCString& aData);
|
||||
|
||||
private:
|
||||
|
|
|
@ -65,7 +65,7 @@ CrashReporterHost::FinalizeCrashReport()
|
|||
MOZ_ASSERT(!mFinalized);
|
||||
MOZ_ASSERT(HasMinidump());
|
||||
|
||||
CrashReporter::AnnotationTable notes;
|
||||
CrashReporter::AnnotationTable annotations;
|
||||
|
||||
nsAutoCString type;
|
||||
switch (mProcessType) {
|
||||
|
@ -83,22 +83,23 @@ CrashReporterHost::FinalizeCrashReport()
|
|||
NS_ERROR("unknown process type");
|
||||
break;
|
||||
}
|
||||
notes.Put(NS_LITERAL_CSTRING("ProcessType"), type);
|
||||
annotations[CrashReporter::Annotation::ProcessType] = type;
|
||||
|
||||
char startTime[32];
|
||||
SprintfLiteral(startTime, "%lld", static_cast<long long>(mStartTime));
|
||||
notes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));
|
||||
annotations[CrashReporter::Annotation::StartupTime] =
|
||||
nsDependentCString(startTime);
|
||||
|
||||
// We might not have shmem (for example, when running crashreporter tests).
|
||||
if (mShmem.IsReadable()) {
|
||||
CrashReporterMetadataShmem::ReadAppNotes(mShmem, ¬es);
|
||||
CrashReporterMetadataShmem::ReadAppNotes(mShmem, annotations);
|
||||
}
|
||||
CrashReporter::AppendExtraData(mDumpID, mExtraNotes);
|
||||
CrashReporter::AppendExtraData(mDumpID, notes);
|
||||
CrashReporter::AppendExtraData(mDumpID, mExtraAnnotations);
|
||||
CrashReporter::AppendExtraData(mDumpID, annotations);
|
||||
|
||||
// Use mExtraNotes, since NotifyCrashService looks for "PluginHang" which is
|
||||
// set in the parent process.
|
||||
NotifyCrashService(mProcessType, mDumpID, &mExtraNotes);
|
||||
// Use mExtraAnnotations, since NotifyCrashService looks for "PluginHang"
|
||||
// which is set in the parent process.
|
||||
NotifyCrashService(mProcessType, mDumpID, mExtraAnnotations);
|
||||
|
||||
mFinalized = true;
|
||||
return true;
|
||||
|
@ -221,11 +222,11 @@ CrashReporterHost::GenerateMinidumpAndPair(GeckoChildProcessHost* aChildProcess,
|
|||
/* static */ void
|
||||
CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType,
|
||||
const nsString& aChildDumpID,
|
||||
const AnnotationTable* aNotes)
|
||||
const AnnotationTable& aNotes)
|
||||
{
|
||||
if (!NS_IsMainThread()) {
|
||||
RefPtr<Runnable> runnable = NS_NewRunnableFunction(
|
||||
"ipc::CrashReporterHost::NotifyCrashService", [=]() -> void {
|
||||
"ipc::CrashReporterHost::NotifyCrashService", [&]() -> void {
|
||||
CrashReporterHost::NotifyCrashService(
|
||||
aProcessType, aChildDumpID, aNotes);
|
||||
});
|
||||
|
@ -255,9 +256,8 @@ CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType,
|
|||
case GeckoProcessType_Plugin: {
|
||||
processType = nsICrashService::PROCESS_TYPE_PLUGIN;
|
||||
telemetryKey.AssignLiteral("plugin");
|
||||
nsAutoCString val;
|
||||
if (aNotes->Get(NS_LITERAL_CSTRING("PluginHang"), &val) &&
|
||||
val.EqualsLiteral("1")) {
|
||||
nsCString val = aNotes[CrashReporter::Annotation::PluginHang];
|
||||
if (val.Equals(NS_LITERAL_CSTRING("1"))) {
|
||||
crashType = nsICrashService::CRASH_TYPE_HANG;
|
||||
telemetryKey.AssignLiteral("pluginhang");
|
||||
}
|
||||
|
@ -282,9 +282,35 @@ CrashReporterHost::NotifyCrashService(GeckoProcessType aProcessType,
|
|||
}
|
||||
|
||||
void
|
||||
CrashReporterHost::AddNote(const nsCString& aKey, const nsCString& aValue)
|
||||
CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey, bool aValue)
|
||||
{
|
||||
mExtraNotes.Put(aKey, aValue);
|
||||
mExtraAnnotations[aKey] = aValue ? NS_LITERAL_CSTRING("1")
|
||||
: NS_LITERAL_CSTRING("0");
|
||||
}
|
||||
|
||||
void
|
||||
CrashReporterHost::AddAnnotation(CrashReporter::Annotation aKey,
|
||||
int aValue)
|
||||
{
|
||||
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 nsCString& aValue)
|
||||
{
|
||||
mExtraAnnotations[aKey] = aValue;
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
|
|
|
@ -130,9 +130,12 @@ public:
|
|||
static void NotifyCrashService(
|
||||
GeckoProcessType aProcessType,
|
||||
const nsString& aChildDumpID,
|
||||
const AnnotationTable* aNotes);
|
||||
const AnnotationTable& aNotes);
|
||||
|
||||
void AddNote(const nsCString& aKey, const nsCString& aValue);
|
||||
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 nsCString& aValue);
|
||||
|
||||
bool HasMinidump() const {
|
||||
return !mDumpID.IsEmpty();
|
||||
|
@ -152,7 +155,7 @@ private:
|
|||
Shmem mShmem;
|
||||
ThreadId mThreadId;
|
||||
time_t mStartTime;
|
||||
AnnotationTable mExtraNotes;
|
||||
AnnotationTable mExtraAnnotations;
|
||||
nsString mDumpID;
|
||||
bool mFinalized;
|
||||
nsCOMPtr<nsIFile> mTargetDump;
|
||||
|
|
|
@ -6,11 +6,14 @@
|
|||
|
||||
#include "CrashReporterMetadataShmem.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/EnumeratedRange.h"
|
||||
#include "nsISupportsImpl.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
using CrashReporter::Annotation;
|
||||
|
||||
enum class EntryType : uint8_t {
|
||||
None,
|
||||
Annotation,
|
||||
|
@ -28,9 +31,10 @@ CrashReporterMetadataShmem::~CrashReporterMetadataShmem()
|
|||
}
|
||||
|
||||
void
|
||||
CrashReporterMetadataShmem::AnnotateCrashReport(const nsCString& aKey, const nsCString& aData)
|
||||
CrashReporterMetadataShmem::AnnotateCrashReport(Annotation aKey,
|
||||
const nsCString& aData)
|
||||
{
|
||||
mNotes.Put(aKey, aData);
|
||||
mAnnotations[aKey] = aData;
|
||||
SyncNotesToShmem();
|
||||
}
|
||||
|
||||
|
@ -38,7 +42,7 @@ void
|
|||
CrashReporterMetadataShmem::AppendAppNotes(const nsCString& aData)
|
||||
{
|
||||
mAppNotes.Append(aData);
|
||||
mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes);
|
||||
mAnnotations[Annotation::Notes] = mAppNotes;
|
||||
SyncNotesToShmem();
|
||||
}
|
||||
|
||||
|
@ -52,7 +56,7 @@ public:
|
|||
*mCursor = uint8_t(EntryType::None);
|
||||
}
|
||||
|
||||
MOZ_MUST_USE bool WriteAnnotation(const nsCString& aKey, const nsCString& aValue) {
|
||||
MOZ_MUST_USE bool WriteAnnotation(Annotation aKey, const nsCString& aValue) {
|
||||
// This shouldn't happen because Commit() guarantees mCursor < mEnd. But
|
||||
// we might as well be safe.
|
||||
if (mCursor >= mEnd) {
|
||||
|
@ -125,11 +129,11 @@ CrashReporterMetadataShmem::SyncNotesToShmem()
|
|||
{
|
||||
MetadataShmemWriter writer(mShmem);
|
||||
|
||||
for (auto it = mNotes.Iter(); !it.Done(); it.Next()) {
|
||||
nsCString key = nsCString(it.Key());
|
||||
nsCString value = nsCString(it.Data());
|
||||
if (!writer.WriteAnnotation(key, value)) {
|
||||
return;
|
||||
for (auto key : MakeEnumeratedRange(Annotation::Count)) {
|
||||
if (!mAnnotations[key].IsEmpty()) {
|
||||
if (!writer.WriteAnnotation(key, mAnnotations[key])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,6 +166,11 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool Read(T* aOut) {
|
||||
return Read(aOut, sizeof(T));
|
||||
}
|
||||
|
||||
bool Read(nsCString& aOut) {
|
||||
uint32_t length = 0;
|
||||
if (!Read(&length)) {
|
||||
|
@ -178,10 +187,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
bool Read(T* aOut) {
|
||||
return Read(aOut, sizeof(T));
|
||||
}
|
||||
bool Read(void* aOut, size_t aLength) {
|
||||
const uint8_t* src = Read(aLength);
|
||||
if (!src) {
|
||||
|
@ -209,17 +214,19 @@ private:
|
|||
};
|
||||
|
||||
void
|
||||
CrashReporterMetadataShmem::ReadAppNotes(const Shmem& aShmem, CrashReporter::AnnotationTable* aNotes)
|
||||
CrashReporterMetadataShmem::ReadAppNotes(const Shmem& aShmem,
|
||||
AnnotationTable& aNotes)
|
||||
{
|
||||
for (MetadataShmemReader reader(aShmem); !reader.Done(); reader.Next()) {
|
||||
switch (reader.Type()) {
|
||||
case EntryType::Annotation: {
|
||||
nsCString key, value;
|
||||
if (!reader.Read(key) || !reader.Read(value)) {
|
||||
Annotation key;
|
||||
nsCString value;
|
||||
if (!reader.Read(&key) || !reader.Read(value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
aNotes->Put(key, value);
|
||||
aNotes[key] = value;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -25,10 +25,12 @@ public:
|
|||
~CrashReporterMetadataShmem();
|
||||
|
||||
// Metadata writers. These must only be called in child processes.
|
||||
void AnnotateCrashReport(const nsCString& aKey, const nsCString& aData);
|
||||
void AnnotateCrashReport(CrashReporter::Annotation aKey,
|
||||
const nsCString& aData);
|
||||
void AppendAppNotes(const nsCString& aData);
|
||||
|
||||
static void ReadAppNotes(const Shmem& aShmem, CrashReporter::AnnotationTable* aNotes);
|
||||
static void ReadAppNotes(const Shmem& aShmem,
|
||||
CrashReporter::AnnotationTable& aNotes);
|
||||
|
||||
private:
|
||||
void SyncNotesToShmem();
|
||||
|
@ -36,7 +38,7 @@ private:
|
|||
private:
|
||||
Shmem mShmem;
|
||||
|
||||
AnnotationTable mNotes;
|
||||
AnnotationTable mAnnotations;
|
||||
nsCString mAppNotes;
|
||||
};
|
||||
|
||||
|
|
|
@ -137,12 +137,14 @@ struct EnumSerializer {
|
|||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult) {
|
||||
uintParamType value;
|
||||
if (!ReadParam(aMsg, aIter, &value)) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCReadErrorReason"),
|
||||
NS_LITERAL_CSTRING("Bad iter"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCReadErrorReason,
|
||||
NS_LITERAL_CSTRING("Bad iter"));
|
||||
return false;
|
||||
} else if (!EnumValidator::IsLegalValue(paramType(value))) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCReadErrorReason"),
|
||||
NS_LITERAL_CSTRING("Illegal value"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCReadErrorReason,
|
||||
NS_LITERAL_CSTRING("Illegal value"));
|
||||
return false;
|
||||
}
|
||||
*aResult = paramType(value);
|
||||
|
|
|
@ -774,9 +774,8 @@ void
|
|||
MessageChannel::WillDestroyCurrentMessageLoop()
|
||||
{
|
||||
#if defined(DEBUG)
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("IPCFatalErrorProtocol"),
|
||||
nsDependentCString(mName));
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::IPCFatalErrorProtocol,
|
||||
nsDependentCString(mName));
|
||||
MOZ_CRASH("MessageLoop destroyed before MessageChannel that's bound to it");
|
||||
#endif
|
||||
|
||||
|
@ -804,8 +803,7 @@ MessageChannel::Clear()
|
|||
// shouldn't intentionally crash here.
|
||||
if (!Unsound_IsClosed() && !mInKillHardShutdown) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("IPCFatalErrorProtocol"),
|
||||
nsDependentCString(mName));
|
||||
CrashReporter::Annotation::IPCFatalErrorProtocol, nsDependentCString(mName));
|
||||
switch (mChannelState) {
|
||||
case ChannelOpening:
|
||||
MOZ_CRASH("MessageChannel destroyed without being closed " \
|
||||
|
|
|
@ -159,8 +159,12 @@ void
|
|||
ProcessLink::SendMessage(Message *msg)
|
||||
{
|
||||
if (msg->size() > IPC::Channel::kMaximumMessageSize) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCMessageName"), nsDependentCString(msg->name()));
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("IPCMessageSize"), nsPrintfCString("%d", msg->size()));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCMessageName,
|
||||
nsDependentCString(msg->name()));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCMessageSize,
|
||||
static_cast<int>(msg->size()));
|
||||
MOZ_CRASH("IPC message size is too large");
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ bool DuplicateHandle(HANDLE aSourceHandle,
|
|||
aTargetProcessId));
|
||||
if (!targetProcess) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("IPCTransportFailureReason"),
|
||||
CrashReporter::Annotation::IPCTransportFailureReason,
|
||||
NS_LITERAL_CSTRING("Failed to open target process."));
|
||||
return false;
|
||||
}
|
||||
|
@ -233,20 +233,18 @@ AnnotateSystemError()
|
|||
#endif
|
||||
if (error) {
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("IPCSystemError"),
|
||||
CrashReporter::Annotation::IPCSystemError,
|
||||
nsPrintfCString("%" PRId64, error));
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
void
|
||||
AnnotateCrashReportWithErrno(const char* tag, int error)
|
||||
AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error)
|
||||
{
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
nsCString(tag),
|
||||
nsPrintfCString("%d", error));
|
||||
CrashReporter::AnnotateCrashReport(tag, error);
|
||||
}
|
||||
#endif
|
||||
#endif // defined(XP_MACOSX)
|
||||
|
||||
void
|
||||
LogMessageForProtocol(const char* aTopLevelProtocol, base::ProcessId aOtherPid,
|
||||
|
@ -290,8 +288,9 @@ 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(NS_LITERAL_CSTRING("IPCFatalErrorMsg"),
|
||||
nsDependentCString(aMsg));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::IPCFatalErrorMsg,
|
||||
nsDependentCString(aMsg));
|
||||
AnnotateSystemError();
|
||||
#ifndef FUZZING
|
||||
MOZ_CRASH("IPC FatalError in the parent process!");
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsICrashReporter.h"
|
||||
#include "nsILabelableRunnable.h"
|
||||
|
||||
#if defined(ANDROID) && defined(DEBUG)
|
||||
|
@ -914,9 +915,9 @@ private:
|
|||
};
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
void AnnotateCrashReportWithErrno(const char* tag, int error);
|
||||
void AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error);
|
||||
#else
|
||||
static inline void AnnotateCrashReportWithErrno(const char* tag, int error)
|
||||
static inline void AnnotateCrashReportWithErrno(CrashReporter::Annotation tag, int error)
|
||||
{}
|
||||
#endif
|
||||
|
||||
|
@ -936,7 +937,8 @@ CreateEndpoints(const PrivateIPDLInterface& aPrivate,
|
|||
TransportDescriptor parentTransport, childTransport;
|
||||
nsresult rv;
|
||||
if (NS_FAILED(rv = CreateTransport(aParentDestPid, &parentTransport, &childTransport))) {
|
||||
AnnotateCrashReportWithErrno("IpcCreateEndpointsNsresult", int(rv));
|
||||
AnnotateCrashReportWithErrno(
|
||||
CrashReporter::Annotation::IpcCreateEndpointsNsresult, int(rv));
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,11 +40,13 @@ CreateTransport(base::ProcessId aProcIdOne,
|
|||
// dup them here
|
||||
fd1 = dup(fd1);
|
||||
if (fd1 < 0) {
|
||||
AnnotateCrashReportWithErrno("IpcCreateTransportDupErrno", errno);
|
||||
AnnotateCrashReportWithErrno(
|
||||
CrashReporter::Annotation::IpcCreateTransportDupErrno, errno);
|
||||
}
|
||||
fd2 = dup(fd2);
|
||||
if (fd2 < 0) {
|
||||
AnnotateCrashReportWithErrno("IpcCreateTransportDupErrno", errno);
|
||||
AnnotateCrashReportWithErrno(
|
||||
CrashReporter::Annotation::IpcCreateTransportDupErrno, errno);
|
||||
}
|
||||
|
||||
if (fd1 < 0 || fd2 < 0) {
|
||||
|
|
|
@ -210,8 +210,9 @@ struct ParamTraits<mozilla::mscom::COMPtrHolder<Interface, _IID>>
|
|||
|
||||
mozilla::mscom::ProxyStream proxyStream(_IID, buf.get(), length, &env);
|
||||
if (!proxyStream.IsValid()) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamValid"),
|
||||
NS_LITERAL_CSTRING("false"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ProxyStreamValid,
|
||||
NS_LITERAL_CSTRING("false"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,8 @@ ProxyStream::ProxyStream(REFIID aIID, const BYTE* aInitBuf,
|
|||
, mBufSize(aInitBufSize)
|
||||
, mPreserveStream(false)
|
||||
{
|
||||
NS_NAMED_LITERAL_CSTRING(kCrashReportKey, "ProxyStreamUnmarshalStatus");
|
||||
CrashReporter::Annotation kCrashReportKey =
|
||||
CrashReporter::Annotation::ProxyStreamUnmarshalStatus;
|
||||
|
||||
if (!aInitBufSize) {
|
||||
CrashReporter::AnnotateCrashReport(kCrashReportKey,
|
||||
|
@ -136,7 +137,7 @@ ProxyStream::ProxyStream(REFIID aIID, const BYTE* aInitBuf,
|
|||
if (FAILED(unmarshalResult) || !mUnmarshaledProxy) {
|
||||
nsPrintfCString hrAsStr("0x%08X", unmarshalResult);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("CoUnmarshalInterfaceResult"), hrAsStr);
|
||||
CrashReporter::Annotation::CoUnmarshalInterfaceResult, hrAsStr);
|
||||
AnnotateInterfaceRegistration(aIID);
|
||||
if (!mUnmarshaledProxy) {
|
||||
CrashReporter::AnnotateCrashReport(kCrashReportKey,
|
||||
|
@ -145,24 +146,21 @@ ProxyStream::ProxyStream(REFIID aIID, const BYTE* aInitBuf,
|
|||
|
||||
#if defined(ACCESSIBILITY)
|
||||
AnnotateClassRegistration(CLSID_AccessibleHandler);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("UnmarshalActCtx"),
|
||||
strActCtx);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("UnmarshalActCtxManifestPath"),
|
||||
NS_ConvertUTF16toUTF8(manifestPath));
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("A11yHandlerRegistered"),
|
||||
a11y::IsHandlerRegistered() ?
|
||||
NS_LITERAL_CSTRING("true") :
|
||||
NS_LITERAL_CSTRING("false"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::UnmarshalActCtx, strActCtx);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::UnmarshalActCtxManifestPath,
|
||||
NS_ConvertUTF16toUTF8(manifestPath));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::A11yHandlerRegistered,
|
||||
a11y::IsHandlerRegistered() ? NS_LITERAL_CSTRING("true")
|
||||
: NS_LITERAL_CSTRING("false"));
|
||||
|
||||
nsAutoCString strExpectedStreamLen;
|
||||
strExpectedStreamLen.AppendInt(expectedStreamLen);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ExpectedStreamLen"),
|
||||
strExpectedStreamLen);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ExpectedStreamLen, expectedStreamLen);
|
||||
|
||||
nsAutoCString actualStreamLen;
|
||||
actualStreamLen.AppendInt(aInitBufSize);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ActualStreamLen"),
|
||||
actualStreamLen);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ActualStreamLen, aInitBufSize);
|
||||
#endif // defined(ACCESSIBILITY)
|
||||
}
|
||||
}
|
||||
|
@ -360,38 +358,37 @@ ProxyStream::ProxyStream(REFIID aIID, IUnknown* aObject, Environment* aEnv,
|
|||
if (FAILED(createStreamResult)) {
|
||||
nsPrintfCString hrAsStr("0x%08X", createStreamResult);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("CreateStreamOnHGlobalFailure"),
|
||||
hrAsStr);
|
||||
CrashReporter::Annotation::CreateStreamOnHGlobalFailure, hrAsStr);
|
||||
}
|
||||
|
||||
if (FAILED(marshalResult)) {
|
||||
AnnotateInterfaceRegistration(aIID);
|
||||
nsPrintfCString hrAsStr("0x%08X", marshalResult);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("CoMarshalInterfaceFailure"), hrAsStr);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("MarshalActCtxManifestPath"),
|
||||
NS_ConvertUTF16toUTF8(manifestPath));
|
||||
CrashReporter::Annotation::CoMarshalInterfaceFailure, hrAsStr);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::MarshalActCtxManifestPath,
|
||||
NS_ConvertUTF16toUTF8(manifestPath));
|
||||
}
|
||||
|
||||
if (FAILED(statResult)) {
|
||||
nsPrintfCString hrAsStr("0x%08X", statResult);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("StatFailure"),
|
||||
hrAsStr);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::StatFailure,
|
||||
hrAsStr);
|
||||
}
|
||||
|
||||
if (FAILED(getHGlobalResult)) {
|
||||
nsPrintfCString hrAsStr("0x%08X", getHGlobalResult);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("GetHGlobalFromStreamFailure"),
|
||||
hrAsStr);
|
||||
CrashReporter::Annotation::GetHGlobalFromStreamFailure, hrAsStr);
|
||||
}
|
||||
|
||||
mStream = std::move(stream);
|
||||
|
||||
if (streamSize) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSizeFrom"),
|
||||
NS_LITERAL_CSTRING("IStream::Stat"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ProxyStreamSizeFrom,
|
||||
NS_LITERAL_CSTRING("IStream::Stat"));
|
||||
mBufSize = streamSize;
|
||||
}
|
||||
|
||||
|
@ -406,16 +403,14 @@ ProxyStream::ProxyStream(REFIID aIID, IUnknown* aObject, Environment* aEnv,
|
|||
// the size of the memory block allocated by the HGLOBAL, though it might
|
||||
// be larger than the actual stream size.
|
||||
if (!streamSize) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSizeFrom"),
|
||||
NS_LITERAL_CSTRING("GlobalSize"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ProxyStreamSizeFrom,
|
||||
NS_LITERAL_CSTRING("GlobalSize"));
|
||||
mBufSize = static_cast<int>(::GlobalSize(hglobal));
|
||||
}
|
||||
|
||||
nsAutoCString strBufSize;
|
||||
strBufSize.AppendInt(mBufSize);
|
||||
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProxyStreamSize"),
|
||||
strBufSize);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProxyStreamSize,
|
||||
mBufSize);
|
||||
}
|
||||
|
||||
} // namespace mscom
|
||||
|
|
|
@ -376,16 +376,15 @@ AnnotateInterfaceRegistration(REFIID aIid)
|
|||
|
||||
json.End();
|
||||
|
||||
nsAutoCString annotationKey;
|
||||
annotationKey.AppendLiteral("InterfaceRegistrationInfo");
|
||||
CrashReporter::Annotation annotationKey;
|
||||
if (XRE_IsParentProcess()) {
|
||||
annotationKey.AppendLiteral("Parent");
|
||||
annotationKey = CrashReporter::Annotation::InterfaceRegistrationInfoParent;
|
||||
} else {
|
||||
annotationKey.AppendLiteral("Child");
|
||||
annotationKey = CrashReporter::Annotation::InterfaceRegistrationInfoChild;
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(annotationKey,
|
||||
static_cast<CStringWriter*>(json.WriteFunc())->Get());
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
annotationKey,
|
||||
static_cast<CStringWriter*>(json.WriteFunc())->Get());
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -414,12 +413,11 @@ AnnotateClassRegistration(REFCLSID aClsid)
|
|||
|
||||
json.End();
|
||||
|
||||
nsAutoCString annotationKey;
|
||||
annotationKey.AppendLiteral("ClassRegistrationInfo");
|
||||
CrashReporter::Annotation annotationKey;
|
||||
if (XRE_IsParentProcess()) {
|
||||
annotationKey.AppendLiteral("Parent");
|
||||
annotationKey = CrashReporter::Annotation::ClassRegistrationInfoParent;
|
||||
} else {
|
||||
annotationKey.AppendLiteral("Child");
|
||||
annotationKey = CrashReporter::Annotation::ClassRegistrationInfoChild;
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(annotationKey,
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "js/Printf.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "mozilla/Module.h"
|
||||
#include "nsIFile.h"
|
||||
|
@ -56,10 +57,6 @@
|
|||
#include "mozilla/UniquePtrExtensions.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
#include "mozilla/ipc/CrashReporterClient.h"
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::scache;
|
||||
using namespace mozilla::loader;
|
||||
|
@ -363,11 +360,10 @@ ResolveModuleObjectProperty(JSContext* aCx, HandleObject aModObj, const char* na
|
|||
return aModObj;
|
||||
}
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
static mozilla::Result<nsCString, nsresult> ReadScript(ComponentLoaderInfo& aInfo);
|
||||
|
||||
static nsresult
|
||||
AnnotateScriptContents(const nsACString& aName, const nsACString& aURI)
|
||||
AnnotateScriptContents(CrashReporter::Annotation aName, const nsACString& aURI)
|
||||
{
|
||||
ComponentLoaderInfo info(aURI);
|
||||
|
||||
|
@ -384,20 +380,17 @@ AnnotateScriptContents(const nsACString& aName, const nsACString& aURI)
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif // defined MOZ_CRASHREPORTER
|
||||
|
||||
nsresult
|
||||
mozJSComponentLoader::AnnotateCrashReport()
|
||||
{
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
Unused << AnnotateScriptContents(
|
||||
NS_LITERAL_CSTRING("nsAsyncShutdownComponent"),
|
||||
CrashReporter::Annotation::nsAsyncShutdownComponent,
|
||||
NS_LITERAL_CSTRING("resource://gre/components/nsAsyncShutdown.js"));
|
||||
|
||||
Unused << AnnotateScriptContents(
|
||||
NS_LITERAL_CSTRING("AsyncShutdownModule"),
|
||||
CrashReporter::Annotation::AsyncShutdownModule,
|
||||
NS_LITERAL_CSTRING("resource://gre/modules/AsyncShutdown.jsm"));
|
||||
#endif // defined MOZ_CRASHREPORTER
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -684,7 +684,7 @@ bool Gecko_DocumentRule_UseForPresentation(RawGeckoPresContextBorrowed,
|
|||
void Gecko_SetJemallocThreadLocalArena(bool enabled);
|
||||
|
||||
void Gecko_AddBufferToCrashReport(const void* addr, size_t len);
|
||||
void Gecko_AnnotateCrashReport(const char* key_str, const char* value_str);
|
||||
void Gecko_AnnotateCrashReport(uint32_t key, const char* value_str);
|
||||
|
||||
// Pseudo-element flags.
|
||||
#define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
|
||||
|
|
|
@ -712,8 +712,9 @@ AnnotateCrashReport(nsIURI* aURI)
|
|||
annotation.AppendLiteral("No GRE omnijar\n");
|
||||
}
|
||||
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("SheetLoadFailure"),
|
||||
NS_ConvertUTF16toUTF8(annotation));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::SheetLoadFailure,
|
||||
NS_ConvertUTF16toUTF8(annotation));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -8,6 +8,7 @@ package org.mozilla.gecko.telemetry.pingbuilders;
|
|||
|
||||
import android.util.Log;
|
||||
|
||||
import org.mozilla.gecko.CrashReporterConstants;
|
||||
import org.mozilla.gecko.sync.ExtendedJSONObject;
|
||||
import org.mozilla.gecko.sync.NonObjectJSONException;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
|
@ -35,40 +36,6 @@ public class TelemetryCrashPingBuilder extends TelemetryPingBuilder {
|
|||
private static final String ISO8601_DATE = "yyyy-MM-dd";
|
||||
private static final String ISO8601_DATE_HOURS = "yyyy-MM-dd'T'HH':00:00.000Z'";
|
||||
|
||||
// The following list should be kept in sync with the one in CrashManager.jsm
|
||||
private static final String[] ANNOTATION_WHITELIST = {
|
||||
"AsyncShutdownTimeout",
|
||||
"AvailablePageFile",
|
||||
"AvailablePhysicalMemory",
|
||||
"AvailableVirtualMemory",
|
||||
"BlockedDllList",
|
||||
"BlocklistInitFailed",
|
||||
"BuildID",
|
||||
"ContainsMemoryReport",
|
||||
"CrashTime",
|
||||
"EventLoopNestingLevel",
|
||||
"ipc_channel_error",
|
||||
"IsGarbageCollecting",
|
||||
"LowCommitSpaceEvents",
|
||||
"MozCrashReason",
|
||||
"OOMAllocationSize",
|
||||
"ProductID",
|
||||
"ProductName",
|
||||
"ReleaseChannel",
|
||||
"RemoteType",
|
||||
"SecondsSinceLastCrash",
|
||||
"ShutdownProgress",
|
||||
"StartupCrash",
|
||||
"SystemMemoryUsePercentage",
|
||||
"TextureUsage",
|
||||
"TotalPageFile",
|
||||
"TotalPhysicalMemory",
|
||||
"TotalVirtualMemory",
|
||||
"UptimeTS",
|
||||
"User32BeforeBlocklist",
|
||||
"Version",
|
||||
};
|
||||
|
||||
public TelemetryCrashPingBuilder(String crashId, String clientId, HashMap<String, String> annotations) {
|
||||
super(TelemetryPingBuilder.UNIFIED_TELEMETRY_VERSION);
|
||||
|
||||
|
@ -178,7 +145,7 @@ public class TelemetryCrashPingBuilder extends TelemetryPingBuilder {
|
|||
ExtendedJSONObject node = new ExtendedJSONObject();
|
||||
|
||||
for (Entry<String, String> pair : annotations.entrySet()) {
|
||||
if (Arrays.binarySearch(ANNOTATION_WHITELIST, pair.getKey()) >= 0) {
|
||||
if (Arrays.binarySearch(CrashReporterConstants.ANNOTATION_WHITELIST, pair.getKey()) >= 0) {
|
||||
node.put(pair.getKey(), pair.getValue());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ GENERATED_FILES += [
|
|||
'AndroidManifest.xml',
|
||||
'generated/preprocessed/org/mozilla/gecko/AdjustConstants.java',
|
||||
'generated/preprocessed/org/mozilla/gecko/AppConstants.java',
|
||||
'generated/preprocessed/org/mozilla/gecko/CrashReporterConstants.java',
|
||||
'generated/preprocessed/org/mozilla/gecko/MmaConstants.java',
|
||||
]
|
||||
x = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/AdjustConstants.java']
|
||||
|
@ -131,6 +132,11 @@ z = GENERATED_FILES['AndroidManifest.xml']
|
|||
z.script = 'generate_build_config.py:generate_android_manifest'
|
||||
z.inputs += ['AndroidManifest.xml.in']
|
||||
|
||||
# Generate CrashReporterConstants.java
|
||||
crash_reporter_constants = GENERATED_FILES['generated/preprocessed/org/mozilla/gecko/CrashReporterConstants.java']
|
||||
crash_reporter_constants.script = '/toolkit/crashreporter/generate_crash_reporter_sources.py:emit_class'
|
||||
crash_reporter_constants.inputs += ['/toolkit/crashreporter/CrashAnnotations.yaml']
|
||||
|
||||
# Regular builds invoke `libs` targets that localize files with no AB_CD set
|
||||
# into the default resources (res/{values,raw}).
|
||||
#
|
||||
|
@ -192,6 +198,7 @@ GENERATED_FILES[t].inputs += [
|
|||
'!AndroidManifest.xml',
|
||||
'!generated/preprocessed/org/mozilla/gecko/AdjustConstants.java',
|
||||
'!generated/preprocessed/org/mozilla/gecko/AppConstants.java',
|
||||
'!generated/preprocessed/org/mozilla/gecko/CrashReporterConstants.java',
|
||||
'!generated/preprocessed/org/mozilla/gecko/MmaConstants.java',
|
||||
# These all depend on AB_CD, which isn't captured in this definition. Due
|
||||
# to subtle RecursiveMake details, everything works out. In the future we
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#pragma warning( pop )
|
||||
|
||||
#include "Authenticode.h"
|
||||
#include "CrashAnnotations.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsWindowsDllInterceptor.h"
|
||||
#include "mozilla/Sprintf.h"
|
||||
|
@ -38,6 +39,9 @@
|
|||
|
||||
using namespace mozilla;
|
||||
|
||||
using CrashReporter::Annotation;
|
||||
using CrashReporter::AnnotationToString;
|
||||
|
||||
#define DLL_BLOCKLIST_ENTRY(name, ...) \
|
||||
{ name, __VA_ARGS__ },
|
||||
#define DLL_BLOCKLIST_STRING_TYPE const char*
|
||||
|
@ -46,18 +50,6 @@ using namespace mozilla;
|
|||
// define this for very verbose dll load debug spew
|
||||
#undef DEBUG_very_verbose
|
||||
|
||||
static const char kBlockedDllsParameter[] = "BlockedDllList=";
|
||||
static const int kBlockedDllsParameterLen =
|
||||
sizeof(kBlockedDllsParameter) - 1;
|
||||
|
||||
static const char kBlocklistInitFailedParameter[] = "BlocklistInitFailed=1\n";
|
||||
static const int kBlocklistInitFailedParameterLen =
|
||||
sizeof(kBlocklistInitFailedParameter) - 1;
|
||||
|
||||
static const char kUser32BeforeBlocklistParameter[] = "User32BeforeBlocklist=1\n";
|
||||
static const int kUser32BeforeBlocklistParameterLen =
|
||||
sizeof(kUser32BeforeBlocklistParameter) - 1;
|
||||
|
||||
static uint32_t sInitFlags;
|
||||
static bool sBlocklistInitAttempted;
|
||||
static bool sBlocklistInitFailed;
|
||||
|
@ -779,23 +771,31 @@ DllBlocklist_Initialize(uint32_t aInitFlags)
|
|||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
WriteAnnotation(HANDLE aFile, Annotation aAnnotation, const char* aValue,
|
||||
DWORD* aNumBytes)
|
||||
{
|
||||
const char* str = AnnotationToString(aAnnotation);
|
||||
WriteFile(aFile, str, strlen(str), aNumBytes, nullptr);
|
||||
WriteFile(aFile, "=", 1, aNumBytes, nullptr);
|
||||
WriteFile(aFile, aValue, strlen(aValue), aNumBytes, nullptr);
|
||||
}
|
||||
|
||||
static void
|
||||
InternalWriteNotes(HANDLE file)
|
||||
{
|
||||
DWORD nBytes;
|
||||
|
||||
WriteFile(file, kBlockedDllsParameter, kBlockedDllsParameterLen, &nBytes, nullptr);
|
||||
WriteAnnotation(file, Annotation::BlockedDllList, "", &nBytes);
|
||||
DllBlockSet::Write(file);
|
||||
WriteFile(file, "\n", 1, &nBytes, nullptr);
|
||||
|
||||
if (sBlocklistInitFailed) {
|
||||
WriteFile(file, kBlocklistInitFailedParameter,
|
||||
kBlocklistInitFailedParameterLen, &nBytes, nullptr);
|
||||
WriteAnnotation(file, Annotation::BlocklistInitFailed, "1\n", &nBytes);
|
||||
}
|
||||
|
||||
if (sUser32BeforeBlocklist) {
|
||||
WriteFile(file, kUser32BeforeBlocklistParameter,
|
||||
kUser32BeforeBlocklistParameterLen, &nBytes, nullptr);
|
||||
WriteAnnotation(file, Annotation::User32BeforeBlocklist, "1\n", &nBytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,7 +107,8 @@ struct ParamTraits<mozilla::net::NetAddr>
|
|||
} else {
|
||||
if (XRE_IsParentProcess()) {
|
||||
nsPrintfCString msg("%d", aParam.raw.family);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Unknown NetAddr socket family"), msg);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::UnknownNetAddrSocketFamily, msg);
|
||||
}
|
||||
|
||||
MOZ_CRASH("Unknown socket family");
|
||||
|
|
|
@ -796,7 +796,7 @@ Service::Observe(nsISupports *, const char *aTopic, const char16_t *)
|
|||
// getFilename is only the leaf name for the database file,
|
||||
// so it shouldn't contain privacy-sensitive information.
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("StorageConnectionNotClosed"),
|
||||
CrashReporter::Annotation::StorageConnectionNotClosed,
|
||||
connections[i]->getFilename());
|
||||
#ifdef DEBUG
|
||||
printf_stderr("Storage connection not closed: %s",
|
||||
|
|
|
@ -221,44 +221,6 @@ this.CrashManager.prototype = Object.freeze({
|
|||
// The type of event is unknown.
|
||||
EVENT_FILE_ERROR_UNKNOWN_EVENT: "unknown-event",
|
||||
|
||||
// A whitelist of crash annotations which do not contain sensitive data
|
||||
// and are saved in the crash record and sent with Firefox Health Report.
|
||||
ANNOTATION_WHITELIST: [
|
||||
"AsyncShutdownTimeout",
|
||||
"BuildID",
|
||||
"ipc_channel_error",
|
||||
"LowCommitSpaceEvents",
|
||||
"ProductID",
|
||||
"ProductName",
|
||||
"ReleaseChannel",
|
||||
"RemoteType",
|
||||
"SecondsSinceLastCrash",
|
||||
"ShutdownProgress",
|
||||
"StartupCrash",
|
||||
"TelemetryEnvironment",
|
||||
"Version",
|
||||
// The following entries are not normal annotations that can be found in
|
||||
// the .extra file but are included in the crash record/FHR:
|
||||
"AvailablePageFile",
|
||||
"AvailablePhysicalMemory",
|
||||
"AvailableVirtualMemory",
|
||||
"BlockedDllList",
|
||||
"BlocklistInitFailed",
|
||||
"ContainsMemoryReport",
|
||||
"CrashTime",
|
||||
"EventLoopNestingLevel",
|
||||
"IsGarbageCollecting",
|
||||
"MozCrashReason",
|
||||
"OOMAllocationSize",
|
||||
"SystemMemoryUsePercentage",
|
||||
"TextureUsage",
|
||||
"TotalPageFile",
|
||||
"TotalPhysicalMemory",
|
||||
"TotalVirtualMemory",
|
||||
"UptimeTS",
|
||||
"User32BeforeBlocklist",
|
||||
],
|
||||
|
||||
/**
|
||||
* Obtain a list of all dumps pending upload.
|
||||
*
|
||||
|
@ -637,10 +599,16 @@ this.CrashManager.prototype = Object.freeze({
|
|||
|
||||
_filterAnnotations(annotations) {
|
||||
let filteredAnnotations = {};
|
||||
let crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"]
|
||||
.getService(Ci.nsICrashReporter);
|
||||
|
||||
for (let line in annotations) {
|
||||
if (this.ANNOTATION_WHITELIST.includes(line)) {
|
||||
filteredAnnotations[line] = annotations[line];
|
||||
try {
|
||||
if (crashReporter.isAnnotationWhitelistedForPing(line)) {
|
||||
filteredAnnotations[line] = annotations[line];
|
||||
}
|
||||
} catch (e) {
|
||||
// Silently drop unknown annotations
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ Vendor=Mozilla
|
|||
InstallTime=1000000000
|
||||
Theme=classic/1.0
|
||||
ReleaseChannel=default
|
||||
AddonsShouldHaveBlockedE10s=1
|
||||
ServerURL=https://crash-reports.mozilla.com
|
||||
SafeMode=0
|
||||
ContentSandboxCapable=1
|
||||
|
|
|
@ -72,12 +72,20 @@ function reportTestReason(val) {
|
|||
histogram.add(val);
|
||||
}
|
||||
|
||||
function annotateCrashReport(value) {
|
||||
function annotateCrashReport() {
|
||||
try {
|
||||
// "1" if we're annotating the crash report, "" to remove the annotation.
|
||||
var crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"].
|
||||
getService(Ci.nsICrashReporter);
|
||||
crashReporter.annotateCrashReport("GraphicsSanityTest", value ? "1" : "");
|
||||
crashReporter.annotateCrashReport("GraphicsSanityTest", "1");
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
||||
function removeCrashReportAnnotation(value) {
|
||||
try {
|
||||
var crashReporter = Cc["@mozilla.org/toolkit/crash-reporter;1"].
|
||||
getService(Ci.nsICrashReporter);
|
||||
crashReporter.removeCrashReportAnnotation("GraphicsSanityTest");
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
|
@ -242,7 +250,7 @@ var listener = {
|
|||
|
||||
// Remove the annotation after we've cleaned everything up, to catch any
|
||||
// incidental crashes from having performed the sanity test.
|
||||
annotateCrashReport(false);
|
||||
removeCrashReportAnnotation();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -330,7 +338,7 @@ SanityTest.prototype = {
|
|||
|
||||
if (!this.shouldRunTest()) return;
|
||||
|
||||
annotateCrashReport(true);
|
||||
annotateCrashReport();
|
||||
|
||||
// Open a tiny window to render our test page, and notify us when it's loaded
|
||||
var sanityTest = Services.ww.openWindow(null,
|
||||
|
|
|
@ -690,8 +690,8 @@ var TelemetrySendImpl = {
|
|||
|
||||
if (!this.sendingEnabled() || !TelemetryReportingPolicy.canUpload()) {
|
||||
// If we cannot send pings then clear the crash annotations
|
||||
crs.annotateCrashReport("TelemetryClientId", "");
|
||||
crs.annotateCrashReport("TelemetryServerURL", "");
|
||||
crs.removeCrashReportAnnotation("TelemetryClientId");
|
||||
crs.removeCrashReportAnnotation("TelemetryServerURL");
|
||||
} else {
|
||||
crs.annotateCrashReport("TelemetryClientId", clientId);
|
||||
crs.annotateCrashReport("TelemetryServerURL", server);
|
||||
|
|
|
@ -639,9 +639,14 @@ add_task(async function test_pref_observer() {
|
|||
reject(Error("Crash report annotation without expected value."));
|
||||
}
|
||||
|
||||
if (!expectedValue && value != "") {
|
||||
if (keys.size == 0) {
|
||||
MockRegistrar.unregister(gMockCrs);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
removeCrashReportAnnotation(key) {
|
||||
if (!keys.delete(key)) {
|
||||
MockRegistrar.unregister(gMockCrs);
|
||||
reject(Error(`Crash report annotation ("${key}") with unexpected value: "${value}".`));
|
||||
}
|
||||
|
||||
if (keys.size == 0) {
|
||||
|
|
|
@ -603,8 +603,8 @@ nsTerminator::UpdateCrashReport(const char* aTopic)
|
|||
// In case of crash, we wish to know where in shutdown we are
|
||||
nsAutoCString report(aTopic);
|
||||
|
||||
Unused << CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ShutdownProgress"),
|
||||
report);
|
||||
Unused << CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ShutdownProgress, report);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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 "CrashAnnotations.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
|
||||
using std::begin;
|
||||
using std::end;
|
||||
using std::find_if;
|
||||
|
||||
namespace CrashReporter {
|
||||
|
||||
bool
|
||||
AnnotationFromString(Annotation& aResult, const char* aValue)
|
||||
{
|
||||
auto elem = find_if(
|
||||
begin(kAnnotationStrings),
|
||||
end(kAnnotationStrings),
|
||||
[&aValue](const char* aString) {
|
||||
return strcmp(aString, aValue) == 0;
|
||||
}
|
||||
);
|
||||
|
||||
if (elem == end(kAnnotationStrings)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aResult = static_cast<Annotation>(elem - begin(kAnnotationStrings));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IsAnnotationWhitelistedForPing(Annotation aAnnotation) {
|
||||
auto elem = find_if(
|
||||
begin(kCrashPingWhitelist),
|
||||
end(kCrashPingWhitelist),
|
||||
[&aAnnotation](Annotation aElement) {
|
||||
return aElement == aAnnotation;
|
||||
}
|
||||
);
|
||||
|
||||
return elem != end(kCrashPingWhitelist);
|
||||
}
|
||||
|
||||
bool
|
||||
IsAnnotationBlacklistedForContent(Annotation aAnnotation)
|
||||
{
|
||||
auto elem = find_if(
|
||||
begin(kContentProcessBlacklist),
|
||||
end(kContentProcessBlacklist),
|
||||
[&aAnnotation](Annotation aElement) {
|
||||
return aElement == aAnnotation;
|
||||
}
|
||||
);
|
||||
|
||||
return elem != end(kContentProcessBlacklist);
|
||||
}
|
||||
|
||||
} // namespace CrashReporter
|
|
@ -0,0 +1,76 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* 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/. */
|
||||
|
||||
#ifndef CrashAnnotations_h
|
||||
#define CrashAnnotations_h
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace CrashReporter {
|
||||
|
||||
// Typed enum representing all crash annotations
|
||||
enum class Annotation : uint32_t {
|
||||
${enum}
|
||||
};
|
||||
|
||||
// Stringified crash annotation names
|
||||
const char* const kAnnotationStrings[] = {
|
||||
${strings}
|
||||
};
|
||||
|
||||
// Whitelist of crash annotations that can be included in a crash ping
|
||||
const Annotation kCrashPingWhitelist[] = {
|
||||
${whitelist}
|
||||
};
|
||||
|
||||
// Blacklist of crash annotations that shouldn't be read from a content process
|
||||
const Annotation kContentProcessBlacklist[] = {
|
||||
${blacklist}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return the string representation of a crash annotation.
|
||||
*
|
||||
* @param aAnnotation a crash annotation
|
||||
* @returns A constant string holding the annotation name
|
||||
*/
|
||||
static inline const char*
|
||||
AnnotationToString(Annotation aAnnotation) {
|
||||
return kAnnotationStrings[static_cast<uint32_t>(aAnnotation)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to its corresponding crash annotation.
|
||||
*
|
||||
* @param aResult a reference where the annotation will be stored
|
||||
* @param aValue the string to be converted
|
||||
* @return true if the string was successfully converted, false if it did not
|
||||
* correspond to any known annotation
|
||||
*/
|
||||
bool AnnotationFromString(Annotation& aResult, const char* aValue);
|
||||
|
||||
/**
|
||||
* Checks if the given crash annotation is whitelisted for inclusion in the
|
||||
* crash ping.
|
||||
*
|
||||
* @param aAnnotation the crash annotation to be checked
|
||||
* @return true if the annotation can be included in the crash ping, false
|
||||
* otherwise
|
||||
*/
|
||||
bool IsAnnotationWhitelistedForPing(Annotation aAnnotation);
|
||||
|
||||
/**
|
||||
* Checks if the given crash annotation needs to be filtered out when reading
|
||||
* a content process crash annotations. Blacklisted annotations will be
|
||||
* replaced with ones provided by the parent process.
|
||||
*
|
||||
* @param aAnnotation the crash annotation to be checked
|
||||
* @return true if the annotation needs to be filtered out when reading
|
||||
* annotations provided by a content process, false otherwise
|
||||
*/
|
||||
bool IsAnnotationBlacklistedForContent(Annotation aAnnotation);
|
||||
|
||||
} // namespace CrashReporter
|
||||
|
||||
#endif // CrashAnnotations_h
|
|
@ -0,0 +1,776 @@
|
|||
# This lists all the available crash annotations.
|
||||
#
|
||||
# Mandatory fields for each entry are:
|
||||
# - description: A string describing the annotation
|
||||
# - type: the annotation type, currently `string`, `integer` or `boolean`.
|
||||
# The latter are stringified to `1` for true and `0` for false.
|
||||
#
|
||||
# Additionally a field can have the following optional fields:
|
||||
# - altname: A string that will be used when writing out the annotation to the
|
||||
# .extra file instead of the annotation name
|
||||
# - ping: A boolean that indicates whether the annotation is whitelisted for
|
||||
# going into the crash ping, if not specified this defaults to false
|
||||
# - content: A boolean that indicates whether the field will be included in
|
||||
# subprocess reports, if not specified this defaults to true
|
||||
|
||||
A11yHandlerRegistered:
|
||||
description: >
|
||||
Set to "true" if the accessibility handler is registered, "false" otherwise.
|
||||
type: string
|
||||
|
||||
AbortMessage:
|
||||
description: >
|
||||
Message passed to NS_DebugBreak().
|
||||
type: string
|
||||
|
||||
Accessibility:
|
||||
description: >
|
||||
Set to "Active" by the accessibility service when it is active.
|
||||
type: string
|
||||
|
||||
AccessibilityClient:
|
||||
description: >
|
||||
Accessibility client ID.
|
||||
type: string
|
||||
|
||||
AccessibilityInProcClient:
|
||||
description: >
|
||||
Hexadecimal mask of in-process accessibility consumers, see
|
||||
accessible/windows/msaa/Compatibility.h for the mappings.
|
||||
type: string
|
||||
|
||||
ActualStreamLen:
|
||||
description: >
|
||||
Actual length of an IPC proxy stream.
|
||||
type: integer
|
||||
|
||||
AdapterDeviceID:
|
||||
description: >
|
||||
Graphics adapter name.
|
||||
type: string
|
||||
|
||||
AdapterDriverVersion:
|
||||
description: >
|
||||
Graphics adapter driver version.
|
||||
type: string
|
||||
|
||||
AdapterSubsysID:
|
||||
description: >
|
||||
Graphics adapter subsystem ID.
|
||||
type: string
|
||||
|
||||
AdapterVendorID:
|
||||
description: >
|
||||
Graphics adapter vendor name.
|
||||
type: string
|
||||
|
||||
additional_minidumps:
|
||||
description: >
|
||||
Comma separated list of additional minidumps for this crash, each element
|
||||
in the list represent the suffix used in the dump filename. E.g. the
|
||||
"browser" entry for crash fa909194-737b-4b93-b8da-da110ac785e0 implies the
|
||||
existence of the fa909194-737b-4b93-b8da-da110ac785e0-browser.dmp file.
|
||||
type: string
|
||||
|
||||
Addons:
|
||||
description: >
|
||||
List of currently enabled add-ons.
|
||||
type: string
|
||||
altname: Add-ons
|
||||
|
||||
AppInitDLLs:
|
||||
description: >
|
||||
List of DLLs loaded when launching any application on Windows, this
|
||||
reflects the contents of the AppInit_DLLs registry key.
|
||||
type: string
|
||||
|
||||
AsyncShutdownModule:
|
||||
description: >
|
||||
Holds the contents of the AsyncShutdown.js script
|
||||
type: string
|
||||
|
||||
AsyncShutdownTimeout:
|
||||
description: >
|
||||
This annotation is present if a shutdown blocker was not released in time
|
||||
and the browser was crashed instead of waiting for shutdown to finish. The
|
||||
condition that caused the hang is contained in the annotation.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
AvailablePageFile:
|
||||
description: >
|
||||
Windows-only, maximum amount of memory that can be committed. This
|
||||
annotation is populated with the contents of the MEMORYSTATUSEX's structure
|
||||
ullAvailPageFile field.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
AvailablePhysicalMemory:
|
||||
description: >
|
||||
Windows-only, amount of free physical memory in bytes. This annotation
|
||||
is populated with the contents of the MEMORYSTATUSEX's structure
|
||||
ullAvailPhys field.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
AvailableVirtualMemory:
|
||||
description: >
|
||||
Windows-only, amount of free virtual memory in bytes. This annotation is
|
||||
populated with the contents of the MEMORYSTATUSEX's structure
|
||||
ullAvailVirtual field.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
BIOS_Manufacturer:
|
||||
description: >
|
||||
Name of the BIOS manufacturer.
|
||||
type: string
|
||||
|
||||
BlockedDllList:
|
||||
description: >
|
||||
Comma-separated list of blocked DLLS, Windows-only
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
BlocklistInitFailed:
|
||||
description: >
|
||||
Set to 1 if the DLL blocklist could not be initialized.
|
||||
type: boolean
|
||||
ping: true
|
||||
|
||||
BreakpadReserveAddress:
|
||||
description: >
|
||||
Address of the buffer reserved by Breakpad.
|
||||
type: string
|
||||
|
||||
BreakpadReserveSize:
|
||||
description: >
|
||||
Size of the buffer reserved by Breakpad.
|
||||
type: string
|
||||
|
||||
BuildID:
|
||||
description: >
|
||||
Application build ID, the format is YYYYMMDDHHMMSS.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
ClassRegistrationInfoChild:
|
||||
description: >
|
||||
Microsoft COM class registration annotation for the child process.
|
||||
type: string
|
||||
|
||||
ClassRegistrationInfoParent:
|
||||
description: >
|
||||
Microsoft COM class registration annotation for the parent process.
|
||||
type: string
|
||||
|
||||
CoMarshalInterfaceFailure:
|
||||
description: >
|
||||
Annotation describing the error returned by trying to marshal an object
|
||||
via CoMarshalInterface during the creation of an IPC proxy stream.
|
||||
type: string
|
||||
|
||||
ContainsMemoryReport:
|
||||
description: >
|
||||
Indicates that the crash dump contains a memory report.
|
||||
type: boolean
|
||||
ping: true
|
||||
|
||||
ContentSandboxCapabilities:
|
||||
description: >
|
||||
List of capabilities of the content process sandbox.
|
||||
type: string
|
||||
|
||||
ContentSandboxEnabled:
|
||||
description: >
|
||||
Set to 1 when content process sandboxing is enabled.
|
||||
type: boolean
|
||||
|
||||
ContentSandboxCapable:
|
||||
description: >
|
||||
Set to 1 if the client is capable of content sandboxing.
|
||||
type: boolean
|
||||
|
||||
ContentSandboxLevel:
|
||||
description: >
|
||||
Content sandbox level.
|
||||
type: integer
|
||||
|
||||
CoUnmarshalInterfaceResult:
|
||||
description: >
|
||||
Annotation describing the error returned by trying to unmarshal an object
|
||||
via CoUnmarshalInterface during the creation of an IPC proxy stream.
|
||||
type: integer
|
||||
|
||||
CPUMicrocodeVersion:
|
||||
description: >
|
||||
Version of the CPU microcode.
|
||||
type: string
|
||||
|
||||
CpuUsageFlashProcess1:
|
||||
description: >
|
||||
CPU usage of the first Adobe Flash plugin process.
|
||||
type: string
|
||||
|
||||
CpuUsageFlashProcess2:
|
||||
description: >
|
||||
CPU usage of the second Adobe Flash plugin process.
|
||||
type: string
|
||||
|
||||
CrashAddressLikelyWrong:
|
||||
description: >
|
||||
Set to 1 if signal handling is broken, in which case the crash address is
|
||||
likely to be wrong.
|
||||
type: boolean
|
||||
|
||||
CrashTime:
|
||||
description: >
|
||||
Crash time in seconds since the Epoch.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
CreateStreamOnHGlobalFailure:
|
||||
description: >
|
||||
Set when failing to obtain a global memory handle during the creation of an
|
||||
IPC proxy stream.
|
||||
type: string
|
||||
|
||||
CycleCollector:
|
||||
description: >
|
||||
Reason why the cycle collector crashed.
|
||||
type: string
|
||||
|
||||
DeviceResetReason:
|
||||
description: >
|
||||
Reason why a DirectX device has been reset, Windows only.
|
||||
type: string
|
||||
|
||||
DOMIPCEnabled:
|
||||
description: >
|
||||
Set to 1 when a tab is running in a content process
|
||||
type: boolean
|
||||
|
||||
EMCheckCompatibility:
|
||||
description: >
|
||||
Set to 1 if add-on compatibility checking is enabled.
|
||||
type: boolean
|
||||
|
||||
EventLoopNestingLevel:
|
||||
description: >
|
||||
Present only if higher than 0, indicates that we're running in a nested
|
||||
event loop and indicates the nesting level.
|
||||
type: integer
|
||||
ping: true
|
||||
|
||||
ExpectedStreamLen:
|
||||
description: >
|
||||
Expected length of an IPC proxy stream.
|
||||
type: integer
|
||||
|
||||
FlashProcessDump:
|
||||
description: >
|
||||
Type of process the flash plugin is running in, can be either "Broker" or
|
||||
"Sandbox".
|
||||
type: string
|
||||
|
||||
FramePoisonBase:
|
||||
description: >
|
||||
Base pointer of the memory area used for the poison value we place in freed
|
||||
memory.
|
||||
type: string
|
||||
content: false
|
||||
|
||||
FramePoisonSize:
|
||||
description: >
|
||||
Size of the memory area used for the poison value we place in freed
|
||||
memory.
|
||||
type: integer
|
||||
content: false
|
||||
|
||||
GetHGlobalFromStreamFailure:
|
||||
description: >
|
||||
Error returned when invoking GetHGlobalFromStreamFailure() during the
|
||||
creation of an IPC stream proxy.
|
||||
type: string
|
||||
|
||||
GMPLibraryPath:
|
||||
description: >
|
||||
Holds the path to the GMP plugin library.
|
||||
type: string
|
||||
|
||||
GMPPlugin:
|
||||
description: >
|
||||
Set to 1 if the GMP plugin is enabled.
|
||||
type: boolean
|
||||
|
||||
GPUProcessLaunchCount:
|
||||
description: >
|
||||
Number of times the GPU process was launched.
|
||||
type: integer
|
||||
|
||||
GPUProcessStatus:
|
||||
description: >
|
||||
Status of the GPU process, can be set to "Running" or "Destroyed"
|
||||
type: string
|
||||
|
||||
GraphicsCriticalError:
|
||||
description: >
|
||||
Information of a critical error that occurred within the graphics code.
|
||||
type: string
|
||||
|
||||
GraphicsSanityTest:
|
||||
description: >
|
||||
Annotation used in tests.
|
||||
type: string
|
||||
|
||||
GraphicsStartupTest:
|
||||
description: >
|
||||
Set to 1 by the graphics driver crash guard when it's activated.
|
||||
type: boolean
|
||||
|
||||
HangMonitorDescription:
|
||||
description: >
|
||||
Name of the hang monitor that generated the crash.
|
||||
type: string
|
||||
|
||||
HasDeviceTouchScreen:
|
||||
description: >
|
||||
Set to 1 if the device had a touch-screen, this only applies to Firefox
|
||||
desktop as on mobile devices we assume a touch-screen is always present.
|
||||
type: boolean
|
||||
|
||||
IAccessibleConfig:
|
||||
description: >
|
||||
Set when something is seriously wrong with the IAccessible configuration in
|
||||
the computer's registry. The value is always set to "NoSystemTypeLibOrPS"
|
||||
type: string
|
||||
|
||||
InstallTime:
|
||||
description: >
|
||||
The time when Firefox was installed expressed as seconds since the Epoch
|
||||
type: integer
|
||||
|
||||
InterfaceRegistrationInfoChild:
|
||||
description: >
|
||||
Microsoft COM interface registration annotation for the child process.
|
||||
type: string
|
||||
|
||||
InterfaceRegistrationInfoParent:
|
||||
description: >
|
||||
Microsoft COM interface registration annotation for the parent process.
|
||||
type: string
|
||||
|
||||
ipc_channel_error:
|
||||
description: >
|
||||
Set before a content process crashes because of an IPC channel error, holds
|
||||
a description of the error.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
IpcCreateEndpointsNsresult:
|
||||
description: >
|
||||
errno value retrieved after failing to create an IPC transport object.
|
||||
type: integer
|
||||
|
||||
IpcCreatePipeCloExecErrno:
|
||||
description: >
|
||||
errno value retrieved after failing to set the O_CLOEXEC flag on a pipe
|
||||
used for IPC.
|
||||
type: integer
|
||||
|
||||
IpcCreatePipeFcntlErrno:
|
||||
description: >
|
||||
errno value retrieved after a call to fcntl() on a pipe used for IPC failed.
|
||||
type: integer
|
||||
|
||||
IpcCreatePipeSocketPairErrno:
|
||||
description: >
|
||||
errno value retrieved after a socketpair() call failed while creating an IPC
|
||||
transport object.
|
||||
type: integer
|
||||
|
||||
IpcCreateTransportDupErrno:
|
||||
description: >
|
||||
errno value retrieved after a dup() call failed while creating an IPC
|
||||
transport object.
|
||||
type: integer
|
||||
|
||||
IPCFatalErrorMsg:
|
||||
description: >
|
||||
Describes a fatal error that occurred during IPC operation.
|
||||
type: string
|
||||
|
||||
IPCFatalErrorProtocol:
|
||||
description: >
|
||||
Name of the protocol used by IPC when a fatal error occurred.
|
||||
type: string
|
||||
|
||||
IPCMessageName:
|
||||
description: >
|
||||
Name of the IPC message that caused a crash because it was too large.
|
||||
type: string
|
||||
|
||||
IPCMessageSize:
|
||||
description: >
|
||||
Size of the IPC message that caused a crash because it was too large.
|
||||
type: integer
|
||||
|
||||
IPCReadErrorReason:
|
||||
description: >
|
||||
Reason why reading an object via IPC failed.
|
||||
type: string
|
||||
|
||||
IPCShutdownState:
|
||||
description: >
|
||||
IPC shutdown state, can be set to either "RecvShutdown" or
|
||||
"SendFinishShutdown" by a content process while it's shutting down.
|
||||
type: string
|
||||
|
||||
IPCSystemError:
|
||||
description: >
|
||||
Description of the last system error that occurred during IPC operation.
|
||||
type: string
|
||||
|
||||
IPCTransportFailureReason:
|
||||
description: >
|
||||
Reason why creating an IPC channel failed.
|
||||
type: string
|
||||
|
||||
IsGarbageCollecting:
|
||||
description: >
|
||||
If true then the JavaScript garbage collector was running when the crash
|
||||
occurred.
|
||||
type: boolean
|
||||
ping: true
|
||||
|
||||
JavaStackTrace:
|
||||
description: >
|
||||
Java stack trace, only present on Firefox for Android if we encounter an
|
||||
uncaught Java exception.
|
||||
type: string
|
||||
|
||||
JSLargeAllocationFailure:
|
||||
description: >
|
||||
A large allocation couldn't be satisfied, check the JSOutOfMemory
|
||||
description for the possible values of this annotation.
|
||||
type: string
|
||||
|
||||
JSOutOfMemory:
|
||||
description: >
|
||||
A small allocation couldn't be satisfied, the annotation may contain the
|
||||
"Reporting", "Reported" or "Recovered" value. The first one means that
|
||||
we crashed while responding to the OOM condition (possibly while running a
|
||||
memory-pressure observers), the second that we crashed after having tried to
|
||||
free some memory, and the last that the GC had managed to free enough memory
|
||||
to satisfy the allocation.
|
||||
type: string
|
||||
|
||||
LowCommitSpaceEvents:
|
||||
description: >
|
||||
Number of times the available memory tracker has detected a that
|
||||
commit-space was running low. This is a Windows-specific annotation.
|
||||
type: integer
|
||||
ping: true
|
||||
|
||||
MarshalActCtxManifestPath:
|
||||
description: >
|
||||
Proxy stream marshalling current activation context manifest path.
|
||||
type: string
|
||||
|
||||
MozCrashReason:
|
||||
description: >
|
||||
Plaintext description of why Firefox crashed, this is usually set by
|
||||
assertions and the like.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
Notes:
|
||||
description: >
|
||||
Miscellaneous notes that can be appended to a crash.
|
||||
type: string
|
||||
|
||||
nsAsyncShutdownComponent:
|
||||
description: >
|
||||
Holds the contents of the nsAsyncShutdown.js script
|
||||
type: string
|
||||
|
||||
NumberOfProcessors:
|
||||
description: >
|
||||
Number of logical processors in the system.
|
||||
type: integer
|
||||
|
||||
OOMAllocationSize:
|
||||
description: >
|
||||
Size of the allocation that caused an out-of-memory condition.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
PluginCpuUsage:
|
||||
description: >
|
||||
CPU usage of the plugin process.
|
||||
type: string
|
||||
|
||||
PluginFilename:
|
||||
description: >
|
||||
Plugin filename, only the process holding the plugin has this annotation.
|
||||
type: string
|
||||
|
||||
PluginHang:
|
||||
description: >
|
||||
The presence of this annotation indicates that this crash was generated in
|
||||
response to a plugin hanging.
|
||||
type: boolean
|
||||
|
||||
PluginHangUIDuration:
|
||||
description: >
|
||||
Duration in milliseconds of the plugin hang that caused this crash.
|
||||
type: integer
|
||||
|
||||
PluginName:
|
||||
description: >
|
||||
Display name of a plugin, only the process holding the plugin has this
|
||||
annotation.
|
||||
type: string
|
||||
|
||||
PluginVersion:
|
||||
description: >
|
||||
Version of a plugin, only the process holding the plugin has this
|
||||
annotation.
|
||||
type: string
|
||||
|
||||
ProcessType:
|
||||
description: >
|
||||
Type of the process that crashed, can hold the values "content", "plugin" or
|
||||
"gpu" currently.
|
||||
type: string
|
||||
|
||||
ProductName:
|
||||
description: >
|
||||
Application name (e.g. Firefox).
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
ProductID:
|
||||
description: >
|
||||
Application UUID (e.g. ec8030f7-c20a-464f-9b0e-13a3a9e97384).
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
ProxyStreamSize:
|
||||
description: >
|
||||
Size of an IPC proxy stream.
|
||||
type: integer
|
||||
|
||||
ProxyStreamSizeFrom:
|
||||
description: >
|
||||
Describes how the size of a proxy stream was obtained. It can be set to
|
||||
either Stream::Stat or GlobalSize.
|
||||
type: string
|
||||
|
||||
ProxyStreamUnmarshalStatus:
|
||||
description: >
|
||||
Status of the proxy stream unmarshalling, see ipc/mscom/ProxyStream.cpp for
|
||||
the various value this annotation can take.
|
||||
type: string
|
||||
|
||||
ProxyStreamValid:
|
||||
description: >
|
||||
Set to "false" when encountering an invalid IPC proxy stream.
|
||||
type: string
|
||||
|
||||
ReleaseChannel:
|
||||
description: >
|
||||
Application release channel (e.g. default, beta, ...)
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
RemoteType:
|
||||
description: >
|
||||
Type of the content process, can be set to "web", "file" or "extension".
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
SafeMode:
|
||||
description: >
|
||||
Set to 1 if the browser was started in safe mode.
|
||||
type: boolean
|
||||
|
||||
SecondsSinceLastCrash:
|
||||
description: >
|
||||
Time in seconds since the last crash occurred.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
ServerURL:
|
||||
description: >
|
||||
URL used to post the crash report.
|
||||
type: string
|
||||
|
||||
SheetLoadFailure:
|
||||
description: >
|
||||
Set when failing to load a built-in style sheet. This can contain a
|
||||
potentially very large amount of diagnostic information.
|
||||
type: string
|
||||
|
||||
ShutdownProgress:
|
||||
description: >
|
||||
Shutdown step at which the browser crashed, can be set to "quit-application",
|
||||
"profile-change-teardown", "profile-before-change", "xpcom-will-shutdown" or
|
||||
"xpcom-shutdown".
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
StartupCrash:
|
||||
description: >
|
||||
If set to 1 then this crash occurred during startup.
|
||||
type: boolean
|
||||
content: false
|
||||
ping: true
|
||||
|
||||
StartupTime:
|
||||
description: >
|
||||
The time when Firefox was launched expressed in seconds since the Epoch.
|
||||
type: integer
|
||||
content: false
|
||||
|
||||
StatFailure:
|
||||
description: >
|
||||
Error returned when invoking IStream's Stat function during the creation
|
||||
of an IPC proxy stream.
|
||||
type: string
|
||||
|
||||
StorageConnectionNotClosed:
|
||||
description: >
|
||||
This annotation is added when a mozStorage connection has not been properly
|
||||
closed during shutdown. The annotation holds the filename of the database
|
||||
associated with the connection.
|
||||
type: string
|
||||
|
||||
SystemMemoryUsePercentage:
|
||||
description: >
|
||||
Windows-only, percentage of physical memory in use. This annotation is
|
||||
populated with the contents of the MEMORYSTATUSEX's structure dwMemoryLoad
|
||||
field.
|
||||
type: integer
|
||||
ping: true
|
||||
|
||||
TelemetryClientId:
|
||||
description: >
|
||||
Telemetry client ID.
|
||||
type: string
|
||||
|
||||
TelemetryEnvironment:
|
||||
description: >
|
||||
The telemetry environment in JSON format.
|
||||
type: string
|
||||
|
||||
TelemetryServerURL:
|
||||
description: >
|
||||
Telemetry server URL. Used to send main process crash pings directly from
|
||||
the crashreporter client.
|
||||
type: string
|
||||
|
||||
TelemetrySessionId:
|
||||
description: >
|
||||
Telemetry session ID.
|
||||
type: string
|
||||
|
||||
TestKey:
|
||||
description: >
|
||||
Annotation used in tests.
|
||||
type: string
|
||||
|
||||
TestUnicode:
|
||||
description: >
|
||||
Annotation used in tests.
|
||||
type: string
|
||||
|
||||
TextureUsage:
|
||||
description: >
|
||||
Amount of memory in bytes consumed by textures.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
ThreadIdNameMapping:
|
||||
description: >
|
||||
List of thread names with their corresponding thread IDs.
|
||||
type: string
|
||||
|
||||
TotalPageFile:
|
||||
description: >
|
||||
Windows-only, current committed memory limit. This annotation is
|
||||
populated with the contents of the MEMORYSTATUSEX's structure
|
||||
ullTotalPageFile field.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
TotalPhysicalMemory:
|
||||
description: >
|
||||
Windows-only, amount of physical memory in bytes. This annotation is
|
||||
populated with the contents of the MEMORYSTATUSEX's structure
|
||||
ullTotalPhys field.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
TotalVirtualMemory:
|
||||
description: >
|
||||
Windows-only, size of the virtual address space. This annotation is
|
||||
populated with the contents of the MEMORYSTATUSEX's structure
|
||||
ullTotalVirtual field.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
UnknownNetAddrSocketFamily:
|
||||
description: >
|
||||
An unknown network address family was requested to Necko. The value is the
|
||||
requested family number.
|
||||
type: integer
|
||||
|
||||
UnmarshalActCtx:
|
||||
description: >
|
||||
Proxy stream unmarshalling current activation context.
|
||||
type: string
|
||||
|
||||
UnmarshalActCtxManifestPath:
|
||||
description: >
|
||||
Proxy stream unmarshalling current activation context manifest path.
|
||||
type: string
|
||||
|
||||
UptimeTS:
|
||||
description: >
|
||||
Uptime in seconds. This annotation uses a string instead of an integer
|
||||
because it has a fractional component.
|
||||
type: string
|
||||
ping: true
|
||||
|
||||
URL:
|
||||
description: >
|
||||
URL being loaded.
|
||||
type: string
|
||||
content: false
|
||||
|
||||
User32BeforeBlocklist:
|
||||
description: >
|
||||
Set to 1 if user32.dll was loaded before we could install the DLL blocklist.
|
||||
type: boolean
|
||||
ping: true
|
||||
|
||||
useragent_locale:
|
||||
description: >
|
||||
User-agent locale.
|
||||
type: string
|
||||
|
||||
Vendor:
|
||||
description: >
|
||||
Application vendor (e.g. Mozilla).
|
||||
type: string
|
||||
|
||||
Version:
|
||||
description: >
|
||||
Product version.
|
||||
type: string
|
||||
|
||||
Winsock_LSP:
|
||||
description: >
|
||||
Information on winsock LSPs injected in our networking stack.
|
||||
type: string
|
|
@ -8,6 +8,7 @@ if CONFIG['OS_TARGET'] != 'Android':
|
|||
Program('crashreporter')
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'../CrashAnnotations.cpp',
|
||||
'crashreporter.cpp',
|
||||
'ping.cpp',
|
||||
]
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "json/json.h"
|
||||
|
||||
#include "CrashAnnotations.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace CrashReporter {
|
||||
|
@ -120,45 +122,15 @@ const int kTelemetryVersion = 4;
|
|||
static Json::Value
|
||||
CreateMetadataNode(StringTable& strings)
|
||||
{
|
||||
// The following list should be kept in sync with the one in CrashManager.jsm
|
||||
const char *entries[] = {
|
||||
"AsyncShutdownTimeout",
|
||||
"AvailablePageFile",
|
||||
"AvailablePhysicalMemory",
|
||||
"AvailableVirtualMemory",
|
||||
"BlockedDllList",
|
||||
"BlocklistInitFailed",
|
||||
"BuildID",
|
||||
"ContainsMemoryReport",
|
||||
"CrashTime",
|
||||
"EventLoopNestingLevel",
|
||||
"ipc_channel_error",
|
||||
"IsGarbageCollecting",
|
||||
"LowCommitSpaceEvents",
|
||||
"MozCrashReason",
|
||||
"OOMAllocationSize",
|
||||
"ProductID",
|
||||
"ProductName",
|
||||
"ReleaseChannel",
|
||||
"RemoteType",
|
||||
"SecondsSinceLastCrash",
|
||||
"ShutdownProgress",
|
||||
"StartupCrash",
|
||||
"SystemMemoryUsePercentage",
|
||||
"TextureUsage",
|
||||
"TotalPageFile",
|
||||
"TotalPhysicalMemory",
|
||||
"TotalVirtualMemory",
|
||||
"UptimeTS",
|
||||
"User32BeforeBlocklist",
|
||||
"Version",
|
||||
};
|
||||
|
||||
Json::Value node;
|
||||
|
||||
for (auto entry : entries) {
|
||||
if ((strings.find(entry) != strings.end()) && !strings[entry].empty()) {
|
||||
node[entry] = strings[entry];
|
||||
for (auto line : strings) {
|
||||
Annotation annotation;
|
||||
|
||||
if (AnnotationFromString(annotation, line.first.c_str())) {
|
||||
if (IsAnnotationWhitelistedForPing(annotation)) {
|
||||
node[line.first] = line.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# 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/.
|
||||
|
||||
import string
|
||||
import sys
|
||||
import textwrap
|
||||
import yaml
|
||||
|
||||
###############################################################################
|
||||
# Language-agnostic functionality #
|
||||
###############################################################################
|
||||
|
||||
template_header = "/* This file was autogenerated by " \
|
||||
"toolkit/crashreporter/generate_crash_reporter_sources.py. DO NOT EDIT */\n\n"
|
||||
|
||||
|
||||
def validate_annotations(annotations):
|
||||
""" Ensure that the annotations have all the required fields """
|
||||
|
||||
for (name, data) in sorted(annotations.items()):
|
||||
if "description" not in data:
|
||||
print("Annotation " + name + " does not have a description\n")
|
||||
sys.exit(1)
|
||||
if "type" not in data:
|
||||
print("Annotation " + name + " does not have a type\n")
|
||||
sys.exit(1)
|
||||
else:
|
||||
annotation_type = data.get("type")
|
||||
valid_types = ["boolean", "integer", "string"]
|
||||
if not any(annotation_type == t for t in valid_types):
|
||||
print("Annotation " + name + " has an unknown type: " + annotation_type + "\n")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def read_annotations(annotations_filename):
|
||||
"""Read the annotations from a YAML file.
|
||||
If an error is encountered quit the program."""
|
||||
|
||||
try:
|
||||
with open(annotations_filename, "r") as annotations_file:
|
||||
annotations = yaml.safe_load(annotations_file)
|
||||
except (IOError, ValueError) as e:
|
||||
print("Error parsing " + annotations_filename + ":\n" + str(e) + "\n")
|
||||
sys.exit(1)
|
||||
|
||||
validate_annotations(annotations)
|
||||
|
||||
return annotations
|
||||
|
||||
|
||||
def read_template(template_filename):
|
||||
"""Read the contents of the template.
|
||||
If an error is encountered quit the program."""
|
||||
|
||||
try:
|
||||
with open(template_filename, "r") as template_file:
|
||||
template = template_file.read()
|
||||
except IOError as ex:
|
||||
print("Error when reading " + template_filename + ":\n" + str(ex) + "\n")
|
||||
sys.exit(1)
|
||||
|
||||
return template
|
||||
|
||||
|
||||
def extract_crash_ping_whitelist(annotations):
|
||||
"""Extract an array holding the names of the annotations whitelisted for
|
||||
inclusion in the crash ping."""
|
||||
|
||||
return [name
|
||||
for (name, data)
|
||||
in sorted(annotations.items())
|
||||
if data.get("ping", False)]
|
||||
|
||||
|
||||
def extract_content_process_blacklist(annotations):
|
||||
"""Extract an array holding the names of the annotations blacklisted when
|
||||
read from a content process."""
|
||||
|
||||
return [name
|
||||
for (name, data)
|
||||
in sorted(annotations.items())
|
||||
if not data.get("content", True)]
|
||||
|
||||
###############################################################################
|
||||
# C++ code generation #
|
||||
###############################################################################
|
||||
|
||||
|
||||
def generate_strings(annotations):
|
||||
"""Generate strings corresponding to every annotation."""
|
||||
|
||||
names = [" \"" + data.get("altname", name) + "\""
|
||||
for (name, data)
|
||||
in sorted(annotations.items())]
|
||||
|
||||
return ",\n".join(names)
|
||||
|
||||
|
||||
def generate_enum(annotations):
|
||||
"""Generate the C++ typed enum holding all the annotations and return it
|
||||
as a string."""
|
||||
|
||||
enum = ""
|
||||
|
||||
for i, (name, _) in enumerate(sorted(annotations.items())):
|
||||
enum += " " + name + " = " + str(i) + ",\n"
|
||||
|
||||
enum += " Count = " + str(len(annotations))
|
||||
|
||||
return enum
|
||||
|
||||
|
||||
def generate_array_initializer(contents):
|
||||
"""Generates the initializer for a C++ array of annotations."""
|
||||
|
||||
initializer = [" Annotation::" + name for name in contents]
|
||||
|
||||
return ",\n".join(initializer)
|
||||
|
||||
|
||||
def generate_header(template, annotations):
|
||||
"""Generate a header by filling the template with the the list of
|
||||
annotations and return it as a string."""
|
||||
|
||||
whitelist = extract_crash_ping_whitelist(annotations)
|
||||
blacklist = extract_content_process_blacklist(annotations)
|
||||
|
||||
return template_header + string.Template(template).substitute({
|
||||
"enum": generate_enum(annotations),
|
||||
"strings": generate_strings(annotations),
|
||||
"whitelist": generate_array_initializer(whitelist),
|
||||
"blacklist": generate_array_initializer(blacklist),
|
||||
})
|
||||
|
||||
|
||||
def emit_header(output, template_filename, annotations_filename):
|
||||
"""Generate the C++ header from the template and write it out."""
|
||||
|
||||
annotations = read_annotations(annotations_filename)
|
||||
template = read_template(template_filename)
|
||||
generated_header = generate_header(template, annotations)
|
||||
|
||||
try:
|
||||
output.write(generated_header)
|
||||
except IOError as ex:
|
||||
print("Error while writing out the generated file:\n" + str(ex) + "\n")
|
||||
sys.exit(1)
|
||||
|
||||
###############################################################################
|
||||
# Java code generation #
|
||||
###############################################################################
|
||||
|
||||
|
||||
def generate_java_array_initializer(contents):
|
||||
"""Generates the initializer for an array of strings.
|
||||
Effectively turns `["a", "b"]` into ' \"a\",\n \"b\"\n'."""
|
||||
|
||||
initializer = ""
|
||||
|
||||
for name in contents:
|
||||
initializer += " \"" + name + "\",\n"
|
||||
|
||||
return initializer.strip(",\n")
|
||||
|
||||
|
||||
def generate_class(template, annotations):
|
||||
"""Fill the class template from the list of annotations."""
|
||||
|
||||
whitelist = extract_crash_ping_whitelist(annotations)
|
||||
|
||||
return template_header + string.Template(template).substitute({
|
||||
"whitelist": generate_java_array_initializer(whitelist),
|
||||
})
|
||||
|
||||
|
||||
def emit_class(output, annotations_filename):
|
||||
"""Generate the CrashReporterConstants.java file."""
|
||||
|
||||
template = textwrap.dedent("""\
|
||||
package org.mozilla.gecko;
|
||||
|
||||
/**
|
||||
* Constants used by the crash reporter. These are generated so that they
|
||||
* are kept in sync with the other C++ and JS users.
|
||||
*/
|
||||
public class CrashReporterConstants {
|
||||
public static final String[] ANNOTATION_WHITELIST = {
|
||||
${whitelist}
|
||||
};
|
||||
}""")
|
||||
|
||||
annotations = read_annotations(annotations_filename)
|
||||
generated_class = generate_class(template, annotations)
|
||||
|
||||
try:
|
||||
output.write(generated_class)
|
||||
except IOError as ex:
|
||||
print("Error while writing out the generated file:\n" + str(ex) + "\n")
|
||||
sys.exit(1)
|
|
@ -9,13 +9,19 @@ SPHINX_TREES['crashreporter'] = 'docs'
|
|||
with Files('docs/**'):
|
||||
SCHEDULES.exclusive = ['docs']
|
||||
|
||||
GENERATED_FILES += [
|
||||
'CrashAnnotations.h',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'!CrashAnnotations.h',
|
||||
'nsExceptionHandler.h',
|
||||
]
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
||||
UNIFIED_SOURCES = [
|
||||
'CrashAnnotations.cpp',
|
||||
'nsExceptionHandlerUtils.cpp',
|
||||
]
|
||||
|
||||
|
@ -125,6 +131,13 @@ else:
|
|||
'nsDummyExceptionHandler.cpp',
|
||||
]
|
||||
|
||||
# Generate CrashAnnotations.h
|
||||
crash_annotations = GENERATED_FILES['CrashAnnotations.h']
|
||||
crash_annotations.script = 'generate_crash_reporter_sources.py:emit_header'
|
||||
crash_annotations.inputs = [
|
||||
'CrashAnnotations.h.in',
|
||||
'CrashAnnotations.yaml',
|
||||
]
|
||||
|
||||
with Files('**'):
|
||||
BUG_COMPONENT = ('Toolkit', 'Crash Reporting')
|
||||
|
|
|
@ -66,14 +66,31 @@ UnsetExceptionHandler()
|
|||
}
|
||||
|
||||
nsresult
|
||||
AnnotateCrashReport(const nsACString& key,
|
||||
const nsACString& data)
|
||||
AnnotateCrashReport(Annotation key, bool data)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
RemoveCrashReportAnnotation(const nsACString& key)
|
||||
AnnotateCrashReport(Annotation key, int data)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
AnnotateCrashReport(Annotation key, unsigned int data)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
AnnotateCrashReport(Annotation key, const nsACString& data)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
RemoveCrashReportAnnotation(Annotation key)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "nsDirectoryService.h"
|
||||
#include "nsDataHashtable.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/EnumeratedRange.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "mozilla/Unused.h"
|
||||
|
@ -233,7 +234,7 @@ static const char* androidCrashReporterJobId = nullptr;
|
|||
// this holds additional data sent via the API
|
||||
static Mutex* crashReporterAPILock;
|
||||
static Mutex* notesFieldLock;
|
||||
static AnnotationTable* crashReporterAPIData_Hash;
|
||||
static AnnotationTable crashReporterAPIData_Table;
|
||||
static nsCString* crashReporterAPIData = nullptr;
|
||||
static nsCString* crashEventAPIData = nullptr;
|
||||
static nsCString* notesField = nullptr;
|
||||
|
@ -324,15 +325,6 @@ private:
|
|||
};
|
||||
#endif // MOZ_CRASHREPORTER_INJECTOR
|
||||
|
||||
// Crashreporter annotations that we don't send along in subprocess reports.
|
||||
static const char* kSubprocessBlacklist[] = {
|
||||
"FramePoisonBase",
|
||||
"FramePoisonSize",
|
||||
"StartupCrash",
|
||||
"StartupTime",
|
||||
"URL"
|
||||
};
|
||||
|
||||
// If annotations are attempted before the crash reporter is enabled,
|
||||
// they queue up here.
|
||||
class DelayedNote;
|
||||
|
@ -679,13 +671,16 @@ WriteString(PlatformWriter& pw, const char* str) {
|
|||
pw.WriteBuffer(str, len);
|
||||
}
|
||||
|
||||
template<int N>
|
||||
static void
|
||||
WriteAnnotation(PlatformWriter& pw, const char (&name)[N],
|
||||
const char* value) {
|
||||
WriteLiteral(pw, name);
|
||||
WriteAnnotation(PlatformWriter& pw, const Annotation name,
|
||||
const char* value, size_t len = 0) {
|
||||
WriteString(pw, AnnotationToString(name));
|
||||
WriteLiteral(pw, "=");
|
||||
WriteString(pw, value);
|
||||
if (len == 0) {
|
||||
WriteString(pw, value);
|
||||
} else {
|
||||
pw.WriteBuffer(value, len);
|
||||
}
|
||||
WriteLiteral(pw, "\n");
|
||||
};
|
||||
|
||||
|
@ -737,13 +732,18 @@ WriteGlobalMemoryStatus(PlatformWriter* apiData, PlatformWriter* eventFile)
|
|||
WriteAnnotation(*eventFile, name, buffer); \
|
||||
}
|
||||
|
||||
WRITE_STATEX_FIELD(dwMemoryLoad, "SystemMemoryUsePercentage", ltoa);
|
||||
WRITE_STATEX_FIELD(ullTotalVirtual, "TotalVirtualMemory", _ui64toa);
|
||||
WRITE_STATEX_FIELD(ullAvailVirtual, "AvailableVirtualMemory", _ui64toa);
|
||||
WRITE_STATEX_FIELD(ullTotalPageFile, "TotalPageFile", _ui64toa);
|
||||
WRITE_STATEX_FIELD(ullAvailPageFile, "AvailablePageFile", _ui64toa);
|
||||
WRITE_STATEX_FIELD(ullTotalPhys, "TotalPhysicalMemory", _ui64toa);
|
||||
WRITE_STATEX_FIELD(ullAvailPhys, "AvailablePhysicalMemory", _ui64toa);
|
||||
WRITE_STATEX_FIELD(dwMemoryLoad, Annotation::SystemMemoryUsePercentage,
|
||||
ltoa);
|
||||
WRITE_STATEX_FIELD(ullTotalVirtual, Annotation::TotalVirtualMemory,
|
||||
_ui64toa);
|
||||
WRITE_STATEX_FIELD(ullAvailVirtual, Annotation::AvailableVirtualMemory,
|
||||
_ui64toa);
|
||||
WRITE_STATEX_FIELD(ullTotalPageFile, Annotation::TotalPageFile, _ui64toa);
|
||||
WRITE_STATEX_FIELD(ullAvailPageFile, Annotation::AvailablePageFile,
|
||||
_ui64toa);
|
||||
WRITE_STATEX_FIELD(ullTotalPhys, Annotation::TotalPhysicalMemory, _ui64toa);
|
||||
WRITE_STATEX_FIELD(ullAvailPhys, Annotation::AvailablePhysicalMemory,
|
||||
_ui64toa);
|
||||
|
||||
#undef WRITE_STATEX_FIELD
|
||||
}
|
||||
|
@ -1035,41 +1035,43 @@ MinidumpCallback(
|
|||
}
|
||||
|
||||
if (currentSessionId) {
|
||||
WriteAnnotation(apiData, "TelemetrySessionId", currentSessionId);
|
||||
WriteAnnotation(eventFile, "TelemetrySessionId", currentSessionId);
|
||||
WriteAnnotation(apiData, Annotation::TelemetrySessionId,
|
||||
currentSessionId);
|
||||
WriteAnnotation(eventFile, Annotation::TelemetrySessionId,
|
||||
currentSessionId);
|
||||
}
|
||||
|
||||
WriteAnnotation(apiData, "CrashTime", crashTimeString);
|
||||
WriteAnnotation(eventFile, "CrashTime", crashTimeString);
|
||||
WriteAnnotation(apiData, Annotation::CrashTime, crashTimeString);
|
||||
WriteAnnotation(eventFile, Annotation::CrashTime, crashTimeString);
|
||||
|
||||
WriteAnnotation(apiData, "UptimeTS", uptimeTSString);
|
||||
WriteAnnotation(eventFile, "UptimeTS", uptimeTSString);
|
||||
WriteAnnotation(apiData, Annotation::UptimeTS, uptimeTSString);
|
||||
WriteAnnotation(eventFile, Annotation::UptimeTS, uptimeTSString);
|
||||
|
||||
if (timeSinceLastCrash != 0) {
|
||||
WriteAnnotation(apiData, "SecondsSinceLastCrash",
|
||||
WriteAnnotation(apiData, Annotation::SecondsSinceLastCrash,
|
||||
timeSinceLastCrashString);
|
||||
WriteAnnotation(eventFile, "SecondsSinceLastCrash",
|
||||
WriteAnnotation(eventFile, Annotation::SecondsSinceLastCrash,
|
||||
timeSinceLastCrashString);
|
||||
}
|
||||
if (isGarbageCollecting) {
|
||||
WriteAnnotation(apiData, "IsGarbageCollecting", "1");
|
||||
WriteAnnotation(eventFile, "IsGarbageCollecting", "1");
|
||||
WriteAnnotation(apiData, Annotation::IsGarbageCollecting, "1");
|
||||
WriteAnnotation(eventFile, Annotation::IsGarbageCollecting, "1");
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
|
||||
if (eventloopNestingLevel > 0) {
|
||||
XP_STOA(eventloopNestingLevel, buffer, 10);
|
||||
WriteAnnotation(apiData, "EventLoopNestingLevel", buffer);
|
||||
WriteAnnotation(eventFile, "EventLoopNestingLevel", buffer);
|
||||
WriteAnnotation(apiData, Annotation::EventLoopNestingLevel, buffer);
|
||||
WriteAnnotation(eventFile, Annotation::EventLoopNestingLevel, buffer);
|
||||
}
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (gBreakpadReservedVM) {
|
||||
_ui64toa(uintptr_t(gBreakpadReservedVM), buffer, 10);
|
||||
WriteAnnotation(apiData, "BreakpadReserveAddress", buffer);
|
||||
WriteAnnotation(apiData, Annotation::BreakpadReserveAddress, buffer);
|
||||
_ui64toa(kReserveSize, buffer, 10);
|
||||
WriteAnnotation(apiData, "BreakpadReserveSize", buffer);
|
||||
WriteAnnotation(apiData, Annotation::BreakpadReserveSize, buffer);
|
||||
}
|
||||
|
||||
#ifdef HAS_DLL_BLOCKLIST
|
||||
|
@ -1085,41 +1087,37 @@ MinidumpCallback(
|
|||
size_t rust_panic_len;
|
||||
if (get_rust_panic_reason(&rust_panic_reason, &rust_panic_len)) {
|
||||
// rust_panic_reason is not null-terminated.
|
||||
WriteLiteral(apiData, "MozCrashReason=");
|
||||
apiData.WriteBuffer(rust_panic_reason, rust_panic_len);
|
||||
WriteLiteral(apiData, "\n");
|
||||
WriteLiteral(eventFile, "MozCrashReason=");
|
||||
eventFile.WriteBuffer(rust_panic_reason, rust_panic_len);
|
||||
WriteLiteral(eventFile, "\n");
|
||||
WriteAnnotation(apiData, Annotation::MozCrashReason, rust_panic_reason,
|
||||
rust_panic_len);
|
||||
WriteAnnotation(eventFile, Annotation::MozCrashReason, rust_panic_reason,
|
||||
rust_panic_len);
|
||||
} else if (gMozCrashReason) {
|
||||
WriteAnnotation(apiData, "MozCrashReason", gMozCrashReason);
|
||||
WriteAnnotation(eventFile, "MozCrashReason", gMozCrashReason);
|
||||
WriteAnnotation(apiData, Annotation::MozCrashReason, gMozCrashReason);
|
||||
WriteAnnotation(eventFile, Annotation::MozCrashReason, gMozCrashReason);
|
||||
}
|
||||
|
||||
if (oomAllocationSizeBuffer[0]) {
|
||||
WriteAnnotation(apiData, "OOMAllocationSize", oomAllocationSizeBuffer);
|
||||
WriteAnnotation(eventFile, "OOMAllocationSize", oomAllocationSizeBuffer);
|
||||
WriteAnnotation(apiData, Annotation::OOMAllocationSize,
|
||||
oomAllocationSizeBuffer);
|
||||
WriteAnnotation(eventFile, Annotation::OOMAllocationSize,
|
||||
oomAllocationSizeBuffer);
|
||||
}
|
||||
|
||||
if (texturesSizeBuffer[0]) {
|
||||
WriteAnnotation(apiData, "TextureUsage", texturesSizeBuffer);
|
||||
WriteAnnotation(eventFile, "TextureUsage", texturesSizeBuffer);
|
||||
WriteAnnotation(apiData, Annotation::TextureUsage, texturesSizeBuffer);
|
||||
WriteAnnotation(eventFile, Annotation::TextureUsage, texturesSizeBuffer);
|
||||
}
|
||||
|
||||
if (memoryReportPath) {
|
||||
WriteLiteral(apiData, "ContainsMemoryReport=1\n");
|
||||
WriteLiteral(eventFile, "ContainsMemoryReport=1\n");
|
||||
WriteAnnotation(apiData, Annotation::ContainsMemoryReport, "1");
|
||||
WriteAnnotation(eventFile, Annotation::ContainsMemoryReport, "1");
|
||||
}
|
||||
|
||||
std::function<void(const char*)> getThreadAnnotationCB =
|
||||
[&] (const char * aAnnotation) -> void {
|
||||
if (aAnnotation) {
|
||||
WriteLiteral(apiData, "ThreadIdNameMapping=");
|
||||
WriteLiteral(eventFile, "ThreadIdNameMapping=");
|
||||
WriteString(apiData, aAnnotation);
|
||||
WriteString(eventFile, aAnnotation);
|
||||
WriteLiteral(apiData, "\n");
|
||||
WriteLiteral(eventFile, "\n");
|
||||
[&] (const char* aValue) -> void {
|
||||
if (aValue) {
|
||||
WriteAnnotation(apiData, Annotation::ThreadIdNameMapping, aValue);
|
||||
WriteAnnotation(eventFile, Annotation::ThreadIdNameMapping, aValue);
|
||||
}
|
||||
};
|
||||
GetFlatThreadAnnotation(getThreadAnnotationCB, false);
|
||||
|
@ -1286,26 +1284,24 @@ PrepareChildExceptionTimeAnnotations(void* context)
|
|||
}
|
||||
|
||||
if (oomAllocationSizeBuffer[0]) {
|
||||
WriteAnnotation(apiData, "OOMAllocationSize", oomAllocationSizeBuffer);
|
||||
WriteAnnotation(apiData, Annotation::OOMAllocationSize,
|
||||
oomAllocationSizeBuffer);
|
||||
}
|
||||
|
||||
char* rust_panic_reason;
|
||||
size_t rust_panic_len;
|
||||
if (get_rust_panic_reason(&rust_panic_reason, &rust_panic_len)) {
|
||||
// rust_panic_reason is not null-terminated.
|
||||
WriteLiteral(apiData, "MozCrashReason=");
|
||||
apiData.WriteBuffer(rust_panic_reason, rust_panic_len);
|
||||
WriteLiteral(apiData, "\n");
|
||||
WriteAnnotation(apiData, Annotation::MozCrashReason, rust_panic_reason,
|
||||
rust_panic_len);
|
||||
} else if (gMozCrashReason) {
|
||||
WriteAnnotation(apiData, "MozCrashReason", gMozCrashReason);
|
||||
WriteAnnotation(apiData, Annotation::MozCrashReason, gMozCrashReason);
|
||||
}
|
||||
|
||||
std::function<void(const char*)> getThreadAnnotationCB =
|
||||
[&] (const char * aAnnotation) -> void {
|
||||
if (aAnnotation) {
|
||||
WriteLiteral(apiData, "ThreadIdNameMapping=");
|
||||
WriteString(apiData, aAnnotation);
|
||||
WriteLiteral(apiData, "\n");
|
||||
[&] (const char * aValue) -> void {
|
||||
if (aValue) {
|
||||
WriteAnnotation(apiData, Annotation::ThreadIdNameMapping, aValue);
|
||||
}
|
||||
};
|
||||
GetFlatThreadAnnotation(getThreadAnnotationCB, true);
|
||||
|
@ -1508,10 +1504,6 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
|||
NS_ASSERTION(!notesFieldLock, "Shouldn't have a lock yet");
|
||||
notesFieldLock = new Mutex("notesFieldLock");
|
||||
|
||||
crashReporterAPIData_Hash =
|
||||
new nsDataHashtable<nsCStringHashKey,nsCString>();
|
||||
NS_ENSURE_TRUE(crashReporterAPIData_Hash, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
notesField = new nsCString();
|
||||
NS_ENSURE_TRUE(notesField, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
|
@ -1678,8 +1670,7 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
|
|||
char timeString[32];
|
||||
time_t startupTime = time(nullptr);
|
||||
XP_TTOA(startupTime, timeString, 10);
|
||||
AnnotateCrashReport(NS_LITERAL_CSTRING("StartupTime"),
|
||||
nsDependentCString(timeString));
|
||||
AnnotateCrashReport(Annotation::StartupTime, nsDependentCString(timeString));
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
// On OS X, many testers like to see the OS crash reporting dialog
|
||||
|
@ -1933,7 +1924,7 @@ nsresult SetupExtraData(nsIFile* aAppDataDirectory, const nsACString& aBuildID)
|
|||
if(NS_SUCCEEDED(GetOrInit(dataDirectory,
|
||||
NS_LITERAL_CSTRING("InstallTime") + aBuildID,
|
||||
data, InitInstallTime)))
|
||||
AnnotateCrashReport(NS_LITERAL_CSTRING("InstallTime"), data);
|
||||
AnnotateCrashReport(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
|
||||
|
@ -1991,8 +1982,9 @@ nsresult UnsetExceptionHandler()
|
|||
|
||||
// do this here in the unlikely case that we succeeded in allocating
|
||||
// our strings but failed to allocate gExceptionHandler.
|
||||
delete crashReporterAPIData_Hash;
|
||||
crashReporterAPIData_Hash = nullptr;
|
||||
std::fill(crashReporterAPIData_Table.begin(),
|
||||
crashReporterAPIData_Table.end(),
|
||||
EmptyCString());
|
||||
|
||||
delete crashReporterAPILock;
|
||||
crashReporterAPILock = nullptr;
|
||||
|
@ -2079,12 +2071,8 @@ static void ReplaceChar(nsCString& str, const nsACString& character,
|
|||
}
|
||||
|
||||
static nsresult
|
||||
EscapeAnnotation(const nsACString& key, const nsACString& data, nsCString& escapedData)
|
||||
EscapeAnnotation(const nsACString& data, nsCString& escapedData)
|
||||
{
|
||||
if (FindInReadable(NS_LITERAL_CSTRING("="), key) ||
|
||||
FindInReadable(NS_LITERAL_CSTRING("\n"), key))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
if (FindInReadable(NS_LITERAL_CSTRING("\0"), data))
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
|
@ -2102,15 +2090,15 @@ EscapeAnnotation(const nsACString& key, const nsACString& data, nsCString& escap
|
|||
class DelayedNote
|
||||
{
|
||||
public:
|
||||
DelayedNote(const nsACString& aKey, const nsACString& aData)
|
||||
: mKey(aKey), mData(aData), mType(Annotation) {}
|
||||
DelayedNote(Annotation aKey, const nsACString& aData)
|
||||
: mKey(aKey), mData(aData), mType(CrashAnnotation) {}
|
||||
|
||||
explicit DelayedNote(const nsACString& aData)
|
||||
: mData(aData), mType(AppNote) {}
|
||||
|
||||
void Run()
|
||||
{
|
||||
if (mType == Annotation) {
|
||||
if (mType == CrashAnnotation) {
|
||||
AnnotateCrashReport(mKey, mData);
|
||||
} else {
|
||||
AppendAppNotesToCrashReport(mData);
|
||||
|
@ -2118,9 +2106,9 @@ class DelayedNote
|
|||
}
|
||||
|
||||
private:
|
||||
nsCString mKey;
|
||||
Annotation mKey;
|
||||
nsCString mData;
|
||||
enum AnnotationType { Annotation, AppNote } mType;
|
||||
enum AnnotationType { CrashAnnotation, AppNote } mType;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -2144,20 +2132,42 @@ RunAndCleanUpDelayedNotes()
|
|||
}
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data)
|
||||
nsresult AnnotateCrashReport(Annotation key, bool data)
|
||||
{
|
||||
return AnnotateCrashReport(key, data ? NS_LITERAL_CSTRING("1")
|
||||
: NS_LITERAL_CSTRING("0"));
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, int data)
|
||||
{
|
||||
nsAutoCString dataString;
|
||||
dataString.AppendInt(data);
|
||||
|
||||
return AnnotateCrashReport(key, dataString);
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, unsigned int data)
|
||||
{
|
||||
nsAutoCString dataString;
|
||||
dataString.AppendInt(data);
|
||||
|
||||
return AnnotateCrashReport(key, dataString);
|
||||
}
|
||||
|
||||
nsresult AnnotateCrashReport(Annotation key, const nsACString& data)
|
||||
{
|
||||
if (!GetEnabled())
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
||||
nsCString escapedData;
|
||||
nsresult rv = EscapeAnnotation(key, data, escapedData);
|
||||
nsresult rv = EscapeAnnotation(data, escapedData);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (!XRE_IsParentProcess()) {
|
||||
// The newer CrashReporterClient can be used from any thread.
|
||||
if (RefPtr<CrashReporterClient> client = CrashReporterClient::GetSingleton()) {
|
||||
client->AnnotateCrashReport(nsCString(key), escapedData);
|
||||
client->AnnotateCrashReport(key, escapedData);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2170,18 +2180,18 @@ nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data)
|
|||
|
||||
MutexAutoLock lock(*crashReporterAPILock);
|
||||
|
||||
crashReporterAPIData_Hash->Put(key, escapedData);
|
||||
crashReporterAPIData_Table[key] = escapedData;
|
||||
|
||||
// now rebuild the file contents
|
||||
crashReporterAPIData->Truncate(0);
|
||||
crashEventAPIData->Truncate(0);
|
||||
for (auto it = crashReporterAPIData_Hash->Iter(); !it.Done(); it.Next()) {
|
||||
const nsACString& key = it.Key();
|
||||
nsCString entry = it.Data();
|
||||
for (auto key : MakeEnumeratedRange(Annotation::Count)) {
|
||||
nsDependentCString str(AnnotationToString(key));
|
||||
nsCString entry = crashReporterAPIData_Table[key];
|
||||
if (!entry.IsEmpty()) {
|
||||
NS_NAMED_LITERAL_CSTRING(kEquals, "=");
|
||||
NS_NAMED_LITERAL_CSTRING(kNewline, "\n");
|
||||
nsAutoCString line = key + kEquals + entry + kNewline;
|
||||
nsAutoCString line = str + kEquals + entry + kNewline;
|
||||
|
||||
crashReporterAPIData->Append(line);
|
||||
crashEventAPIData->Append(line);
|
||||
|
@ -2191,9 +2201,9 @@ nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult RemoveCrashReportAnnotation(const nsACString& key)
|
||||
nsresult RemoveCrashReportAnnotation(Annotation key)
|
||||
{
|
||||
return AnnotateCrashReport(key, NS_LITERAL_CSTRING(""));
|
||||
return AnnotateCrashReport(key, EmptyCString());
|
||||
}
|
||||
|
||||
nsresult SetGarbageCollecting(bool collecting)
|
||||
|
@ -2230,7 +2240,7 @@ nsresult AppendAppNotesToCrashReport(const nsACString& data)
|
|||
// we must ensure that the data is escaped and valid before the parent
|
||||
// sees it.
|
||||
nsCString escapedData;
|
||||
nsresult rv = EscapeAnnotation(NS_LITERAL_CSTRING("Notes"), data, escapedData);
|
||||
nsresult rv = EscapeAnnotation(data, escapedData);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
|
@ -2249,20 +2259,21 @@ nsresult AppendAppNotesToCrashReport(const nsACString& data)
|
|||
MutexAutoLock lock(*notesFieldLock);
|
||||
|
||||
notesField->Append(data);
|
||||
return AnnotateCrashReport(NS_LITERAL_CSTRING("Notes"), *notesField);
|
||||
return AnnotateCrashReport(Annotation::Notes, *notesField);
|
||||
}
|
||||
|
||||
// Returns true if found, false if not found.
|
||||
static bool
|
||||
GetAnnotation(const nsACString& key, nsACString& data)
|
||||
GetAnnotation(CrashReporter::Annotation key, nsACString& data)
|
||||
{
|
||||
if (!gExceptionHandler)
|
||||
return false;
|
||||
|
||||
MutexAutoLock lock(*crashReporterAPILock);
|
||||
nsAutoCString entry;
|
||||
if (!crashReporterAPIData_Hash->Get(key, &entry))
|
||||
nsCString entry = crashReporterAPIData_Table[key];
|
||||
if (entry.IsEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data = entry;
|
||||
return true;
|
||||
|
@ -2310,15 +2321,14 @@ bool GetServerURL(nsACString& aServerURL)
|
|||
if (!gExceptionHandler)
|
||||
return false;
|
||||
|
||||
return GetAnnotation(NS_LITERAL_CSTRING("ServerURL"), aServerURL);
|
||||
return GetAnnotation(CrashReporter::Annotation::ServerURL, aServerURL);
|
||||
}
|
||||
|
||||
nsresult SetServerURL(const nsACString& aServerURL)
|
||||
{
|
||||
// store server URL with the API data
|
||||
// the client knows to handle this specially
|
||||
return AnnotateCrashReport(NS_LITERAL_CSTRING("ServerURL"),
|
||||
aServerURL);
|
||||
return AnnotateCrashReport(Annotation::ServerURL, aServerURL);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -2941,25 +2951,11 @@ AppendExtraData(const nsAString& id, const AnnotationTable& data)
|
|||
//-----------------------------------------------------------------------------
|
||||
// Helpers for AppendExtraData()
|
||||
//
|
||||
struct Blacklist {
|
||||
Blacklist() : mItems(nullptr), mLen(0) { }
|
||||
Blacklist(const char** items, int len) : mItems(items), mLen(len) { }
|
||||
|
||||
bool Contains(const nsACString& key) const {
|
||||
for (int i = 0; i < mLen; ++i)
|
||||
if (key.EqualsASCII(mItems[i]))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char** mItems;
|
||||
const int mLen;
|
||||
};
|
||||
|
||||
static void
|
||||
WriteAnnotation(PRFileDesc* fd, const nsACString& key, const nsACString& value)
|
||||
WriteAnnotation(PRFileDesc* fd, const Annotation key, const nsACString& value)
|
||||
{
|
||||
PR_Write(fd, key.BeginReading(), key.Length());
|
||||
const char* annotation = AnnotationToString(key);
|
||||
PR_Write(fd, annotation, strlen(annotation));
|
||||
PR_Write(fd, "=", 1);
|
||||
PR_Write(fd, value.BeginReading(), value.Length());
|
||||
PR_Write(fd, "\n", 1);
|
||||
|
@ -2979,9 +2975,9 @@ WriteLiteral(PRFileDesc* fd, const char (&str)[N])
|
|||
static bool
|
||||
WriteExtraData(nsIFile* extraFile,
|
||||
const AnnotationTable& data,
|
||||
const Blacklist& blacklist,
|
||||
bool writeCrashTime=false,
|
||||
bool truncate=false)
|
||||
bool truncate=false,
|
||||
bool content=false)
|
||||
{
|
||||
PRFileDesc* fd;
|
||||
int truncOrAppend = truncate ? PR_TRUNCATE : PR_APPEND;
|
||||
|
@ -2991,13 +2987,14 @@ WriteExtraData(nsIFile* extraFile,
|
|||
if (NS_FAILED(rv))
|
||||
return false;
|
||||
|
||||
for (auto iter = data.ConstIter(); !iter.Done(); iter.Next()) {
|
||||
// Skip entries in the blacklist.
|
||||
const nsACString& key = iter.Key();
|
||||
if (blacklist.Contains(key)) {
|
||||
continue;
|
||||
for (auto key : MakeEnumeratedRange(Annotation::Count)) {
|
||||
nsCString value = data[key];
|
||||
// Skip entries in the blacklist and empty entries.
|
||||
if ((content && IsAnnotationBlacklistedForContent(key)) ||
|
||||
value.IsEmpty()) {
|
||||
continue;
|
||||
}
|
||||
WriteAnnotation(fd, key, iter.Data());
|
||||
WriteAnnotation(fd, key, value);
|
||||
}
|
||||
|
||||
if (writeCrashTime) {
|
||||
|
@ -3006,7 +3003,7 @@ WriteExtraData(nsIFile* extraFile,
|
|||
XP_TTOA(crashTime, crashTimeString, 10);
|
||||
|
||||
WriteAnnotation(fd,
|
||||
nsDependentCString("CrashTime"),
|
||||
Annotation::CrashTime,
|
||||
nsDependentCString(crashTimeString));
|
||||
|
||||
double uptimeTS = (TimeStamp::NowLoRes() -
|
||||
|
@ -3015,12 +3012,13 @@ WriteExtraData(nsIFile* extraFile,
|
|||
SimpleNoCLibDtoA(uptimeTS, uptimeTSString, sizeof(uptimeTSString));
|
||||
|
||||
WriteAnnotation(fd,
|
||||
nsDependentCString("UptimeTS"),
|
||||
Annotation::UptimeTS,
|
||||
nsDependentCString(uptimeTSString));
|
||||
}
|
||||
|
||||
if (memoryReportPath) {
|
||||
WriteLiteral(fd, "ContainsMemoryReport=1\n");
|
||||
WriteAnnotation(fd, Annotation::ContainsMemoryReport,
|
||||
NS_LITERAL_CSTRING("1"));
|
||||
}
|
||||
|
||||
PR_Close(fd);
|
||||
|
@ -3030,7 +3028,7 @@ WriteExtraData(nsIFile* extraFile,
|
|||
bool
|
||||
AppendExtraData(nsIFile* extraFile, const AnnotationTable& data)
|
||||
{
|
||||
return WriteExtraData(extraFile, data, Blacklist());
|
||||
return WriteExtraData(extraFile, data);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -3075,24 +3073,32 @@ ReadAndValidateExceptionTimeAnnotations(FILE*& aFd,
|
|||
if (strchr(line, '\n')) {
|
||||
break;
|
||||
}
|
||||
// The annotation sould be known
|
||||
Annotation annotation;
|
||||
if (!AnnotationFromString(annotation, line)) {
|
||||
break;
|
||||
}
|
||||
// Data should have been escaped by the child
|
||||
if (!IsDataEscaped(data)) {
|
||||
break;
|
||||
}
|
||||
// Looks good, save the (line,data) pair
|
||||
aAnnotations.Put(nsDependentCString(line),
|
||||
nsDependentCString(data, dataLen));
|
||||
aAnnotations[annotation] = nsDependentCString(data, dataLen);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes extra data in the .extra file corresponding to the specified
|
||||
* minidump. If `content` is set to true then this assumes that of a child
|
||||
* process.
|
||||
*
|
||||
* NOTE: One side effect of this function is that it deletes the
|
||||
* GeckoChildCrash<pid>.extra file if it exists, once processed.
|
||||
*/
|
||||
static bool
|
||||
WriteExtraForMinidump(nsIFile* minidump,
|
||||
uint32_t pid,
|
||||
const Blacklist& blacklist,
|
||||
bool content,
|
||||
nsIFile** extraFile)
|
||||
{
|
||||
nsCOMPtr<nsIFile> extra;
|
||||
|
@ -3102,10 +3108,10 @@ WriteExtraForMinidump(nsIFile* minidump,
|
|||
|
||||
{
|
||||
MutexAutoLock lock(*crashReporterAPILock);
|
||||
if (!WriteExtraData(extra, *crashReporterAPIData_Hash,
|
||||
blacklist,
|
||||
if (!WriteExtraData(extra, crashReporterAPIData_Table,
|
||||
true /*write crash time*/,
|
||||
true /*truncate*/)) {
|
||||
true /*truncate*/,
|
||||
content)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -3210,11 +3216,10 @@ OnChildProcessDumpRequested(void* aContext,
|
|||
aClientInfo->pid();
|
||||
#endif
|
||||
|
||||
if (!WriteExtraForMinidump(minidump, pid,
|
||||
Blacklist(kSubprocessBlacklist,
|
||||
ArrayLength(kSubprocessBlacklist)),
|
||||
getter_AddRefs(extraFile)))
|
||||
if (!WriteExtraForMinidump(minidump, pid, /* content */ true,
|
||||
getter_AddRefs(extraFile))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ShouldReport()) {
|
||||
nsCOMPtr<nsIFile> memoryReport;
|
||||
|
@ -3737,7 +3742,8 @@ PairedDumpCallbackExtra(
|
|||
nsCOMPtr<nsIFile>& minidump = *static_cast< nsCOMPtr<nsIFile>* >(context);
|
||||
|
||||
nsCOMPtr<nsIFile> extra;
|
||||
return WriteExtraForMinidump(minidump, 0, Blacklist(), getter_AddRefs(extra));
|
||||
return WriteExtraForMinidump(minidump, 0, /* content */ false,
|
||||
getter_AddRefs(extra));
|
||||
}
|
||||
|
||||
ThreadId
|
||||
|
|
|
@ -13,6 +13,9 @@
|
|||
#define nsExceptionHandler_h__
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
|
||||
#include "CrashAnnotations.h"
|
||||
|
||||
#include <functional>
|
||||
#include <stddef.h>
|
||||
|
@ -37,8 +40,6 @@
|
|||
#endif
|
||||
|
||||
class nsIFile;
|
||||
template<class KeyClass, class DataType> class nsDataHashtable;
|
||||
class nsCStringHashKey;
|
||||
|
||||
namespace CrashReporter {
|
||||
|
||||
|
@ -92,8 +93,11 @@ nsresult SetMinidumpPath(const nsAString& aPath);
|
|||
// AnnotateCrashReport, RemoveCrashReportAnnotation and
|
||||
// AppendAppNotesToCrashReport may be called from any thread in a chrome
|
||||
// process, but may only be called from the main thread in a content process.
|
||||
nsresult AnnotateCrashReport(const nsACString& key, const nsACString& data);
|
||||
nsresult RemoveCrashReportAnnotation(const nsACString& key);
|
||||
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 RemoveCrashReportAnnotation(Annotation key);
|
||||
nsresult AppendAppNotesToCrashReport(const nsACString& data);
|
||||
|
||||
void AnnotateOOMAllocationSize(size_t size);
|
||||
|
@ -113,7 +117,8 @@ nsresult UnregisterAppMemory(void* ptr);
|
|||
void SetIncludeContextHeap(bool aValue);
|
||||
|
||||
// Functions for working with minidumps and .extras
|
||||
typedef nsDataHashtable<nsCStringHashKey, nsCString> AnnotationTable;
|
||||
typedef mozilla::EnumeratedArray<Annotation, Annotation::Count, nsCString>
|
||||
AnnotationTable;
|
||||
|
||||
void DeleteMinidumpFilesForID(const nsAString& id);
|
||||
bool GetMinidumpForID(const nsAString& id, nsIFile** minidump);
|
||||
|
|
|
@ -7,12 +7,12 @@ function run_test() {
|
|||
do_crash(
|
||||
function() {
|
||||
crashType = CrashTestUtils.CRASH_MOZ_CRASH;
|
||||
crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
|
||||
crashReporter.annotateCrashReport("TestKey", "Yes");
|
||||
Cu.getJSTestingFunctions().reportLargeAllocationFailure();
|
||||
Cu.forceGC();
|
||||
},
|
||||
function(mdump, extra) {
|
||||
Assert.equal(extra.TestingOOMCrash, "Yes");
|
||||
Assert.equal(extra.TestKey, "Yes");
|
||||
Assert.equal(false, "JSOutOfMemory" in extra);
|
||||
Assert.equal(extra.JSLargeAllocationFailure, "Recovered");
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ function run_test() {
|
|||
do_crash(
|
||||
function() {
|
||||
crashType = CrashTestUtils.CRASH_MOZ_CRASH;
|
||||
crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
|
||||
crashReporter.annotateCrashReport("TestKey", "Yes");
|
||||
|
||||
function crashWhileReporting() {
|
||||
CrashTestUtils.crash(crashType);
|
||||
|
@ -17,7 +17,7 @@ function run_test() {
|
|||
Cu.getJSTestingFunctions().reportLargeAllocationFailure();
|
||||
},
|
||||
function(mdump, extra) {
|
||||
Assert.equal(extra.TestingOOMCrash, "Yes");
|
||||
Assert.equal(extra.TestKey, "Yes");
|
||||
Assert.equal(extra.JSLargeAllocationFailure, "Reporting");
|
||||
},
|
||||
true);
|
||||
|
|
|
@ -7,12 +7,12 @@ function run_test() {
|
|||
do_crash(
|
||||
function() {
|
||||
crashType = CrashTestUtils.CRASH_MOZ_CRASH;
|
||||
crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
|
||||
crashReporter.annotateCrashReport("TestKey", "Yes");
|
||||
Cu.getJSTestingFunctions().reportOutOfMemory();
|
||||
Cu.forceGC();
|
||||
},
|
||||
function(mdump, extra) {
|
||||
Assert.equal(extra.TestingOOMCrash, "Yes");
|
||||
Assert.equal(extra.TestKey, "Yes");
|
||||
Assert.equal(extra.JSOutOfMemory, "Recovered");
|
||||
},
|
||||
true);
|
||||
|
|
|
@ -7,7 +7,7 @@ function run_test() {
|
|||
do_crash(
|
||||
function() {
|
||||
crashType = CrashTestUtils.CRASH_MOZ_CRASH;
|
||||
crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
|
||||
crashReporter.annotateCrashReport("TestKey", "Yes");
|
||||
|
||||
// GC now to avoid having it happen randomly later, which would make the
|
||||
// test bogusly fail. See comment below.
|
||||
|
@ -16,7 +16,7 @@ function run_test() {
|
|||
Cu.getJSTestingFunctions().reportOutOfMemory();
|
||||
},
|
||||
function(mdump, extra) {
|
||||
Assert.equal(extra.TestingOOMCrash, "Yes");
|
||||
Assert.equal(extra.TestKey, "Yes");
|
||||
|
||||
// The JSOutOfMemory field is absent if the JS engine never reported OOM,
|
||||
// "Reported" if it did, and "Recovered" if it reported OOM but
|
||||
|
|
|
@ -7,13 +7,13 @@ function run_test() {
|
|||
do_crash(
|
||||
function() {
|
||||
crashType = CrashTestUtils.CRASH_MOZ_CRASH;
|
||||
crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
|
||||
crashReporter.annotateCrashReport("TestKey", "Yes");
|
||||
Cu.getJSTestingFunctions().reportOutOfMemory();
|
||||
Cu.forceGC(); // recover from first OOM
|
||||
Cu.getJSTestingFunctions().reportOutOfMemory();
|
||||
},
|
||||
function(mdump, extra) {
|
||||
Assert.equal(extra.TestingOOMCrash, "Yes");
|
||||
Assert.equal(extra.TestKey, "Yes");
|
||||
|
||||
// Technically, GC can happen at any time, but it would be really
|
||||
// peculiar for it to happen again heuristically right after a GC was
|
||||
|
|
|
@ -7,10 +7,10 @@ function run_test() {
|
|||
do_crash(
|
||||
function() {
|
||||
crashType = CrashTestUtils.CRASH_OOM;
|
||||
crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
|
||||
crashReporter.annotateCrashReport("TestKey", "Yes");
|
||||
},
|
||||
function(mdump, extra) {
|
||||
Assert.equal(extra.TestingOOMCrash, "Yes");
|
||||
Assert.equal(extra.TestKey, "Yes");
|
||||
Assert.ok("OOMAllocationSize" in extra);
|
||||
Assert.ok(Number(extra.OOMAllocationSize) > 0);
|
||||
},
|
||||
|
|
|
@ -39,27 +39,28 @@ function run_test() {
|
|||
cr.minidumpPath = cwd;
|
||||
Assert.equal(cr.minidumpPath.path, cwd.path);
|
||||
|
||||
// Test annotateCrashReport()
|
||||
try {
|
||||
cr.annotateCrashReport("equal=equal", "");
|
||||
do_throw("Calling annotateCrashReport() with an '=' in key should have thrown!");
|
||||
cr.annotateCrashReport(undefined, "");
|
||||
do_throw("Calling annotateCrashReport() with an undefined key should have thrown!");
|
||||
} catch (ex) {
|
||||
Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
try {
|
||||
cr.annotateCrashReport("new\nline", "");
|
||||
do_throw("Calling annotateCrashReport() with a '\\n' in key should have thrown!");
|
||||
cr.annotateCrashReport("foobar", "");
|
||||
do_throw("Calling annotateCrashReport() with a bogus key should have thrown!");
|
||||
} catch (ex) {
|
||||
Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
try {
|
||||
cr.annotateCrashReport("", "da\0ta");
|
||||
cr.annotateCrashReport("TestKey", "da\0ta");
|
||||
do_throw("Calling annotateCrashReport() with a '\\0' in data should have thrown!");
|
||||
} catch (ex) {
|
||||
Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
cr.annotateCrashReport("testKey", "testData1");
|
||||
cr.annotateCrashReport("TestKey", "testData1");
|
||||
// Replace previous data.
|
||||
cr.annotateCrashReport("testKey", "testData2");
|
||||
cr.annotateCrashReport("TestKey", "testData2");
|
||||
|
||||
try {
|
||||
cr.appendAppNotesToCrashReport("da\0ta");
|
||||
|
@ -71,6 +72,22 @@ function run_test() {
|
|||
// Add more data.
|
||||
cr.appendAppNotesToCrashReport("additional testData4");
|
||||
|
||||
// Test removeCrashReportAnnotation()
|
||||
try {
|
||||
cr.removeCrashReportAnnotation(undefined);
|
||||
do_throw("Calling removeCrashReportAnnotation() with an undefined key should have thrown!");
|
||||
} catch (ex) {
|
||||
Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
try {
|
||||
cr.removeCrashReportAnnotation("foobar");
|
||||
do_throw("Calling removeCrashReportAnnotation() with a bogus key should have thrown!");
|
||||
} catch (ex) {
|
||||
Assert.equal(ex.result, Cr.NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
cr.removeCrashReportAnnotation("TestKey");
|
||||
|
||||
// Testing setting the minidumpPath field
|
||||
cr.minidumpPath = cwd;
|
||||
Assert.equal(cr.minidumpPath.path, cwd.path);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,8 @@ function run_test() {
|
|||
do_crash(function() {
|
||||
// Add various annotations
|
||||
crashReporter.annotateCrashReport("TestKey", "TestValue");
|
||||
crashReporter.annotateCrashReport("\u2665", "\u{1F4A9}");
|
||||
crashReporter.annotateCrashReport("TestUnicode", "\u{1F4A9}");
|
||||
crashReporter.annotateCrashReport("Add-ons", "test%40mozilla.org:0.1");
|
||||
crashReporter.appendAppNotesToCrashReport("Junk");
|
||||
crashReporter.appendAppNotesToCrashReport("MoreJunk");
|
||||
|
||||
|
@ -45,8 +46,9 @@ function run_test() {
|
|||
},
|
||||
function(mdump, extra) {
|
||||
Assert.equal(extra.TestKey, "TestValue");
|
||||
Assert.equal(extra["\u2665"], "\u{1F4A9}");
|
||||
Assert.equal(extra.TestUnicode, "\u{1F4A9}");
|
||||
Assert.equal(extra.Notes, "JunkMoreJunk");
|
||||
Assert.equal(extra["Add-ons"], "test%40mozilla.org:0.1");
|
||||
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
||||
Assert.ok("TelemetrySessionId" in extra,
|
||||
"The TelemetrySessionId field is present in the extra file");
|
||||
|
|
|
@ -7,10 +7,10 @@ function run_test() {
|
|||
do_crash(
|
||||
function() {
|
||||
crashType = CrashTestUtils.CRASH_OOM;
|
||||
crashReporter.annotateCrashReport("TestingOOMCrash", "Yes");
|
||||
crashReporter.annotateCrashReport("TestKey", "Yes");
|
||||
},
|
||||
function(mdump, extra) {
|
||||
Assert.equal(extra.TestingOOMCrash, "Yes");
|
||||
Assert.equal(extra.TestKey, "Yes");
|
||||
Assert.ok("OOMAllocationSize" in extra);
|
||||
Assert.ok(Number(extra.OOMAllocationSize) > 0);
|
||||
Assert.ok("SystemMemoryUsePercentage" in extra);
|
||||
|
|
|
@ -1235,7 +1235,40 @@ NS_IMETHODIMP
|
|||
nsXULAppInfo::AnnotateCrashReport(const nsACString& key,
|
||||
const nsACString& data)
|
||||
{
|
||||
return CrashReporter::AnnotateCrashReport(key, data);
|
||||
CrashReporter::Annotation annotation;
|
||||
|
||||
if (!AnnotationFromString(annotation, PromiseFlatCString(key).get())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return CrashReporter::AnnotateCrashReport(annotation, data);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULAppInfo::RemoveCrashReportAnnotation(const nsACString& key)
|
||||
{
|
||||
CrashReporter::Annotation annotation;
|
||||
|
||||
if (!AnnotationFromString(annotation, PromiseFlatCString(key).get())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return CrashReporter::RemoveCrashReportAnnotation(annotation);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULAppInfo::IsAnnotationWhitelistedForPing(const nsACString& aValue,
|
||||
bool* aIsWhitelisted)
|
||||
{
|
||||
CrashReporter::Annotation annotation;
|
||||
|
||||
if (!AnnotationFromString(annotation, PromiseFlatCString(aValue).get())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
*aIsWhitelisted = CrashReporter::IsAnnotationWhitelistedForPing(annotation);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -3390,39 +3423,39 @@ XREMain::XRE_mainInit(bool* aExitFlag)
|
|||
CrashReporter::SetServerURL(nsDependentCString(mAppData->crashReporterURL));
|
||||
|
||||
// We overwrite this once we finish starting up.
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("StartupCrash"),
|
||||
NS_LITERAL_CSTRING("1"));
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::StartupCrash,
|
||||
true);
|
||||
|
||||
// pass some basic info from the app data
|
||||
if (mAppData->vendor)
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Vendor"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Vendor,
|
||||
nsDependentCString(mAppData->vendor));
|
||||
if (mAppData->name)
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProductName"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProductName,
|
||||
nsDependentCString(mAppData->name));
|
||||
if (mAppData->ID)
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ProductID"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::ProductID,
|
||||
nsDependentCString(mAppData->ID));
|
||||
if (mAppData->version)
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Version"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Version,
|
||||
nsDependentCString(mAppData->version));
|
||||
if (mAppData->buildID)
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("BuildID"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::BuildID,
|
||||
nsDependentCString(mAppData->buildID));
|
||||
|
||||
nsDependentCString releaseChannel(NS_STRINGIFY(MOZ_UPDATE_CHANNEL));
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ReleaseChannel"),
|
||||
releaseChannel);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ReleaseChannel, releaseChannel);
|
||||
#ifdef MOZ_LINKER
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CrashAddressLikelyWrong"),
|
||||
IsSignalHandlingBroken() ? NS_LITERAL_CSTRING("1")
|
||||
: NS_LITERAL_CSTRING("0"));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::CrashAddressLikelyWrong,
|
||||
IsSignalHandlingBroken());
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
nsAutoString appInitDLLs;
|
||||
if (widget::WinUtils::GetAppInitDLLs(appInitDLLs)) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AppInitDLLs"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AppInitDLLs,
|
||||
NS_ConvertUTF16toUTF8(appInitDLLs));
|
||||
}
|
||||
#endif
|
||||
|
@ -3583,16 +3616,15 @@ XREMain::XRE_mainInit(bool* aExitFlag)
|
|||
}
|
||||
|
||||
if (cpuUpdateRevision > 0) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CPUMicrocodeVersion"),
|
||||
nsPrintfCString("0x%x",
|
||||
cpuUpdateRevision));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::CPUMicrocodeVersion,
|
||||
nsPrintfCString("0x%x", cpuUpdateRevision));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("SafeMode"),
|
||||
gSafeMode ? NS_LITERAL_CSTRING("1") :
|
||||
NS_LITERAL_CSTRING("0"));
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::SafeMode,
|
||||
gSafeMode);
|
||||
|
||||
// Handle --no-remote and --new-instance command line arguments. Setup
|
||||
// the environment to better accommodate other components and various
|
||||
|
@ -3715,8 +3747,9 @@ static void AnnotateSystemManufacturer()
|
|||
hr = classObject->Get(L"Manufacturer", 0, &value, 0, 0);
|
||||
|
||||
if (SUCCEEDED(hr) && V_VT(&value) == VT_BSTR) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("BIOS_Manufacturer"),
|
||||
NS_ConvertUTF16toUTF8(V_BSTR(&value)));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::BIOS_Manufacturer,
|
||||
NS_ConvertUTF16toUTF8(V_BSTR(&value)));
|
||||
}
|
||||
|
||||
VariantClear(&value);
|
||||
|
@ -4360,7 +4393,7 @@ void AddSandboxAnnotations()
|
|||
levelString.AppendInt(level);
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("ContentSandboxLevel"), levelString);
|
||||
CrashReporter::Annotation::ContentSandboxLevel, levelString);
|
||||
|
||||
// Include whether or not this instance is capable of content sandboxing
|
||||
bool sandboxCapable = false;
|
||||
|
@ -4376,8 +4409,7 @@ void AddSandboxAnnotations()
|
|||
#endif
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("ContentSandboxCapable"),
|
||||
sandboxCapable ? NS_LITERAL_CSTRING("1") : NS_LITERAL_CSTRING("0"));
|
||||
CrashReporter::Annotation::ContentSandboxCapable, sandboxCapable);
|
||||
}
|
||||
#endif /* MOZ_CONTENT_SANDBOX */
|
||||
|
||||
|
@ -4431,16 +4463,18 @@ XREMain::XRE_mainRun()
|
|||
nsAutoCString sval;
|
||||
rv = defaultPrefBranch->GetCharPref("app.update.channel", sval);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("ReleaseChannel"),
|
||||
sval);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::ReleaseChannel, sval);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Needs to be set after xpcom initialization.
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonBase"),
|
||||
nsPrintfCString("%.16" PRIu64, uint64_t(gMozillaPoisonBase)));
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("FramePoisonSize"),
|
||||
nsPrintfCString("%" PRIu32, uint32_t(gMozillaPoisonSize)));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::FramePoisonBase,
|
||||
nsPrintfCString("%.16" PRIu64, uint64_t(gMozillaPoisonBase)));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::FramePoisonSize,
|
||||
uint32_t(gMozillaPoisonSize));
|
||||
|
||||
bool includeContextHeap =
|
||||
Preferences::GetBool("toolkit.crashreporter.include_context_heap", false);
|
||||
|
@ -4599,7 +4633,8 @@ XREMain::XRE_mainRun()
|
|||
|
||||
nsCString userAgentLocale;
|
||||
LocaleService::GetInstance()->GetAppLocaleAsLangTag(userAgentLocale);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("useragent_locale"), userAgentLocale);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::useragent_locale, userAgentLocale);
|
||||
|
||||
appStartup->GetShuttingDown(&mShuttingDown);
|
||||
|
||||
|
@ -4695,8 +4730,8 @@ XREMain::XRE_mainRun()
|
|||
|
||||
(void)appStartup->DoneStartingUp();
|
||||
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("StartupCrash"),
|
||||
NS_LITERAL_CSTRING("0"));
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::StartupCrash,
|
||||
false);
|
||||
|
||||
appStartup->GetShuttingDown(&mShuttingDown);
|
||||
}
|
||||
|
@ -4753,7 +4788,7 @@ XREMain::XRE_mainRun()
|
|||
flagsString.AppendInt(sandboxInfo.AsInteger());
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("ContentSandboxCapabilities"), flagsString);
|
||||
CrashReporter::Annotation::ContentSandboxCapabilities, flagsString);
|
||||
#endif /* MOZ_SANDBOX && XP_LINUX */
|
||||
|
||||
#if defined(MOZ_CONTENT_SANDBOX)
|
||||
|
|
|
@ -325,10 +325,8 @@ AddContentSandboxLevelAnnotation()
|
|||
{
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
int level = GetEffectiveContentSandboxLevel();
|
||||
nsAutoCString levelString;
|
||||
levelString.AppendInt(level);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("ContentSandboxLevel"), levelString);
|
||||
CrashReporter::Annotation::ContentSandboxLevel, level);
|
||||
}
|
||||
}
|
||||
#endif /* MOZ_CONTENT_SANDBOX */
|
||||
|
|
|
@ -348,19 +348,12 @@ GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active)
|
|||
void
|
||||
GfxInfo::AddCrashReportAnnotations()
|
||||
{
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
|
||||
mGLStrings->Vendor());
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
|
||||
mGLStrings->Renderer());
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"),
|
||||
mGLStrings->Version());
|
||||
|
||||
/* Add an App Note for now so that we get the data immediately. These
|
||||
* can go away after we store the above in the socorro db */
|
||||
nsAutoCString note;
|
||||
note.AppendPrintf("AdapterDescription: '%s'\n", mAdapterDescription.get());
|
||||
|
||||
CrashReporter::AppendAppNotesToCrashReport(note);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::AdapterDriverVersion, mGLStrings->Version());
|
||||
}
|
||||
|
||||
const nsTArray<GfxDriverInfo>&
|
||||
|
|
|
@ -204,8 +204,8 @@ bool ReportException(JNIEnv* aEnv, jthrowable aExc, jstring aStack)
|
|||
bool result = true;
|
||||
|
||||
result &= NS_SUCCEEDED(CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("JavaStackTrace"),
|
||||
String::Ref::From(aStack)->ToCString()));
|
||||
CrashReporter::Annotation::JavaStackTrace,
|
||||
String::Ref::From(aStack)->ToCString()));
|
||||
|
||||
auto appNotes = java::GeckoAppShell::GetAppNotes();
|
||||
if (NS_WARN_IF(aEnv->ExceptionCheck())) {
|
||||
|
|
|
@ -9,13 +9,11 @@
|
|||
#include "base/message_loop.h"
|
||||
#include "base/task.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "nsIScreen.h"
|
||||
#include "nsIScreenManager.h"
|
||||
#include "nsWindow.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsICommandLineRunner.h"
|
||||
#include "nsICrashReporter.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIAppStartup.h"
|
||||
#include "nsIGeolocationProvider.h"
|
||||
|
|
|
@ -283,21 +283,12 @@ GfxInfo::AddCrashReportAnnotations()
|
|||
GetAdapterDriverVersion(driverVersion);
|
||||
CopyUTF16toUTF8(driverVersion, narrowDriverVersion);
|
||||
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
|
||||
narrowVendorID);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
|
||||
narrowDeviceID);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"),
|
||||
narrowDriverVersion);
|
||||
/* Add an App Note for now so that we get the data immediately. These
|
||||
* can go away after we store the above in the socorro db */
|
||||
nsAutoCString note;
|
||||
/* AppendPrintf only supports 32 character strings, mrghh. */
|
||||
note.AppendLiteral("AdapterVendorID: ");
|
||||
note.Append(narrowVendorID);
|
||||
note.AppendLiteral(", AdapterDeviceID: ");
|
||||
note.Append(narrowDeviceID);
|
||||
CrashReporter::AppendAppNotesToCrashReport(note);
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::AdapterDriverVersion, narrowDriverVersion);
|
||||
}
|
||||
|
||||
// We don't support checking driver versions on Mac.
|
||||
|
|
|
@ -893,35 +893,24 @@ GfxInfo::AddCrashReportAnnotations()
|
|||
GetAdapterSubsysID(subsysID);
|
||||
CopyUTF16toUTF8(subsysID, narrowSubsysID);
|
||||
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterVendorID"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterVendorID,
|
||||
narrowVendorID);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDeviceID"),
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterDeviceID,
|
||||
narrowDeviceID);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterDriverVersion"),
|
||||
narrowDriverVersion);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterSubsysID"),
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::AdapterDriverVersion, narrowDriverVersion);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::AdapterSubsysID,
|
||||
narrowSubsysID);
|
||||
|
||||
/* Add an App Note for now so that we get the data immediately. These
|
||||
* can go away after we store the above in the socorro db */
|
||||
/* Add an App Note, this contains extra information. */
|
||||
nsAutoCString note;
|
||||
/* AppendPrintf only supports 32 character strings, mrghh. */
|
||||
note.AppendLiteral("AdapterVendorID: ");
|
||||
note.Append(narrowVendorID);
|
||||
note.AppendLiteral(", AdapterDeviceID: ");
|
||||
note.Append(narrowDeviceID);
|
||||
note.AppendLiteral(", AdapterSubsysID: ");
|
||||
note.Append(narrowSubsysID);
|
||||
note.AppendLiteral(", AdapterDriverVersion: ");
|
||||
note.Append(NS_LossyConvertUTF16toASCII(driverVersion));
|
||||
|
||||
// TODO: We should probably convert this into a proper annotation
|
||||
if (vendorID == GfxDriverInfo::GetDeviceVendor(VendorAll)) {
|
||||
/* if we didn't find a valid vendorID lets append the mDeviceID string to try to find out why */
|
||||
note.AppendLiteral(", ");
|
||||
LossyAppendUTF16toASCII(mDeviceID[mActiveGPUIndex], note);
|
||||
note.AppendLiteral(", ");
|
||||
LossyAppendUTF16toASCII(mDeviceKeyDebug, note);
|
||||
LossyAppendUTF16toASCII(mDeviceKeyDebug, note);
|
||||
}
|
||||
note.AppendLiteral("\n");
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "nsExceptionHandler.h"
|
||||
#include "nsIMemoryReporter.h"
|
||||
#include "nsMemoryPressure.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#endif
|
||||
|
||||
#include "nsIObserver.h"
|
||||
|
@ -151,8 +150,8 @@ nsAvailableMemoryWatcher::IsCommitSpaceLow(const MEMORYSTATUSEX& aStat)
|
|||
(aStat.ullAvailPageFile < kLowCommitSpaceThreshold)) {
|
||||
sNumLowCommitSpaceEvents++;
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
NS_LITERAL_CSTRING("LowCommitSpaceEvents"),
|
||||
nsPrintfCString("%" PRIu32, uint32_t(sNumLowCommitSpaceEvents)));
|
||||
CrashReporter::Annotation::LowCommitSpaceEvents,
|
||||
uint32_t(sNumLowCommitSpaceEvents));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1473,19 +1473,35 @@ CycleCollectedJSRuntime::FinalizeDeferredThings(CycleCollectedJSContext::Deferre
|
|||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
CycleCollectedJSRuntime::OOMStateToString(const OOMState aOomState) const
|
||||
{
|
||||
switch (aOomState) {
|
||||
case OOMState::OK:
|
||||
return "OK";
|
||||
case OOMState::Reporting:
|
||||
return "Reporting";
|
||||
case OOMState::Reported:
|
||||
return "Reported";
|
||||
case OOMState::Recovered:
|
||||
return "Recovered";
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("OOMState holds an invalid value");
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CycleCollectedJSRuntime::AnnotateAndSetOutOfMemory(OOMState* aStatePtr,
|
||||
OOMState aNewState)
|
||||
{
|
||||
*aStatePtr = aNewState;
|
||||
CrashReporter::AnnotateCrashReport(aStatePtr == &mOutOfMemoryState
|
||||
? NS_LITERAL_CSTRING("JSOutOfMemory")
|
||||
: NS_LITERAL_CSTRING("JSLargeAllocationFailure"),
|
||||
aNewState == OOMState::Reporting
|
||||
? NS_LITERAL_CSTRING("Reporting")
|
||||
: aNewState == OOMState::Reported
|
||||
? NS_LITERAL_CSTRING("Reported")
|
||||
: NS_LITERAL_CSTRING("Recovered"));
|
||||
CrashReporter::Annotation annotation = (aStatePtr == &mOutOfMemoryState)
|
||||
? CrashReporter::Annotation::JSOutOfMemory
|
||||
: CrashReporter::Annotation::JSLargeAllocationFailure;
|
||||
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
annotation, nsDependentCString(OOMStateToString(aNewState)));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -237,6 +237,8 @@ public:
|
|||
Recovered
|
||||
};
|
||||
|
||||
const char* OOMStateToString(const OOMState aOomState) const;
|
||||
|
||||
void SetLargeAllocationFailure(OOMState aNewState);
|
||||
|
||||
void AnnotateAndSetOutOfMemory(OOMState* aStatePtr, OOMState aNewState);
|
||||
|
|
|
@ -675,7 +675,8 @@ PtrInfo::AnnotatedReleaseAssert(bool aCondition, const char* aMessage)
|
|||
piName = mParticipant->ClassName();
|
||||
}
|
||||
nsPrintfCString msg("%s, for class %s", aMessage, piName);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("CycleCollector"), msg);
|
||||
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::CycleCollector,
|
||||
msg);
|
||||
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
|
|
@ -409,8 +409,9 @@ NS_DebugBreak(uint32_t aSeverity, const char* aStr, const char* aExpr,
|
|||
note += nonPIDBuf.buffer;
|
||||
note += ")";
|
||||
CrashReporter::AppendAppNotesToCrashReport(note);
|
||||
CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AbortMessage"),
|
||||
nsDependentCString(nonPIDBuf.buffer));
|
||||
CrashReporter::AnnotateCrashReport(
|
||||
CrashReporter::Annotation::AbortMessage,
|
||||
nsDependentCString(nonPIDBuf.buffer));
|
||||
}
|
||||
|
||||
#if defined(DEBUG) && defined(_WIN32)
|
||||
|
|
|
@ -76,17 +76,40 @@ interface nsICrashReporter : nsISupports
|
|||
* Add some extra data to be submitted with a crash report.
|
||||
*
|
||||
* @param key
|
||||
* Name of the data to be added.
|
||||
* Name of a known crash annotation constant.
|
||||
* @param data
|
||||
* Data to be added.
|
||||
*
|
||||
* @throw NS_ERROR_NOT_INITIALIZED if crash reporting not initialized
|
||||
* @throw NS_ERROR_INVALID_ARG if key or data contain invalid characters.
|
||||
* Invalid characters for key are '=' and
|
||||
* '\n'. Invalid character for data is '\0'.
|
||||
* @throw NS_ERROR_INVALID_ARG if key contains an invalid value or data
|
||||
* contains invalid characters. Invalid
|
||||
* character for data is '\0'.
|
||||
*/
|
||||
void annotateCrashReport(in AUTF8String key, in AUTF8String data);
|
||||
|
||||
/**
|
||||
* Remove a crash report annotation.
|
||||
*
|
||||
* @param key
|
||||
* Name of a known crash annotation constant.
|
||||
*
|
||||
* @throw NS_ERROR_NOT_INITIALIZED if crash reporting not initialized
|
||||
* @throw NS_ERROR_INVALID_ARG if key contains an invalid value.
|
||||
*/
|
||||
void removeCrashReportAnnotation(in AUTF8String key);
|
||||
|
||||
/**
|
||||
* Checks if an annotation is whitelisted for inclusion in the crash ping.
|
||||
*
|
||||
* @param key
|
||||
* Name of a known crash annotation constant.
|
||||
*
|
||||
* @return True if the specified value is a valid annotation and can be
|
||||
included in the crash ping, false otherwise.
|
||||
* @throw NS_ERROR_INVALID_ARG if key contains an invalid value.
|
||||
*/
|
||||
boolean isAnnotationWhitelistedForPing(in ACString value);
|
||||
|
||||
/**
|
||||
* Append some data to the "Notes" field, to be submitted with a crash report.
|
||||
* Unlike annotateCrashReport, this method will append to existing data.
|
||||
|
@ -121,7 +144,7 @@ interface nsICrashReporter : nsISupports
|
|||
* @param aExceptionInfo EXCEPTION_INFO* provided by Window's SEH
|
||||
*/
|
||||
[noscript] void writeMinidumpForException(in voidPtr aExceptionInfo);
|
||||
|
||||
|
||||
/**
|
||||
* Append note containing an Obj-C exception's info.
|
||||
*
|
||||
|
|
Загрузка…
Ссылка в новой задаче