michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set sw=4 ts=8 et tw=80 : michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: #include "CrashReporterParent.h" michael@0: #include "mozilla/dom/ContentParent.h" michael@0: #include "nsXULAppAPI.h" michael@0: #include michael@0: michael@0: #ifdef MOZ_CRASHREPORTER michael@0: #include "nsExceptionHandler.h" michael@0: #endif michael@0: michael@0: using namespace base; michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: michael@0: void michael@0: CrashReporterParent::AnnotateCrashReport(const nsCString& key, michael@0: const nsCString& data) michael@0: { michael@0: #ifdef MOZ_CRASHREPORTER michael@0: mNotes.Put(key, data); michael@0: #endif michael@0: } michael@0: michael@0: bool michael@0: CrashReporterParent::RecvAppendAppNotes(const nsCString& data) michael@0: { michael@0: mAppNotes.Append(data); michael@0: return true; michael@0: } michael@0: michael@0: mozilla::ipc::IProtocol* michael@0: CrashReporterParent::CloneProtocol(Channel* aChannel, michael@0: mozilla::ipc::ProtocolCloneContext* aCtx) michael@0: { michael@0: #ifdef MOZ_CRASHREPORTER michael@0: ContentParent* contentParent = aCtx->GetContentParent(); michael@0: CrashReporter::ThreadId childThreadId = contentParent->Pid(); michael@0: GeckoProcessType childProcessType = michael@0: contentParent->Process()->GetProcessType(); michael@0: michael@0: nsAutoPtr actor( michael@0: contentParent->AllocPCrashReporterParent(childThreadId, michael@0: childProcessType) michael@0: ); michael@0: if (!actor || michael@0: !contentParent->RecvPCrashReporterConstructor(actor, michael@0: childThreadId, michael@0: childThreadId)) { michael@0: return nullptr; michael@0: } michael@0: michael@0: return actor.forget(); michael@0: #else michael@0: MOZ_CRASH("Not Implemented"); michael@0: return nullptr; michael@0: #endif michael@0: } michael@0: michael@0: CrashReporterParent::CrashReporterParent() michael@0: : michael@0: #ifdef MOZ_CRASHREPORTER michael@0: mNotes(4), michael@0: #endif michael@0: mStartTime(::time(nullptr)) michael@0: , mInitialized(false) michael@0: { michael@0: MOZ_COUNT_CTOR(CrashReporterParent); michael@0: } michael@0: michael@0: CrashReporterParent::~CrashReporterParent() michael@0: { michael@0: MOZ_COUNT_DTOR(CrashReporterParent); michael@0: } michael@0: michael@0: void michael@0: CrashReporterParent::SetChildData(const NativeThreadId& tid, michael@0: const uint32_t& processType) michael@0: { michael@0: mInitialized = true; michael@0: mMainThread = tid; michael@0: mProcessType = processType; michael@0: } michael@0: michael@0: #ifdef MOZ_CRASHREPORTER michael@0: bool michael@0: CrashReporterParent::GenerateCrashReportForMinidump(nsIFile* minidump, michael@0: const AnnotationTable* processNotes) michael@0: { michael@0: if (!CrashReporter::GetIDFromMinidump(minidump, mChildDumpID)) michael@0: return false; michael@0: return GenerateChildData(processNotes); michael@0: } michael@0: michael@0: bool michael@0: CrashReporterParent::GenerateChildData(const AnnotationTable* processNotes) michael@0: { michael@0: MOZ_ASSERT(mInitialized); michael@0: michael@0: nsAutoCString type; michael@0: switch (mProcessType) { michael@0: case GeckoProcessType_Content: michael@0: type = NS_LITERAL_CSTRING("content"); michael@0: break; michael@0: case GeckoProcessType_Plugin: michael@0: type = NS_LITERAL_CSTRING("plugin"); michael@0: break; michael@0: default: michael@0: NS_ERROR("unknown process type"); michael@0: break; michael@0: } michael@0: mNotes.Put(NS_LITERAL_CSTRING("ProcessType"), type); michael@0: michael@0: char startTime[32]; michael@0: sprintf(startTime, "%lld", static_cast(mStartTime)); michael@0: mNotes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime)); michael@0: michael@0: if (!mAppNotes.IsEmpty()) michael@0: mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes); michael@0: michael@0: bool ret = CrashReporter::AppendExtraData(mChildDumpID, mNotes); michael@0: if (ret && processNotes) michael@0: ret = CrashReporter::AppendExtraData(mChildDumpID, *processNotes); michael@0: if (!ret) michael@0: NS_WARNING("problem appending child data to .extra"); michael@0: return ret; michael@0: } michael@0: #endif michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla