OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/crash/content/app/breakpad_win.h" | 5 #include "components/crash/content/app/breakpad_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <shellapi.h> | 8 #include <shellapi.h> |
9 #include <stddef.h> | 9 #include <stddef.h> |
10 #include <tchar.h> | 10 #include <tchar.h> |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 return profile_type; | 192 return profile_type; |
193 } | 193 } |
194 | 194 |
195 namespace { | 195 namespace { |
196 | 196 |
197 // This callback is used when we want to get a dump without crashing the | 197 // This callback is used when we want to get a dump without crashing the |
198 // process. | 198 // process. |
199 bool DumpDoneCallbackWhenNoCrash(const wchar_t*, const wchar_t*, void*, | 199 bool DumpDoneCallbackWhenNoCrash(const wchar_t*, const wchar_t*, void*, |
200 EXCEPTION_POINTERS* ex_info, | 200 EXCEPTION_POINTERS* ex_info, |
201 MDRawAssertionInfo*, bool succeeded) { | 201 MDRawAssertionInfo*, bool succeeded) { |
202 GetCrashReporterClient()->RecordCrashDumpAttemptResult( | |
203 false /* is_real_crash */, succeeded); | |
204 return true; | 202 return true; |
205 } | 203 } |
206 | 204 |
207 // This callback is executed when the browser process has crashed, after | 205 // This callback is executed when the browser process has crashed, after |
208 // the crash dump has been created. We need to minimize the amount of work | 206 // the crash dump has been created. We need to minimize the amount of work |
209 // done here since we have potentially corrupted process. Our job is to | 207 // done here since we have potentially corrupted process. Our job is to |
210 // spawn another instance of chrome which will show a 'chrome has crashed' | 208 // spawn another instance of chrome which will show a 'chrome has crashed' |
211 // dialog. This code needs to live in the exe and thus has no access to | 209 // dialog. This code needs to live in the exe and thus has no access to |
212 // facilities such as the i18n helpers. | 210 // facilities such as the i18n helpers. |
213 bool DumpDoneCallback(const wchar_t*, const wchar_t*, void*, | 211 bool DumpDoneCallback(const wchar_t*, const wchar_t*, void*, |
214 EXCEPTION_POINTERS* ex_info, | 212 EXCEPTION_POINTERS* ex_info, |
215 MDRawAssertionInfo*, bool succeeded) { | 213 MDRawAssertionInfo*, bool succeeded) { |
216 GetCrashReporterClient()->RecordCrashDumpAttemptResult( | |
217 true /* is_real_crash */, succeeded); | |
218 // Check if the exception is one of the kind which would not be solved | 214 // Check if the exception is one of the kind which would not be solved |
219 // by simply restarting chrome. In this case we show a message box with | 215 // by simply restarting chrome. In this case we show a message box with |
220 // and exit silently. Remember that chrome is in a crashed state so we | 216 // and exit silently. Remember that chrome is in a crashed state so we |
221 // can't show our own UI from this process. | 217 // can't show our own UI from this process. |
222 if (HardErrorHandler(ex_info)) | 218 if (HardErrorHandler(ex_info)) |
223 return true; | 219 return true; |
224 | 220 |
225 if (!GetCrashReporterClient()->AboutToRestart()) | 221 if (!GetCrashReporterClient()->AboutToRestart()) |
226 return true; | 222 return true; |
227 | 223 |
(...skipping 11 matching lines...) Expand all Loading... |
239 } | 235 } |
240 | 236 |
241 // flag to indicate that we are already handling an exception. | 237 // flag to indicate that we are already handling an exception. |
242 volatile LONG handling_exception = 0; | 238 volatile LONG handling_exception = 0; |
243 | 239 |
244 // This callback is used when there is no crash. Note: Unlike the | 240 // This callback is used when there is no crash. Note: Unlike the |
245 // |FilterCallback| below this does not do dupe detection. It is upto the caller | 241 // |FilterCallback| below this does not do dupe detection. It is upto the caller |
246 // to implement it. | 242 // to implement it. |
247 bool FilterCallbackWhenNoCrash( | 243 bool FilterCallbackWhenNoCrash( |
248 void*, EXCEPTION_POINTERS*, MDRawAssertionInfo*) { | 244 void*, EXCEPTION_POINTERS*, MDRawAssertionInfo*) { |
249 GetCrashReporterClient()->RecordCrashDumpAttempt(false); | |
250 return true; | 245 return true; |
251 } | 246 } |
252 | 247 |
253 // This callback is executed when the Chrome process has crashed and *before* | 248 // This callback is executed when the Chrome process has crashed and *before* |
254 // the crash dump is created. To prevent duplicate crash reports we | 249 // the crash dump is created. To prevent duplicate crash reports we |
255 // make every thread calling this method, except the very first one, | 250 // make every thread calling this method, except the very first one, |
256 // go to sleep. | 251 // go to sleep. |
257 bool FilterCallback(void*, EXCEPTION_POINTERS*, MDRawAssertionInfo*) { | 252 bool FilterCallback(void*, EXCEPTION_POINTERS*, MDRawAssertionInfo*) { |
258 // Capture every thread except the first one in the sleep. We don't | 253 // Capture every thread except the first one in the sleep. We don't |
259 // want multiple threads to concurrently report exceptions. | 254 // want multiple threads to concurrently report exceptions. |
260 if (::InterlockedCompareExchange(&handling_exception, 1, 0) == 1) { | 255 if (::InterlockedCompareExchange(&handling_exception, 1, 0) == 1) { |
261 ::Sleep(INFINITE); | 256 ::Sleep(INFINITE); |
262 } | 257 } |
263 GetCrashReporterClient()->RecordCrashDumpAttempt(true); | |
264 return true; | 258 return true; |
265 } | 259 } |
266 | 260 |
267 // Previous unhandled filter. Will be called if not null when we | 261 // Previous unhandled filter. Will be called if not null when we |
268 // intercept a crash. | 262 // intercept a crash. |
269 LPTOP_LEVEL_EXCEPTION_FILTER previous_filter = NULL; | 263 LPTOP_LEVEL_EXCEPTION_FILTER previous_filter = NULL; |
270 | 264 |
271 // Exception filter used when breakpad is not enabled. We just display | 265 // Exception filter used when breakpad is not enabled. We just display |
272 // the "Do you want to restart" message and then we call the previous filter. | 266 // the "Do you want to restart" message and then we call the previous filter. |
273 long WINAPI ChromeExceptionFilter(EXCEPTION_POINTERS* info) { | 267 long WINAPI ChromeExceptionFilter(EXCEPTION_POINTERS* info) { |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 callback = &DumpDoneCallback; | 568 callback = &DumpDoneCallback; |
575 default_filter = &ChromeExceptionFilter; | 569 default_filter = &ChromeExceptionFilter; |
576 } else if (process_type == L"service") { | 570 } else if (process_type == L"service") { |
577 callback = &DumpDoneCallback; | 571 callback = &DumpDoneCallback; |
578 default_filter = &ServiceExceptionFilter; | 572 default_filter = &ServiceExceptionFilter; |
579 } | 573 } |
580 | 574 |
581 if (GetCrashReporterClient()->ShouldCreatePipeName(process_type)) | 575 if (GetCrashReporterClient()->ShouldCreatePipeName(process_type)) |
582 InitPipeNameEnvVar(is_per_user_install); | 576 InitPipeNameEnvVar(is_per_user_install); |
583 | 577 |
584 if (process_type == L"browser") | |
585 GetCrashReporterClient()->InitBrowserCrashDumpsRegKey(); | |
586 | |
587 std::unique_ptr<base::Environment> env(base::Environment::Create()); | 578 std::unique_ptr<base::Environment> env(base::Environment::Create()); |
588 std::string pipe_name_ascii; | 579 std::string pipe_name_ascii; |
589 if (!env->GetVar(kPipeNameVar, &pipe_name_ascii)) { | 580 if (!env->GetVar(kPipeNameVar, &pipe_name_ascii)) { |
590 // Breakpad is not enabled. Configuration is managed or the user | 581 // Breakpad is not enabled. Configuration is managed or the user |
591 // did not allow Google Update to send crashes. We need to use | 582 // did not allow Google Update to send crashes. We need to use |
592 // our default crash handler instead, but only for the | 583 // our default crash handler instead, but only for the |
593 // browser/service processes. | 584 // browser/service processes. |
594 if (default_filter) | 585 if (default_filter) |
595 InitDefaultCrashCallback(default_filter); | 586 InitDefaultCrashCallback(default_filter); |
596 return; | 587 return; |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 extern "C" void __declspec(dllexport) __cdecl | 730 extern "C" void __declspec(dllexport) __cdecl |
740 UnregisterNonABICompliantCodeRange(void* start) { | 731 UnregisterNonABICompliantCodeRange(void* start) { |
741 ExceptionHandlerRecord* record = | 732 ExceptionHandlerRecord* record = |
742 reinterpret_cast<ExceptionHandlerRecord*>(start); | 733 reinterpret_cast<ExceptionHandlerRecord*>(start); |
743 | 734 |
744 CHECK(RtlDeleteFunctionTable(&record->runtime_function)); | 735 CHECK(RtlDeleteFunctionTable(&record->runtime_function)); |
745 } | 736 } |
746 #endif | 737 #endif |
747 | 738 |
748 } // namespace breakpad | 739 } // namespace breakpad |
OLD | NEW |