Revert 269361 "Fix WebURLLoaderImpl::Context leak if a pending r..."
[chromium-blink-merge.git] / components / breakpad / app / hard_error_handler_win.cc
blobcf93adcc3ba5bebce72e8927ebc293e2cf8c1b5d
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/breakpad/app/hard_error_handler_win.h"
7 #if defined(_WIN32_WINNT_WIN8) && _MSC_VER < 1700
8 // The Windows 8 SDK defines FACILITY_VISUALCPP in winerror.h, and in
9 // delayimp.h previous to VS2012.
10 #undef FACILITY_VISUALCPP
11 #endif
12 #include <DelayIMP.h>
13 #include <winternl.h>
15 #include "base/basictypes.h"
16 #include "base/strings/string_util.h"
17 #include "components/breakpad/app/breakpad_client.h"
19 namespace breakpad {
21 namespace {
22 const DWORD kExceptionModuleNotFound = VcppException(ERROR_SEVERITY_ERROR,
23 ERROR_MOD_NOT_FOUND);
24 const DWORD kExceptionEntryPtNotFound = VcppException(ERROR_SEVERITY_ERROR,
25 ERROR_PROC_NOT_FOUND);
26 // This is defined in <ntstatus.h> but we can't include this file here.
27 const DWORD FACILITY_GRAPHICS_KERNEL = 0x1E;
28 const DWORD NT_STATUS_ENTRYPOINT_NOT_FOUND = 0xC0000139;
29 const DWORD NT_STATUS_DLL_NOT_FOUND = 0xC0000135;
31 // We assume that exception codes are NT_STATUS codes.
32 DWORD FacilityFromException(DWORD exception_code) {
33 return (exception_code >> 16) & 0x0FFF;
36 // This is not a generic function. It only works with some |nt_status| values.
37 // Check the strings here http://msdn.microsoft.com/en-us/library/cc704588.aspx
38 // before attempting to use this function.
39 void RaiseHardErrorMsg(long nt_status, const std::string& p1,
40 const std::string& p2) {
41 // If headless just exit silently.
42 if (GetBreakpadClient()->IsRunningUnattended())
43 return;
45 HMODULE ntdll = ::GetModuleHandleA("NTDLL.DLL");
46 wchar_t* msg_template = NULL;
47 size_t count = ::FormatMessage(
48 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS |
49 FORMAT_MESSAGE_FROM_HMODULE,
50 ntdll,
51 nt_status,
52 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
53 reinterpret_cast<wchar_t*>(&msg_template),
55 NULL);
57 if (!count)
58 return;
59 count += p1.size() + p2.size() + 1;
60 base::string16 message;
61 ::wsprintf(WriteInto(&message, count), msg_template, p1.c_str(), p2.c_str());
62 // The MB_SERVICE_NOTIFICATION causes this message to be displayed by
63 // csrss. This means that we are not creating windows or pumping WM messages
64 // in this process.
65 ::MessageBox(NULL, message.c_str(),
66 L"chrome.exe",
67 MB_OK | MB_SERVICE_NOTIFICATION);
68 ::LocalFree(msg_template);
71 void ModuleNotFoundHardError(const EXCEPTION_RECORD* ex_record) {
72 DelayLoadInfo* dli = reinterpret_cast<DelayLoadInfo*>(
73 ex_record->ExceptionInformation[0]);
74 if (!dli->szDll)
75 return;
76 RaiseHardErrorMsg(NT_STATUS_DLL_NOT_FOUND, dli->szDll, std::string());
79 void EntryPointNotFoundHardError(const EXCEPTION_RECORD* ex_record) {
80 DelayLoadInfo* dli = reinterpret_cast<DelayLoadInfo*>(
81 ex_record->ExceptionInformation[0]);
82 if (!dli->dlp.fImportByName)
83 return;
84 if (!dli->dlp.szProcName)
85 return;
86 if (!dli->szDll)
87 return;
88 RaiseHardErrorMsg(NT_STATUS_ENTRYPOINT_NOT_FOUND,
89 dli->dlp.szProcName, dli->szDll);
92 } // namespace
94 bool HardErrorHandler(EXCEPTION_POINTERS* ex_info) {
95 if (!ex_info)
96 return false;
97 if (!ex_info->ExceptionRecord)
98 return false;
100 long exception = ex_info->ExceptionRecord->ExceptionCode;
101 if (exception == kExceptionModuleNotFound) {
102 ModuleNotFoundHardError(ex_info->ExceptionRecord);
103 return true;
104 } else if (exception == kExceptionEntryPtNotFound) {
105 EntryPointNotFoundHardError(ex_info->ExceptionRecord);
106 return true;
107 } else if (FacilityFromException(exception) == FACILITY_GRAPHICS_KERNEL) {
108 #if defined(USE_AURA)
109 RaiseHardErrorMsg(exception, std::string(), std::string());
110 return true;
111 #else
112 return false;
113 #endif
115 return false;
118 } // namespace breakpad