diff options
Diffstat (limited to 'mozglue/misc/RuntimeExceptionModule.cpp')
-rw-r--r-- | mozglue/misc/RuntimeExceptionModule.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/mozglue/misc/RuntimeExceptionModule.cpp b/mozglue/misc/RuntimeExceptionModule.cpp new file mode 100644 index 0000000000..6b7e55c5e9 --- /dev/null +++ b/mozglue/misc/RuntimeExceptionModule.cpp @@ -0,0 +1,111 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "RuntimeExceptionModule.h" + +#include <cstdint> + +#include "mozilla/ProcessType.h" + +#if defined(XP_WIN) +# include <windows.h> +# if defined(__MINGW32__) || defined(__MINGW64__) +// Add missing constants and types for mingw builds +# define HREPORT HANDLE +# define PWER_SUBMIT_RESULT WER_SUBMIT_RESULT* +# define WER_MAX_PREFERRED_MODULES_BUFFER (256) +# endif // defined(__MINGW32__) || defined(__MINGW64__) +# include <werapi.h> // For WerRegisterRuntimeExceptionModule() +# include <stdlib.h> + +# include "mozilla/mozalloc_oom.h" +# include "mozilla/Unused.h" + +using mozilla::Unused; +#endif + +namespace CrashReporter { + +#ifdef XP_WIN + +struct InProcessWindowsErrorReportingData { + uint32_t mProcessType; + size_t* mOOMAllocationSizePtr; +}; + +static InProcessWindowsErrorReportingData gInProcessWerData; +const static size_t kModulePathLength = MAX_PATH + 1; +static wchar_t sModulePath[kModulePathLength]; + +bool GetRuntimeExceptionModulePath(wchar_t* aPath, const size_t aLength) { + const wchar_t* kModuleName = L"mozwer.dll"; + DWORD res = ::GetModuleFileNameW(nullptr, aPath, aLength); + if ((res > 0) && (res != aLength)) { + wchar_t* last_backslash = wcsrchr(aPath, L'\\'); + if (last_backslash) { + *(last_backslash + 1) = L'\0'; + if (wcscat_s(aPath, aLength, kModuleName) == 0) { + return true; + } + } + } + + return false; +} + +#endif // XP_WIN + +void RegisterRuntimeExceptionModule() { +#ifdef XP_WIN +# if defined(DEBUG) + // In debug builds, disable the crash reporter by default, and allow to + // enable it with the MOZ_CRASHREPORTER environment variable. + const char* envvar = getenv("MOZ_CRASHREPORTER"); + if (!envvar || !*envvar) { + return; + } +# else + // In other builds, enable the crash reporter by default, and allow + // disabling it with the MOZ_CRASHREPORTER_DISABLE environment variable. + const char* envvar = getenv("MOZ_CRASHREPORTER_DISABLE"); + if (envvar && *envvar) { + return; + } +# endif + + // If sModulePath is set we have already registerd the module. + if (*sModulePath) { + return; + } + + // If we fail to get the path just return. + if (!GetRuntimeExceptionModulePath(sModulePath, kModulePathLength)) { + return; + } + + gInProcessWerData.mProcessType = mozilla::GetGeckoProcessType(); + gInProcessWerData.mOOMAllocationSizePtr = &gOOMAllocationSize; + if (FAILED(::WerRegisterRuntimeExceptionModule(sModulePath, + &gInProcessWerData))) { + // The registration failed null out sModulePath to record this. + *sModulePath = L'\0'; + return; + } +#endif // XP_WIN +} + +void UnregisterRuntimeExceptionModule() { +#ifdef XP_WIN + // If sModulePath is set then we have registered the module. + if (*sModulePath) { + Unused << ::WerUnregisterRuntimeExceptionModule(sModulePath, + &gInProcessWerData); + *sModulePath = L'\0'; + } +#endif // XP_WIN +} + +} // namespace CrashReporter |