CrashReporterHost.h (5148B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef mozilla_ipc_CrashReporterHost_h 8 #define mozilla_ipc_CrashReporterHost_h 9 10 #include <functional> 11 12 #include "base/process.h" 13 #include "nsExceptionHandler.h" 14 #include "nsIFile.h" 15 #include "nsThreadUtils.h" 16 #include "mozilla/ipc/GeckoChildProcessHost.h" 17 #include "mozilla/ipc/ProtocolUtils.h" 18 19 namespace CrashReporter { 20 class CrashReporterInitArgs; 21 } 22 23 namespace mozilla::ipc { 24 25 // This is the newer replacement for CrashReporterParent. It is created in 26 // response to a InitCrashReporter message on a top-level actor. When the 27 // process terminates abnormally, the top-level should call GenerateCrashReport 28 // to automatically integrate metadata. 29 class CrashReporterHost { 30 typedef CrashReporter::AnnotationTable AnnotationTable; 31 32 public: 33 CrashReporterHost(GeckoProcessType aProcessType, base::ProcessId aPid, 34 const CrashReporter::CrashReporterInitArgs& aInitArgs); 35 ~CrashReporterHost(); 36 37 // Helper function for generating a crash report for a process that probably 38 // crashed (i.e., had an AbnormalShutdown in ActorDestroy). Returns true if 39 // the process has a minidump attached and we were able to generate a report. 40 bool GenerateCrashReport(); 41 42 // Given an existing minidump for a crashed child process, take ownership of 43 // it from IPDL. After this, FinalizeCrashReport may be called. 44 RefPtr<nsIFile> TakeCrashedChildMinidump(); 45 46 // Replace the stored minidump with a new one. After this, 47 // FinalizeCrashReport may be called. 48 bool AdoptMinidump(nsIFile* aFile, const AnnotationTable& aAnnotations); 49 50 // If a minidump was already captured (e.g. via the hang reporter), this 51 // finalizes the existing report by attaching metadata, writing out the 52 // .extra file and notifying the crash service. 53 void FinalizeCrashReport(); 54 55 // Delete any crash report we might have generated. 56 void DeleteCrashReport(); 57 58 // Generate a paired minidump. This does not take the crash report, as 59 // GenerateCrashReport does. After this, FinalizeCrashReport may be called. 60 // 61 // This calls TakeCrashedChildMinidump and FinalizeCrashReport. 62 bool GenerateMinidumpAndPair(GeckoChildProcessHost* aChildProcessHost, 63 const nsACString& aPairName) { 64 auto childHandle = base::kInvalidProcessHandle; 65 const auto cleanup = MakeScopeExit([&]() { 66 if (childHandle && childHandle != base::kInvalidProcessHandle) { 67 base::CloseProcessHandle(childHandle); 68 } 69 }); 70 #ifdef XP_MACOSX 71 childHandle = aChildProcessHost->GetChildTask(); 72 #else 73 if (!base::OpenPrivilegedProcessHandle( 74 aChildProcessHost->GetChildProcessId(), &childHandle)) { 75 NS_WARNING("Failed to open child process handle."); 76 return false; 77 } 78 #endif 79 80 nsCOMPtr<nsIFile> targetDump; 81 if (!CrashReporter::CreateMinidumpsAndPair(childHandle, mThreadId, 82 aPairName, mExtraAnnotations, 83 getter_AddRefs(targetDump))) { 84 return false; 85 } 86 87 return CrashReporter::GetIDFromMinidump(targetDump, mDumpID); 88 } 89 90 void AddAnnotationBool(CrashReporter::Annotation aKey, bool aValue); 91 void AddAnnotationU32(CrashReporter::Annotation aKey, uint32_t aValue); 92 void AddAnnotationNSCString(CrashReporter::Annotation aKey, 93 const nsACString& aValue); 94 95 bool HasMinidump() const { return !mDumpID.IsEmpty(); } 96 const nsString& MinidumpID() const { 97 MOZ_ASSERT(HasMinidump()); 98 return mDumpID; 99 } 100 const nsCString& AdditionalMinidumps() const { 101 return mExtraAnnotations[CrashReporter::Annotation::additional_minidumps]; 102 } 103 // Get the process type string. 104 const char* ProcessType() const; 105 106 // This is a static helper function to notify the crash service that a 107 // crash has occurred and record the crash with telemetry. This can be called 108 // from any thread, and if not called from the main thread, will post a 109 // synchronous message to the main thread. 110 static void RecordCrash(GeckoProcessType aProcessType, int32_t aCrashType, 111 const nsString& aChildDumpID); 112 113 private: 114 // Get the nsICrashService crash type to use for an impending crash. 115 int32_t GetCrashType(); 116 117 static void RecordCrashWithTelemetry(GeckoProcessType aProcessType, 118 int32_t aCrashType); 119 static void NotifyCrashService(GeckoProcessType aProcessType, 120 int32_t aCrashType, 121 const nsString& aChildDumpID); 122 123 private: 124 GeckoProcessType mProcessType; 125 base::ProcessId mPid; 126 CrashReporter::ThreadId mThreadId; 127 time_t mStartTime; 128 AnnotationTable mExtraAnnotations; 129 nsString mDumpID; 130 bool mFinalized; 131 }; 132 133 } // namespace mozilla::ipc 134 135 #endif // mozilla_ipc_CrashReporterHost_h