This source file includes following definitions.
- FacilityFromException
- RaiseHardErrorMsg
- ModuleNotFoundHardError
- EntryPointNotFoundHardError
- HardErrorHandler
#include "components/breakpad/app/hard_error_handler_win.h"
#if defined(_WIN32_WINNT_WIN8) && _MSC_VER < 1700
#undef FACILITY_VISUALCPP
#endif
#include <DelayIMP.h>
#include <winternl.h>
#include "base/basictypes.h"
#include "base/strings/string_util.h"
#include "components/breakpad/app/breakpad_client.h"
namespace breakpad {
namespace {
const DWORD kExceptionModuleNotFound = VcppException(ERROR_SEVERITY_ERROR,
ERROR_MOD_NOT_FOUND);
const DWORD kExceptionEntryPtNotFound = VcppException(ERROR_SEVERITY_ERROR,
ERROR_PROC_NOT_FOUND);
const DWORD FACILITY_GRAPHICS_KERNEL = 0x1E;
const DWORD NT_STATUS_ENTRYPOINT_NOT_FOUND = 0xC0000139;
const DWORD NT_STATUS_DLL_NOT_FOUND = 0xC0000135;
DWORD FacilityFromException(DWORD exception_code) {
return (exception_code >> 16) & 0x0FFF;
}
void RaiseHardErrorMsg(long nt_status, const std::string& p1,
const std::string& p2) {
if (GetBreakpadClient()->IsRunningUnattended())
return;
HMODULE ntdll = ::GetModuleHandleA("NTDLL.DLL");
wchar_t* msg_template = NULL;
size_t count = ::FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_HMODULE,
ntdll,
nt_status,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<wchar_t*>(&msg_template),
0,
NULL);
if (!count)
return;
count += p1.size() + p2.size() + 1;
base::string16 message;
::wsprintf(WriteInto(&message, count), msg_template, p1.c_str(), p2.c_str());
::MessageBox(NULL, message.c_str(),
L"chrome.exe",
MB_OK | MB_SERVICE_NOTIFICATION);
::LocalFree(msg_template);
}
void ModuleNotFoundHardError(const EXCEPTION_RECORD* ex_record) {
DelayLoadInfo* dli = reinterpret_cast<DelayLoadInfo*>(
ex_record->ExceptionInformation[0]);
if (!dli->szDll)
return;
RaiseHardErrorMsg(NT_STATUS_DLL_NOT_FOUND, dli->szDll, std::string());
}
void EntryPointNotFoundHardError(const EXCEPTION_RECORD* ex_record) {
DelayLoadInfo* dli = reinterpret_cast<DelayLoadInfo*>(
ex_record->ExceptionInformation[0]);
if (!dli->dlp.fImportByName)
return;
if (!dli->dlp.szProcName)
return;
if (!dli->szDll)
return;
RaiseHardErrorMsg(NT_STATUS_ENTRYPOINT_NOT_FOUND,
dli->dlp.szProcName, dli->szDll);
}
}
bool HardErrorHandler(EXCEPTION_POINTERS* ex_info) {
if (!ex_info)
return false;
if (!ex_info->ExceptionRecord)
return false;
long exception = ex_info->ExceptionRecord->ExceptionCode;
if (exception == kExceptionModuleNotFound) {
ModuleNotFoundHardError(ex_info->ExceptionRecord);
return true;
} else if (exception == kExceptionEntryPtNotFound) {
EntryPointNotFoundHardError(ex_info->ExceptionRecord);
return true;
} else if (FacilityFromException(exception) == FACILITY_GRAPHICS_KERNEL) {
#if defined(USE_AURA)
RaiseHardErrorMsg(exception, std::string(), std::string());
return true;
#else
return false;
#endif
}
return false;
}
}