blob: 6fb5480104eeb7e7fed5b2d5df35378e11a6272c [file] [log] [blame]
[email protected]219d1a62010-04-28 00:45:081// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4//
5// A class to make it easy to tag exception propagation boundaries and
6// get crash reports of exceptions that pass over same.
7#include "chrome_frame/exception_barrier.h"
8
[email protected]72354312010-05-01 02:10:069#include "chrome_frame/crash_reporting/vectored_handler-impl.h"
10#include "chrome_frame/crash_reporting/crash_report.h"
11
[email protected]219d1a62010-04-28 00:45:0812enum {
13 // Flag set by exception handling machinery when unwinding
14 EH_UNWINDING = 0x00000002
15};
16
[email protected]72354312010-05-01 02:10:0617bool ExceptionBarrierConfig::s_enabled_ = false;
18
19ExceptionBarrierCustomHandler::CustomExceptionHandler
20 ExceptionBarrierCustomHandler::s_custom_handler_ = NULL;
[email protected]219d1a62010-04-28 00:45:0821
22// This function must be extern "C" to match up with the SAFESEH
23// declaration in our corresponding ASM file
24extern "C" EXCEPTION_DISPOSITION __cdecl
[email protected]dcdcfa02010-04-28 20:59:0325ExceptionBarrierHandler(struct _EXCEPTION_RECORD* exception_record,
26 void* establisher_frame,
27 struct _CONTEXT* context,
28 void* reserved) {
[email protected]72354312010-05-01 02:10:0629 // When the exception is really propagating through us, we'd like to be
30 // called before the state of the program has been modified by the stack
31 // unwinding. In the absence of an exception handler, the unhandled
32 // exception filter gets called between the first chance and the second
33 // chance exceptions, so Windows pops either the JIT debugger or WER UI.
34 // This is not desirable in most of the cases.
35 EXCEPTION_POINTERS ptrs = { exception_record, context };
36
37 if (ExceptionBarrierConfig::enabled() &&
38 IS_DISPATCHING(exception_record->ExceptionFlags)) {
39 WriteMinidumpForException(&ptrs);
40 }
41
42 return ExceptionContinueSearch;
43}
44
45extern "C" EXCEPTION_DISPOSITION __cdecl
46ExceptionBarrierReportOnlyModuleHandler(
47 struct _EXCEPTION_RECORD* exception_record,
48 void* establisher_frame,
49 struct _CONTEXT* context,
50 void* reserved) {
51 EXCEPTION_POINTERS ptrs = { exception_record, context };
52
53 if (ExceptionBarrierConfig::enabled() &&
54 IS_DISPATCHING(exception_record->ExceptionFlags)) {
55 CrashHandlerTraits traits;
56 traits.Init(0, 0, &WriteMinidumpForException);
57 if (traits.IsOurModule(exception_record->ExceptionAddress)) {
58 traits.WriteDump(&ptrs);
59 }
60 }
61
62 return ExceptionContinueSearch;
63}
64
65extern "C" EXCEPTION_DISPOSITION __cdecl
66ExceptionBarrierCallCustomHandler(struct _EXCEPTION_RECORD* exception_record,
67 void* establisher_frame,
68 struct _CONTEXT* context,
69 void* reserved) {
70 if (ExceptionBarrierConfig::enabled() &&
71 IS_DISPATCHING(exception_record->ExceptionFlags)) {
72 ExceptionBarrierCustomHandler::CustomExceptionHandler handler =
73 ExceptionBarrierCustomHandler::custom_handler();
[email protected]219d1a62010-04-28 00:45:0874 if (handler) {
75 EXCEPTION_POINTERS ptrs = { exception_record, context };
[email protected]219d1a62010-04-28 00:45:0876 handler(&ptrs);
77 }
78 }
79
80 return ExceptionContinueSearch;
81}