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:
Gabriele Svelto 2018-07-05 15:42:11 +02:00
Родитель bf2bee5c8e
Коммит 15adf94f4d
81 изменённых файлов: 1829 добавлений и 665 удалений

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

@ -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, &notes);
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.
*