michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 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: michael@0: #ifndef mozilla_dom_CrashReporterParent_h michael@0: #define mozilla_dom_CrashReporterParent_h michael@0: michael@0: #include "mozilla/dom/PCrashReporterParent.h" michael@0: #include "mozilla/dom/TabMessageUtils.h" michael@0: #include "nsIFile.h" michael@0: #ifdef MOZ_CRASHREPORTER michael@0: #include "nsExceptionHandler.h" michael@0: #include "nsDataHashtable.h" michael@0: #endif michael@0: michael@0: namespace mozilla { michael@0: namespace dom { michael@0: class ProcessReporter; michael@0: michael@0: class CrashReporterParent : michael@0: public PCrashReporterParent michael@0: { michael@0: #ifdef MOZ_CRASHREPORTER michael@0: typedef CrashReporter::AnnotationTable AnnotationTable; michael@0: #endif michael@0: public: michael@0: CrashReporterParent(); michael@0: virtual ~CrashReporterParent(); michael@0: michael@0: #ifdef MOZ_CRASHREPORTER michael@0: /* Attempt to generate a parent/child pair of minidumps from the given michael@0: toplevel actor in the event of a hang. Returns true if successful, michael@0: false otherwise. michael@0: */ michael@0: template michael@0: bool michael@0: GeneratePairedMinidump(Toplevel* t); michael@0: michael@0: /* Attempt to create a bare-bones crash report, along with extra process- michael@0: specific annotations present in the given AnnotationTable. Returns true if michael@0: successful, false otherwise. michael@0: */ michael@0: template michael@0: bool michael@0: GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes); michael@0: michael@0: /** michael@0: * Add the .extra data for an existing crash report. michael@0: */ michael@0: bool michael@0: GenerateChildData(const AnnotationTable* processNotes); michael@0: michael@0: bool michael@0: GenerateCrashReportForMinidump(nsIFile* minidump, michael@0: const AnnotationTable* processNotes); michael@0: michael@0: /* Instantiate a new crash reporter actor from a given parent that manages michael@0: the protocol. michael@0: */ michael@0: template michael@0: static bool CreateCrashReporter(Toplevel* actor); michael@0: #endif michael@0: /* Initialize this reporter with data from the child process */ michael@0: void michael@0: SetChildData(const NativeThreadId& id, const uint32_t& processType); michael@0: michael@0: /* Returns the ID of the child minidump. michael@0: GeneratePairedMinidump or GenerateCrashReport must be called first. michael@0: */ michael@0: const nsString& ChildDumpID() { michael@0: return mChildDumpID; michael@0: } michael@0: michael@0: void michael@0: AnnotateCrashReport(const nsCString& key, const nsCString& data); michael@0: michael@0: protected: michael@0: virtual bool michael@0: RecvAnnotateCrashReport(const nsCString& key, const nsCString& data) MOZ_OVERRIDE { michael@0: AnnotateCrashReport(key, data); michael@0: return true; michael@0: } michael@0: virtual bool michael@0: RecvAppendAppNotes(const nsCString& data) MOZ_OVERRIDE; michael@0: virtual mozilla::ipc::IProtocol* michael@0: CloneProtocol(Channel* aChannel, michael@0: mozilla::ipc::ProtocolCloneContext *aCtx) MOZ_OVERRIDE; michael@0: michael@0: #ifdef MOZ_CRASHREPORTER michael@0: AnnotationTable mNotes; michael@0: #endif michael@0: nsCString mAppNotes; michael@0: nsString mChildDumpID; michael@0: NativeThreadId mMainThread; michael@0: time_t mStartTime; michael@0: uint32_t mProcessType; michael@0: bool mInitialized; michael@0: }; michael@0: michael@0: #ifdef MOZ_CRASHREPORTER michael@0: template michael@0: inline bool michael@0: CrashReporterParent::GeneratePairedMinidump(Toplevel* t) michael@0: { michael@0: CrashReporter::ProcessHandle child; michael@0: #ifdef XP_MACOSX michael@0: child = t->Process()->GetChildTask(); michael@0: #else michael@0: child = t->OtherProcess(); michael@0: #endif michael@0: nsCOMPtr childDump; michael@0: if (CrashReporter::CreatePairedMinidumps(child, michael@0: mMainThread, michael@0: getter_AddRefs(childDump)) && michael@0: CrashReporter::GetIDFromMinidump(childDump, mChildDumpID)) { michael@0: return true; michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: template michael@0: inline bool michael@0: CrashReporterParent::GenerateCrashReport(Toplevel* t, michael@0: const AnnotationTable* processNotes) michael@0: { michael@0: nsCOMPtr crashDump; michael@0: if (t->TakeMinidump(getter_AddRefs(crashDump), nullptr) && michael@0: CrashReporter::GetIDFromMinidump(crashDump, mChildDumpID)) { michael@0: return GenerateChildData(processNotes); michael@0: } michael@0: return false; michael@0: } michael@0: michael@0: template michael@0: /* static */ bool michael@0: CrashReporterParent::CreateCrashReporter(Toplevel* actor) michael@0: { michael@0: #ifdef MOZ_CRASHREPORTER michael@0: NativeThreadId id; michael@0: uint32_t processType; michael@0: PCrashReporterParent* p = michael@0: actor->CallPCrashReporterConstructor(&id, &processType); michael@0: if (p) { michael@0: static_cast(p)->SetChildData(id, processType); michael@0: } else { michael@0: NS_ERROR("Error creating crash reporter actor"); michael@0: } michael@0: return !!p; michael@0: #endif michael@0: return false; michael@0: } michael@0: michael@0: #endif michael@0: michael@0: } // namespace dom michael@0: } // namespace mozilla michael@0: michael@0: #endif // mozilla_dom_CrashReporterParent_h