/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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 "CrashReporterParent.h" #include "mozilla/Sprintf.h" #include "mozilla/dom/ContentParent.h" #include "mozilla/ipc/CrashReporterHost.h" #include "nsAutoPtr.h" #include "nsXULAppAPI.h" #include #include "mozilla/Telemetry.h" #ifdef MOZ_CRASHREPORTER #include "nsExceptionHandler.h" #include "nsICrashService.h" #include "mozilla/SyncRunnable.h" #include "nsThreadUtils.h" #endif namespace mozilla { namespace dom { using namespace mozilla::ipc; void CrashReporterParent::AnnotateCrashReport(const nsCString& key, const nsCString& data) { #ifdef MOZ_CRASHREPORTER mNotes.Put(key, data); #endif } void CrashReporterParent::ActorDestroy(ActorDestroyReason aWhy) { // Implement me! Bug 1005155 } bool CrashReporterParent::RecvAppendAppNotes(const nsCString& data) { mAppNotes.Append(data); return true; } CrashReporterParent::CrashReporterParent() : #ifdef MOZ_CRASHREPORTER mNotes(4), #endif mStartTime(::time(nullptr)) , mInitialized(false) { MOZ_COUNT_CTOR(CrashReporterParent); } CrashReporterParent::~CrashReporterParent() { MOZ_COUNT_DTOR(CrashReporterParent); } void CrashReporterParent::SetChildData(const NativeThreadId& tid, const uint32_t& processType) { mInitialized = true; mMainThread = tid; mProcessType = GeckoProcessType(processType); } #ifdef MOZ_CRASHREPORTER bool CrashReporterParent::GenerateCrashReportForMinidump(nsIFile* minidump, const AnnotationTable* processNotes) { if (!CrashReporter::GetIDFromMinidump(minidump, mChildDumpID)) { return false; } bool result = GenerateChildData(processNotes); FinalizeChildData(); return result; } bool CrashReporterParent::GenerateChildData(const AnnotationTable* processNotes) { MOZ_ASSERT(mInitialized); if (mChildDumpID.IsEmpty()) { NS_WARNING("problem with GenerateChildData: no child dump id yet!"); return false; } nsAutoCString type; switch (mProcessType) { case GeckoProcessType_Content: type = NS_LITERAL_CSTRING("content"); break; case GeckoProcessType_Plugin: case GeckoProcessType_GMPlugin: type = NS_LITERAL_CSTRING("plugin"); break; default: NS_ERROR("unknown process type"); break; } mNotes.Put(NS_LITERAL_CSTRING("ProcessType"), type); char startTime[32]; SprintfLiteral(startTime, "%lld", static_cast(mStartTime)); mNotes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime)); if (!mAppNotes.IsEmpty()) { mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes); } // Append these notes to the end of the extra file based on the current // dump id we obtained from CreatePairedMinidumps. bool ret = CrashReporter::AppendExtraData(mChildDumpID, mNotes); if (ret && processNotes) { ret = CrashReporter::AppendExtraData(mChildDumpID, *processNotes); } if (!ret) { NS_WARNING("problem appending child data to .extra"); } return ret; } void CrashReporterParent::FinalizeChildData() { MOZ_ASSERT(mInitialized); CrashReporterHost::NotifyCrashService(mProcessType, mChildDumpID, &mNotes); mNotes.Clear(); } #endif } // namespace dom } // namespace mozilla