| 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 |