Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: chrome_frame/crash_reporting/crash_report.cc

Issue 557021: Prevent excessive crash reporting due stack overflow (due exception in SEH fi... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698