1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/ipc/CrashReporterParent.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,160 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * vim: set sw=4 ts=8 et tw=80 : 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef mozilla_dom_CrashReporterParent_h 1.11 +#define mozilla_dom_CrashReporterParent_h 1.12 + 1.13 +#include "mozilla/dom/PCrashReporterParent.h" 1.14 +#include "mozilla/dom/TabMessageUtils.h" 1.15 +#include "nsIFile.h" 1.16 +#ifdef MOZ_CRASHREPORTER 1.17 +#include "nsExceptionHandler.h" 1.18 +#include "nsDataHashtable.h" 1.19 +#endif 1.20 + 1.21 +namespace mozilla { 1.22 +namespace dom { 1.23 +class ProcessReporter; 1.24 + 1.25 +class CrashReporterParent : 1.26 + public PCrashReporterParent 1.27 +{ 1.28 +#ifdef MOZ_CRASHREPORTER 1.29 + typedef CrashReporter::AnnotationTable AnnotationTable; 1.30 +#endif 1.31 +public: 1.32 + CrashReporterParent(); 1.33 + virtual ~CrashReporterParent(); 1.34 + 1.35 +#ifdef MOZ_CRASHREPORTER 1.36 + /* Attempt to generate a parent/child pair of minidumps from the given 1.37 + toplevel actor in the event of a hang. Returns true if successful, 1.38 + false otherwise. 1.39 + */ 1.40 + template<class Toplevel> 1.41 + bool 1.42 + GeneratePairedMinidump(Toplevel* t); 1.43 + 1.44 + /* Attempt to create a bare-bones crash report, along with extra process- 1.45 + specific annotations present in the given AnnotationTable. Returns true if 1.46 + successful, false otherwise. 1.47 + */ 1.48 + template<class Toplevel> 1.49 + bool 1.50 + GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes); 1.51 + 1.52 + /** 1.53 + * Add the .extra data for an existing crash report. 1.54 + */ 1.55 + bool 1.56 + GenerateChildData(const AnnotationTable* processNotes); 1.57 + 1.58 + bool 1.59 + GenerateCrashReportForMinidump(nsIFile* minidump, 1.60 + const AnnotationTable* processNotes); 1.61 + 1.62 + /* Instantiate a new crash reporter actor from a given parent that manages 1.63 + the protocol. 1.64 + */ 1.65 + template<class Toplevel> 1.66 + static bool CreateCrashReporter(Toplevel* actor); 1.67 +#endif 1.68 + /* Initialize this reporter with data from the child process */ 1.69 + void 1.70 + SetChildData(const NativeThreadId& id, const uint32_t& processType); 1.71 + 1.72 + /* Returns the ID of the child minidump. 1.73 + GeneratePairedMinidump or GenerateCrashReport must be called first. 1.74 + */ 1.75 + const nsString& ChildDumpID() { 1.76 + return mChildDumpID; 1.77 + } 1.78 + 1.79 + void 1.80 + AnnotateCrashReport(const nsCString& key, const nsCString& data); 1.81 + 1.82 + protected: 1.83 + virtual bool 1.84 + RecvAnnotateCrashReport(const nsCString& key, const nsCString& data) MOZ_OVERRIDE { 1.85 + AnnotateCrashReport(key, data); 1.86 + return true; 1.87 + } 1.88 + virtual bool 1.89 + RecvAppendAppNotes(const nsCString& data) MOZ_OVERRIDE; 1.90 + virtual mozilla::ipc::IProtocol* 1.91 + CloneProtocol(Channel* aChannel, 1.92 + mozilla::ipc::ProtocolCloneContext *aCtx) MOZ_OVERRIDE; 1.93 + 1.94 +#ifdef MOZ_CRASHREPORTER 1.95 + AnnotationTable mNotes; 1.96 +#endif 1.97 + nsCString mAppNotes; 1.98 + nsString mChildDumpID; 1.99 + NativeThreadId mMainThread; 1.100 + time_t mStartTime; 1.101 + uint32_t mProcessType; 1.102 + bool mInitialized; 1.103 +}; 1.104 + 1.105 +#ifdef MOZ_CRASHREPORTER 1.106 +template<class Toplevel> 1.107 +inline bool 1.108 +CrashReporterParent::GeneratePairedMinidump(Toplevel* t) 1.109 +{ 1.110 + CrashReporter::ProcessHandle child; 1.111 +#ifdef XP_MACOSX 1.112 + child = t->Process()->GetChildTask(); 1.113 +#else 1.114 + child = t->OtherProcess(); 1.115 +#endif 1.116 + nsCOMPtr<nsIFile> childDump; 1.117 + if (CrashReporter::CreatePairedMinidumps(child, 1.118 + mMainThread, 1.119 + getter_AddRefs(childDump)) && 1.120 + CrashReporter::GetIDFromMinidump(childDump, mChildDumpID)) { 1.121 + return true; 1.122 + } 1.123 + return false; 1.124 +} 1.125 + 1.126 +template<class Toplevel> 1.127 +inline bool 1.128 +CrashReporterParent::GenerateCrashReport(Toplevel* t, 1.129 + const AnnotationTable* processNotes) 1.130 +{ 1.131 + nsCOMPtr<nsIFile> crashDump; 1.132 + if (t->TakeMinidump(getter_AddRefs(crashDump), nullptr) && 1.133 + CrashReporter::GetIDFromMinidump(crashDump, mChildDumpID)) { 1.134 + return GenerateChildData(processNotes); 1.135 + } 1.136 + return false; 1.137 +} 1.138 + 1.139 +template<class Toplevel> 1.140 +/* static */ bool 1.141 +CrashReporterParent::CreateCrashReporter(Toplevel* actor) 1.142 +{ 1.143 +#ifdef MOZ_CRASHREPORTER 1.144 + NativeThreadId id; 1.145 + uint32_t processType; 1.146 + PCrashReporterParent* p = 1.147 + actor->CallPCrashReporterConstructor(&id, &processType); 1.148 + if (p) { 1.149 + static_cast<CrashReporterParent*>(p)->SetChildData(id, processType); 1.150 + } else { 1.151 + NS_ERROR("Error creating crash reporter actor"); 1.152 + } 1.153 + return !!p; 1.154 +#endif 1.155 + return false; 1.156 +} 1.157 + 1.158 +#endif 1.159 + 1.160 +} // namespace dom 1.161 +} // namespace mozilla 1.162 + 1.163 +#endif // mozilla_dom_CrashReporterParent_h