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

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

Issue 1733021: Add an ExceptionBarrier around outbound calls to patched methods in IE. In so... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 8 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 "base/lock.h"
10 #include "breakpad/src/client/windows/handler/exception_handler.h" 11 #include "breakpad/src/client/windows/handler/exception_handler.h"
11 12
12 // TODO(joshia): factor out common code with chrome used for crash reporting 13 // TODO(joshia): factor out common code with chrome used for crash reporting
13 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\"; 14 const wchar_t kGoogleUpdatePipeName[] = L"\\\\.\\pipe\\GoogleCrashServices\\";
14 static google_breakpad::ExceptionHandler * g_breakpad = NULL; 15 static google_breakpad::ExceptionHandler * g_breakpad = NULL;
16 static Lock g_breakpad_lock;
Sigurður Ásgeirsson 2010/04/28 01:54:10 comment on what this lock protects, please. I'm no
robertshield 2010/04/28 10:45:57 Will add a comment in another patch. Generally: th
15 17
16 // These minidump flag combinations have been tested safe agains the 18 // These minidump flag combinations have been tested safe agains the
17 // DbgHelp.dll version that ships with Windows XP SP2. 19 // DbgHelp.dll version that ships with Windows XP SP2.
18 const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>( 20 const MINIDUMP_TYPE kSmallDumpType = static_cast<MINIDUMP_TYPE>(
19 MiniDumpWithProcessThreadData | // Get PEB and TEB. 21 MiniDumpWithProcessThreadData | // Get PEB and TEB.
20 MiniDumpWithUnloadedModules); // Get unloaded modules when available. 22 MiniDumpWithUnloadedModules); // Get unloaded modules when available.
21 23
22 const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>( 24 const MINIDUMP_TYPE kLargerDumpType = static_cast<MINIDUMP_TYPE>(
23 MiniDumpWithProcessThreadData | // Get PEB and TEB. 25 MiniDumpWithProcessThreadData | // Get PEB and TEB.
24 MiniDumpWithUnloadedModules | // Get unloaded modules when available. 26 MiniDumpWithUnloadedModules | // Get unloaded modules when available.
(...skipping 15 matching lines...) Expand all
40 #pragma code_seg(pop) 42 #pragma code_seg(pop)
41 43
42 // Place code in .text$veh_m. 44 // Place code in .text$veh_m.
43 #pragma code_seg(push, ".text$vm") 45 #pragma code_seg(push, ".text$vm")
44 #include "chrome_frame/crash_reporting/vectored_handler-impl.h" 46 #include "chrome_frame/crash_reporting/vectored_handler-impl.h"
45 47
46 // Use Win32 API; use breakpad for dumps; checks for single (current) module. 48 // Use Win32 API; use breakpad for dumps; checks for single (current) module.
47 class CrashHandlerTraits : public Win32VEHTraits, 49 class CrashHandlerTraits : public Win32VEHTraits,
48 public ModuleOfInterestWithExcludedRegion { 50 public ModuleOfInterestWithExcludedRegion {
49 public: 51 public:
50 CrashHandlerTraits() : breakpad_(NULL) {} 52 CrashHandlerTraits() {}
51 void Init(google_breakpad::ExceptionHandler* breakpad) { 53
52 breakpad_ = breakpad; 54 // Note that breakpad_lock must be held when this is called.
55 void Init(google_breakpad::ExceptionHandler* breakpad, Lock* breakpad_lock) {
56 DCHECK(breakpad);
57 DCHECK(breakpad_lock);
58 breakpad_lock->AssertAcquired();
59
53 Win32VEHTraits::InitializeIgnoredBlocks(); 60 Win32VEHTraits::InitializeIgnoredBlocks();
54 ModuleOfInterestWithExcludedRegion::SetCurrentModule(); 61 ModuleOfInterestWithExcludedRegion::SetCurrentModule();
55 // Pointers to static (non-extern) functions take the address of the 62 // Pointers to static (non-extern) functions take the address of the
56 // function's first byte, as opposed to an entry in the compiler generated 63 // function's first byte, as opposed to an entry in the compiler generated
57 // JMP table. In release builds /OPT:REF wipes away the JMP table, but debug 64 // JMP table. In release builds /OPT:REF wipes away the JMP table, but debug
58 // builds are not so lucky. 65 // builds are not so lucky.
59 ModuleOfInterestWithExcludedRegion::SetExcludedRegion(&veh_segment_start, 66 ModuleOfInterestWithExcludedRegion::SetExcludedRegion(&veh_segment_start,
60 &veh_segment_end); 67 &veh_segment_end);
61 } 68 }
62 69
63 void Shutdown() { 70 void Shutdown() {
64 breakpad_ = 0;
65 } 71 }
66 72
67 inline bool WriteDump(EXCEPTION_POINTERS* p) { 73 inline bool WriteDump(EXCEPTION_POINTERS* p) {
68 return breakpad_->WriteMinidumpForException(p); 74 return WriteMinidumpForException(p);
69 } 75 }
70
71 private:
72 google_breakpad::ExceptionHandler* breakpad_;
73 }; 76 };
74 77
75 class CrashHandler { 78 class CrashHandler {
76 public: 79 public:
77 CrashHandler() : veh_id_(NULL), handler_(&crash_api_) {} 80 CrashHandler() : veh_id_(NULL), handler_(&crash_api_) {}
78 bool Init(google_breakpad::ExceptionHandler* breakpad); 81
82 // Note that breakpad_lock is used to protect accesses to breakpad and must
83 // be held when Init() is called.
84 bool Init(google_breakpad::ExceptionHandler* breakpad, Lock* breakpad_lock);
85
79 void Shutdown(); 86 void Shutdown();
80 private: 87 private:
81 VectoredHandlerT<CrashHandlerTraits> handler_; 88 VectoredHandlerT<CrashHandlerTraits> handler_;
82 CrashHandlerTraits crash_api_; 89 CrashHandlerTraits crash_api_;
83 void* veh_id_; 90 void* veh_id_;
84 91
85 static LONG WINAPI VectoredHandlerEntryPoint(EXCEPTION_POINTERS* exptrs); 92 static LONG WINAPI VectoredHandlerEntryPoint(EXCEPTION_POINTERS* exptrs);
86 }; 93 };
87 94
88 static CrashHandler g_crash_handler; 95 static CrashHandler g_crash_handler;
89 96
90 // Turn off FPO optimization, so ::RtlCaptureStackBackTrace returns sane result. 97 // Turn off FPO optimization, so ::RtlCaptureStackBackTrace returns sane result.
91 #pragma optimize("y", off) 98 #pragma optimize("y", off)
92 LONG WINAPI CrashHandler::VectoredHandlerEntryPoint( 99 LONG WINAPI CrashHandler::VectoredHandlerEntryPoint(
93 EXCEPTION_POINTERS* exptrs) { 100 EXCEPTION_POINTERS* exptrs) {
94 return g_crash_handler.handler_.Handler(exptrs); 101 return g_crash_handler.handler_.Handler(exptrs);
95 } 102 }
96 #pragma optimize("y", on) 103 #pragma optimize("y", on)
97 104
98 #pragma code_seg(pop) 105 #pragma code_seg(pop)
99 106
100 bool CrashHandler::Init(google_breakpad::ExceptionHandler* breakpad) { 107 bool CrashHandler::Init(google_breakpad::ExceptionHandler* breakpad,
108 Lock* breakpad_lock) {
109 DCHECK(breakpad);
110 DCHECK(breakpad_lock);
111 breakpad_lock->AssertAcquired();
112
101 if (veh_id_) 113 if (veh_id_)
102 return true; 114 return true;
103 115
104 void* id = ::AddVectoredExceptionHandler(FALSE, &VectoredHandlerEntryPoint); 116 void* id = ::AddVectoredExceptionHandler(FALSE, &VectoredHandlerEntryPoint);
105 if (id != NULL) { 117 if (id != NULL) {
106 veh_id_ = id; 118 veh_id_ = id;
107 crash_api_.Init(breakpad); 119 crash_api_.Init(breakpad, breakpad_lock);
108 return true; 120 return true;
109 } 121 }
110 122
111 return false; 123 return false;
112 } 124 }
113 125
114 void CrashHandler::Shutdown() { 126 void CrashHandler::Shutdown() {
115 if (veh_id_) { 127 if (veh_id_) {
116 ::RemoveVectoredExceptionHandler(veh_id_); 128 ::RemoveVectoredExceptionHandler(veh_id_);
117 veh_id_ = NULL; 129 veh_id_ = NULL;
118 } 130 }
119 131
120 crash_api_.Shutdown(); 132 crash_api_.Shutdown();
121 } 133 }
122 134
123 std::wstring GetCrashServerPipeName(const std::wstring& user_sid) { 135 std::wstring GetCrashServerPipeName(const std::wstring& user_sid) {
124 std::wstring pipe_name = kGoogleUpdatePipeName; 136 std::wstring pipe_name = kGoogleUpdatePipeName;
125 pipe_name += user_sid; 137 pipe_name += user_sid;
126 return pipe_name; 138 return pipe_name;
127 } 139 }
128 140
129 bool InitializeVectoredCrashReportingWithPipeName( 141 bool InitializeVectoredCrashReportingWithPipeName(
130 bool full_dump, 142 bool full_dump,
131 const wchar_t* pipe_name, 143 const wchar_t* pipe_name,
132 const std::wstring& dump_path, 144 const std::wstring& dump_path,
133 google_breakpad::CustomClientInfo* client_info) { 145 google_breakpad::CustomClientInfo* client_info) {
146 AutoLock lock(g_breakpad_lock);
134 if (g_breakpad) 147 if (g_breakpad)
135 return true; 148 return true;
136 149
137 if (dump_path.empty()) { 150 if (dump_path.empty()) {
138 return false; 151 return false;
139 } 152 }
140 153
141 // TODO(siggi): Consider switching to kSmallerDumpType post-beta. 154 // TODO(siggi): Consider switching to kSmallerDumpType post-beta.
142 MINIDUMP_TYPE dump_type = full_dump ? kFullDumpType : kLargerDumpType; 155 MINIDUMP_TYPE dump_type = full_dump ? kFullDumpType : kLargerDumpType;
143 g_breakpad = new google_breakpad::ExceptionHandler( 156 g_breakpad = new google_breakpad::ExceptionHandler(
144 dump_path, NULL, NULL, NULL, 157 dump_path, NULL, NULL, NULL,
145 google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER | 158 google_breakpad::ExceptionHandler::HANDLER_INVALID_PARAMETER |
146 google_breakpad::ExceptionHandler::HANDLER_PURECALL, dump_type, 159 google_breakpad::ExceptionHandler::HANDLER_PURECALL, dump_type,
147 pipe_name, client_info); 160 pipe_name, client_info);
148 161
149 if (!g_breakpad) 162 if (!g_breakpad)
150 return false; 163 return false;
151 164
152 if (!g_crash_handler.Init(g_breakpad)) { 165 if (!g_crash_handler.Init(g_breakpad, &g_breakpad_lock)) {
153 delete g_breakpad; 166 delete g_breakpad;
154 g_breakpad = NULL; 167 g_breakpad = NULL;
155 return false; 168 return false;
156 } 169 }
157 170
158 return true; 171 return true;
159 } 172 }
160 173
161 bool InitializeVectoredCrashReporting( 174 bool InitializeVectoredCrashReporting(
162 bool full_dump, 175 bool full_dump,
163 const wchar_t* user_sid, 176 const wchar_t* user_sid,
164 const std::wstring& dump_path, 177 const std::wstring& dump_path,
165 google_breakpad::CustomClientInfo* client_info) { 178 google_breakpad::CustomClientInfo* client_info) {
166 DCHECK(user_sid); 179 DCHECK(user_sid);
167 DCHECK(client_info); 180 DCHECK(client_info);
168 181
169 std::wstring pipe_name = GetCrashServerPipeName(user_sid); 182 std::wstring pipe_name = GetCrashServerPipeName(user_sid);
170 183
171 return InitializeVectoredCrashReportingWithPipeName(full_dump, 184 return InitializeVectoredCrashReportingWithPipeName(full_dump,
172 pipe_name.c_str(), 185 pipe_name.c_str(),
173 dump_path, 186 dump_path,
174 client_info); 187 client_info);
175 } 188 }
176 189
177 bool ShutdownVectoredCrashReporting() { 190 bool ShutdownVectoredCrashReporting() {
178 g_crash_handler.Shutdown(); 191 g_crash_handler.Shutdown();
192 AutoLock lock(g_breakpad_lock);
179 delete g_breakpad; 193 delete g_breakpad;
180 g_breakpad = NULL; 194 g_breakpad = NULL;
181 return true; 195 return true;
182 } 196 }
197
198 bool WriteMinidumpForException(EXCEPTION_POINTERS* p) {
199 AutoLock lock(g_breakpad_lock);
200 bool success = false;
201 if (g_breakpad) {
202 success = g_breakpad->WriteMinidumpForException(p);
203 }
204 return success;
205 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698