RuntimeExceptionModule.cpp (3081B)
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 file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "RuntimeExceptionModule.h" 8 9 #include "mozilla/ProcessType.h" 10 11 #if defined(XP_WIN) 12 # include <windows.h> 13 # if defined(__MINGW32__) || defined(__MINGW64__) 14 // Add missing constants and types for mingw builds 15 typedef HANDLE HREPORT; 16 # define WerReportSubmit(a, b, c, d) \ 17 WerReportSubmit(a, b, c, WER_SUBMIT_RESULT* pSubmitResult) 18 # define WER_MAX_PREFERRED_MODULES_BUFFER 256 19 # endif // defined(__MINGW32__) || defined(__MINGW64__) 20 # include <werapi.h> // For WerRegisterRuntimeExceptionModule() 21 # if defined(__MINGW32__) || defined(__MINGW64__) 22 # undef WerReportSubmit 23 # endif // defined(__MINGW32__) || defined(__MINGW64__) 24 # include <stdlib.h> 25 #endif 26 27 namespace CrashReporter { 28 29 #ifdef XP_WIN 30 31 const static size_t kModulePathLength = MAX_PATH + 1; 32 static wchar_t sModulePath[kModulePathLength]; 33 34 bool GetRuntimeExceptionModulePath(wchar_t* aPath, const size_t aLength) { 35 const wchar_t* kModuleName = L"mozwer.dll"; 36 DWORD res = ::GetModuleFileNameW(nullptr, aPath, aLength); 37 if ((res > 0) && (res != aLength)) { 38 wchar_t* last_backslash = wcsrchr(aPath, L'\\'); 39 if (last_backslash) { 40 *(last_backslash + 1) = L'\0'; 41 if (wcscat_s(aPath, aLength, kModuleName) == 0) { 42 return true; 43 } 44 } 45 } 46 47 return false; 48 } 49 50 #endif // XP_WIN 51 52 void RegisterRuntimeExceptionModule() { 53 #ifdef XP_WIN 54 # if defined(DEBUG) 55 // In debug builds, disable the crash reporter by default, and allow to 56 // enable it with the MOZ_CRASHREPORTER environment variable. 57 const char* envvar = getenv("MOZ_CRASHREPORTER"); 58 if (!envvar || !*envvar) { 59 return; 60 } 61 # else 62 // In other builds, enable the crash reporter by default, and allow 63 // disabling it with the MOZ_CRASHREPORTER_DISABLE environment variable. 64 const char* envvar = getenv("MOZ_CRASHREPORTER_DISABLE"); 65 if (envvar && *envvar) { 66 return; 67 } 68 # endif 69 70 // If sModulePath is set we have already registerd the module. 71 if (*sModulePath) { 72 return; 73 } 74 75 // If we fail to get the path just return. 76 if (!GetRuntimeExceptionModulePath(sModulePath, kModulePathLength)) { 77 return; 78 } 79 80 if (FAILED(::WerRegisterRuntimeExceptionModule( 81 sModulePath, 82 reinterpret_cast<PVOID>(mozilla::GetGeckoProcessType())))) { 83 // The registration failed null out sModulePath to record this. 84 *sModulePath = L'\0'; 85 return; 86 } 87 #endif // XP_WIN 88 } 89 90 void UnregisterRuntimeExceptionModule() { 91 #ifdef XP_WIN 92 // If sModulePath is set then we have registered the module. 93 if (*sModulePath) { 94 (void)::WerUnregisterRuntimeExceptionModule( 95 sModulePath, reinterpret_cast<PVOID>(mozilla::GetGeckoProcessType())); 96 *sModulePath = L'\0'; 97 } 98 #endif // XP_WIN 99 } 100 101 } // namespace CrashReporter