| OLD | NEW |
| 1 | 1 |
| 2 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 2 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 3 // Use of this source code is governed by a BSD-style license that can be | 3 // Use of this source code is governed by a BSD-style license that can be |
| 4 // found in the LICENSE file. | 4 // found in the LICENSE file. |
| 5 | 5 |
| 6 // crash_report.cc : Implementation crash reporting. | 6 // crash_report.cc : Implementation crash reporting. |
| 7 #include "chrome_frame/crash_reporting/crash_report.h" | 7 #include "chrome_frame/crash_reporting/crash_report.h" |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "breakpad/src/client/windows/handler/exception_handler.h" | 10 #include "breakpad/src/client/windows/handler/exception_handler.h" |
| 11 #include "chrome_frame/crash_reporting/vectored_handler.h" | |
| 12 | 11 |
| 13 // TODO(joshia): factor out common code with chrome used for crash reporting | 12 // TODO(joshia): factor out common code with chrome used for crash reporting |
| 14 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\"; | 13 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\"; |
| 15 google_breakpad::ExceptionHandler* g_breakpad = NULL; | 14 static google_breakpad::ExceptionHandler * g_breakpad = NULL; |
| 16 | 15 |
| 17 Win32VEHTraits::CodeBlock Win32VEHTraits::IgnoreExceptions[kIgnoreEntries] = { | 16 #pragma code_seg(push, ".text$va") |
| 18 { "kernel32.dll", "IsBadReadPtr", 0, 100, NULL }, | 17 static void veh_segment_start() {} |
| 19 { "kernel32.dll", "IsBadWritePtr", 0, 100, NULL }, | 18 #pragma code_seg(pop) |
| 20 { "kernel32.dll", "IsBadStringPtrA", 0, 100, NULL }, | 19 |
| 21 { "kernel32.dll", "IsBadStringPtrW", 0, 100, NULL }, | 20 #pragma code_seg(push, ".text$vz") |
| 21 static void veh_segment_end() {} |
| 22 #pragma code_seg(pop) |
| 23 |
| 24 // Place code in .text$veh_m. |
| 25 #pragma code_seg(push, ".text$vm") |
| 26 #include "chrome_frame/crash_reporting/vectored_handler-impl.h" |
| 27 |
| 28 // Use Win32 API; use breakpad for dumps; checks for single (current) module. |
| 29 class CrashHandlerTraits : public Win32VEHTraits, |
| 30 public ModuleOfInterestWithExcludedRegion { |
| 31 public: |
| 32 CrashHandlerTraits() : breakpad_(NULL) {} |
| 33 void Init(google_breakpad::ExceptionHandler* breakpad) { |
| 34 breakpad_ = breakpad; |
| 35 Win32VEHTraits::InitializeIgnoredBlocks(); |
| 36 ModuleOfInterestWithExcludedRegion::SetCurrentModule(); |
| 37 // Pointers to static (non-extern) functions take the address of the |
| 38 // function's first byte, as opposed to an entry in the compiler generated |
| 39 // JMP table. In release builds /OPT:REF wipes away the JMP table, but debug |
| 40 // builds are not so lucky. |
| 41 ModuleOfInterestWithExcludedRegion::SetExcludedRegion(&veh_segment_start, |
| 42 &veh_segment_end); |
| 43 } |
| 44 |
| 45 void Shutdown() { |
| 46 breakpad_ = 0; |
| 47 } |
| 48 |
| 49 inline bool WriteDump(EXCEPTION_POINTERS* p) { |
| 50 return breakpad_->WriteMinidumpForException(p); |
| 51 } |
| 52 |
| 53 private: |
| 54 google_breakpad::ExceptionHandler* breakpad_; |
| 22 }; | 55 }; |
| 23 | 56 |
| 57 class CrashHandler { |
| 58 public: |
| 59 CrashHandler() : veh_id_(NULL), handler_(&crash_api_) {} |
| 60 bool Init(google_breakpad::ExceptionHandler* breakpad); |
| 61 void Shutdown(); |
| 62 private: |
| 63 VectoredHandlerT<CrashHandlerTraits> handler_; |
| 64 CrashHandlerTraits crash_api_; |
| 65 void* veh_id_; |
| 66 |
| 67 static LONG WINAPI VectoredHandlerEntryPoint(EXCEPTION_POINTERS* exptrs); |
| 68 }; |
| 69 |
| 70 static CrashHandler g_crash_handler; |
| 71 |
| 72 LONG WINAPI CrashHandler::VectoredHandlerEntryPoint( |
| 73 EXCEPTION_POINTERS* exptrs) { |
| 74 return g_crash_handler.handler_.Handler(exptrs); |
| 75 } |
| 76 #pragma code_seg(pop) |
| 77 |
| 78 bool CrashHandler::Init(google_breakpad::ExceptionHandler* breakpad) { |
| 79 if (veh_id_) |
| 80 return true; |
| 81 |
| 82 void* id = ::AddVectoredExceptionHandler(FALSE, &VectoredHandlerEntryPoint); |
| 83 if (id != NULL) { |
| 84 veh_id_ = id; |
| 85 crash_api_.Init(breakpad); |
| 86 return true; |
| 87 } |
| 88 |
| 89 return false; |
| 90 } |
| 91 |
| 92 void CrashHandler::Shutdown() { |
| 93 if (veh_id_) { |
| 94 ::RemoveVectoredExceptionHandler(veh_id_); |
| 95 veh_id_ = NULL; |
| 96 } |
| 97 |
| 98 crash_api_.Shutdown(); |
| 99 } |
| 100 |
| 24 std::wstring GetCrashServerPipeName(const std::wstring& user_sid) { | 101 std::wstring GetCrashServerPipeName(const std::wstring& user_sid) { |
| 25 std::wstring pipe_name = kGoogleUpdatePipeName; | 102 std::wstring pipe_name = kGoogleUpdatePipeName; |
| 26 pipe_name += user_sid; | 103 pipe_name += user_sid; |
| 27 return pipe_name; | 104 return pipe_name; |
| 28 } | 105 } |
| 29 | 106 |
| 30 bool InitializeVectoredCrashReportingWithPipeName( | 107 bool InitializeVectoredCrashReportingWithPipeName( |
| 31 bool full_dump, | 108 bool full_dump, |
| 32 const wchar_t* pipe_name, | 109 const wchar_t* pipe_name, |
| 33 const std::wstring& dump_path, | 110 const std::wstring& dump_path, |
| 34 google_breakpad::CustomClientInfo* client_info) { | 111 google_breakpad::CustomClientInfo* client_info) { |
| 35 if (g_breakpad) | 112 if (g_breakpad) |
| 36 return true; | 113 return true; |
| 37 | 114 |
| 38 if (dump_path.empty()) { | 115 if (dump_path.empty()) { |
| 39 return false; | 116 return false; |
| 40 } | 117 } |
| 41 | 118 |
| 42 MINIDUMP_TYPE dump_type = full_dump ? MiniDumpWithFullMemory : MiniDumpNormal; | 119 MINIDUMP_TYPE dump_type = full_dump ? MiniDumpWithFullMemory : MiniDumpNormal; |
| 43 g_breakpad = new google_breakpad::ExceptionHandler( | 120 g_breakpad = new google_breakpad::ExceptionHandler( |
| 44 dump_path, NULL, NULL, NULL, | 121 dump_path, NULL, NULL, NULL, |
| 45 google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER | | 122 google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER | |
| 46 google_breakpad::ExceptionHandler::HANDLER_PURECALL, dump_type, | 123 google_breakpad::ExceptionHandler::HANDLER_PURECALL, dump_type, |
| 47 pipe_name, client_info); | 124 pipe_name, client_info); |
| 48 | 125 |
| 49 if (g_breakpad) { | 126 if (!g_breakpad) |
| 50 // Find current module boundaries. | 127 return false; |
| 51 const void* start = &__ImageBase; | 128 |
| 52 const char* s = reinterpret_cast<const char*>(start); | 129 if (!g_crash_handler.Init(g_breakpad)) { |
| 53 const IMAGE_NT_HEADERS32* nt = reinterpret_cast<const IMAGE_NT_HEADERS32*> | 130 delete g_breakpad; |
| 54 (s + __ImageBase.e_lfanew); | 131 g_breakpad = NULL; |
| 55 const void* end = s + nt->OptionalHeader.SizeOfImage; | 132 return false; |
| 56 VectoredHandler::Register(start, end); | |
| 57 } | 133 } |
| 58 | 134 |
| 59 return g_breakpad != NULL; | 135 return true; |
| 60 } | 136 } |
| 61 | 137 |
| 62 bool InitializeVectoredCrashReporting( | 138 bool InitializeVectoredCrashReporting( |
| 63 bool full_dump, | 139 bool full_dump, |
| 64 const wchar_t* user_sid, | 140 const wchar_t* user_sid, |
| 65 const std::wstring& dump_path, | 141 const std::wstring& dump_path, |
| 66 google_breakpad::CustomClientInfo* client_info) { | 142 google_breakpad::CustomClientInfo* client_info) { |
| 67 DCHECK(user_sid); | 143 DCHECK(user_sid); |
| 68 DCHECK(client_info); | 144 DCHECK(client_info); |
| 69 | 145 |
| 70 std::wstring pipe_name = GetCrashServerPipeName(user_sid); | 146 std::wstring pipe_name = GetCrashServerPipeName(user_sid); |
| 71 | 147 |
| 72 return InitializeVectoredCrashReportingWithPipeName(full_dump, | 148 return InitializeVectoredCrashReportingWithPipeName(full_dump, |
| 73 pipe_name.c_str(), | 149 pipe_name.c_str(), |
| 74 dump_path, | 150 dump_path, |
| 75 client_info); | 151 client_info); |
| 76 } | 152 } |
| 77 | 153 |
| 78 bool ShutdownVectoredCrashReporting() { | 154 bool ShutdownVectoredCrashReporting() { |
| 79 VectoredHandler::Unregister(); | 155 g_crash_handler.Shutdown(); |
| 80 delete g_breakpad; | 156 delete g_breakpad; |
| 81 g_breakpad = NULL; | 157 g_breakpad = NULL; |
| 82 return true; | 158 return true; |
| 83 } | 159 } |
| OLD | NEW |