1 // 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.
5 // A class to make it easy to tag exception propagation boundaries and
6 // get crash reports of exceptions that pass over same.
8 // An exception barrier is used to report exceptions that pass through
9 // a boundary where exceptions shouldn't pass, such as e.g. COM interface
11 // This is handy for any kind of plugin code, where if the exception passes
12 // through unhindered, it'll either be swallowed by an SEH exception handler
13 // above us on the stack, or be reported as an unhandled exception for
14 // the application hosting the plugin code.
16 // IMPORTANT NOTE: This class has crash_reporting disabled by default. To
17 // enable crash reporting call:
20 // ExceptionBarrierBase::set_crash_handling(true)
23 // somewhere in your initialization code.
25 // Then, to use this class, simply instantiate an ExceptionBarrier just inside
26 // the code boundary, like this:
28 // HRESULT SomeObject::SomeCOMMethod(...) {
29 // ExceptionBarrier report_crashes;
31 // ... other code here ...
35 // There are three ExceptionBarrier types defined here:
36 // 1) ExceptionBarrier which reports all crashes it sees.
37 // 2) ExceptionBarrierReportOnlyModule which reports only crashes occurring
39 // 3) ExceptionBarrierCustomHandler which calls the handler set by a call
40 // to ExceptionBarrierCallCustomHandler::set_custom_handler(). Note that
41 // there is one custom handler for all ExceptionBarrierCallCustomHandler
42 // instances. If set_custom_handler() is never called, this places an
43 // SEH in the chain that just returns ExceptionContinueSearch.
45 #ifndef CHROME_FRAME_EXCEPTION_BARRIER_H_
46 #define CHROME_FRAME_EXCEPTION_BARRIER_H_
50 extern "C" IMAGE_DOS_HEADER __ImageBase
;
52 // This is the type dictated for an exception handler by the platform ABI
53 // @see _except_handler in excpt.h
54 typedef EXCEPTION_DISPOSITION (__cdecl
* ExceptionHandlerFunc
)(
55 struct _EXCEPTION_RECORD
* exception_record
,
56 void* establisher_frame
,
57 struct _CONTEXT
* context
,
60 // The type of an exception record in the exception handler chain
61 struct EXCEPTION_REGISTRATION
{
62 EXCEPTION_REGISTRATION
* prev
;
63 ExceptionHandlerFunc handler
;
66 // This is our raw exception handler, it must be declared extern "C" to
67 // match up with the SAFESEH declaration in our corresponding ASM file.
68 extern "C" EXCEPTION_DISPOSITION __cdecl
69 ExceptionBarrierHandler(struct _EXCEPTION_RECORD
* exception_record
,
70 void* establisher_frame
,
71 struct _CONTEXT
* context
,
74 // An alternate raw exception handler that reports crashes only for the current
75 // module. It must be declared extern "C" to match up with the SAFESEH
76 // declaration in our corresponding ASM file.
77 extern "C" EXCEPTION_DISPOSITION __cdecl
78 ExceptionBarrierReportOnlyModuleHandler(
79 struct _EXCEPTION_RECORD
* exception_record
,
80 void* establisher_frame
,
81 struct _CONTEXT
* context
,
84 // An alternate raw exception handler that calls out to a custom handler.
85 // It must be declared extern "C" to match up with the SAFESEH declaration in
86 // our corresponding ASM file.
87 extern "C" EXCEPTION_DISPOSITION __cdecl
88 ExceptionBarrierCallCustomHandler(
89 struct _EXCEPTION_RECORD
* exception_record
,
90 void* establisher_frame
,
91 struct _CONTEXT
* context
,
95 // @name These are implemented in the associated .asm file
97 extern "C" void WINAPI
RegisterExceptionRecord(
98 EXCEPTION_REGISTRATION
* registration
,
99 ExceptionHandlerFunc func
);
100 extern "C" void WINAPI
UnregisterExceptionRecord(
101 EXCEPTION_REGISTRATION
* registration
);
105 // Traits classes for ExceptionBarrierT.
108 static void UnregisterException(EXCEPTION_REGISTRATION
* registration
) {
109 UnregisterExceptionRecord(registration
);
113 class EBReportAllTraits
: public EBTraitsBase
{
115 static void RegisterException(EXCEPTION_REGISTRATION
* registration
) {
116 RegisterExceptionRecord(registration
, ExceptionBarrierHandler
);
120 class EBReportOnlyThisModuleTraits
: public EBTraitsBase
{
122 static void RegisterException(EXCEPTION_REGISTRATION
* registration
) {
123 RegisterExceptionRecord(registration
,
124 ExceptionBarrierReportOnlyModuleHandler
);
128 class EBCustomHandlerTraits
: public EBTraitsBase
{
130 static void RegisterException(EXCEPTION_REGISTRATION
* registration
) {
131 RegisterExceptionRecord(registration
,
132 ExceptionBarrierCallCustomHandler
);
136 class ExceptionBarrierConfig
{
138 // Used to globally enable or disable crash handling by ExceptionBarrierBase
140 static void set_enabled(bool enabled
) {
141 s_enabled_
= enabled
;
143 static bool enabled() { return s_enabled_
; }
145 // Whether crash reports are enabled.
146 static bool s_enabled_
;
149 template <typename RegistrarTraits
>
150 class ExceptionBarrierT
{
152 // Register the barrier in the SEH chain
153 ExceptionBarrierT() {
154 RegistrarTraits::RegisterException(®istration_
);
157 // Unregister on destruction
158 virtual ~ExceptionBarrierT() {
159 RegistrarTraits::UnregisterException(®istration_
);
164 EXCEPTION_REGISTRATION registration_
;
167 // This class allows for setting a custom exception handler function. The
168 // handler is shared among all instances. This class is intended to enable
169 // testing of the SEH registration.
170 template <typename RegistrarTraits
>
171 class ExceptionBarrierCustomHandlerT
:
172 public ExceptionBarrierT
<typename RegistrarTraits
> {
174 // Signature of the handler function which gets notified when
175 // an exception propagates through a barrier.
176 typedef void (CALLBACK
* CustomExceptionHandler
)(EXCEPTION_POINTERS
* ptrs
);
178 // Used to set a global custom handler used by all
179 // ExceptionBarrierCustomHandler instances.
180 static void set_custom_handler(CustomExceptionHandler handler
) {
181 s_custom_handler_
= handler
;
183 static CustomExceptionHandler
custom_handler() { return s_custom_handler_
; }
186 static CustomExceptionHandler s_custom_handler_
;
189 // Convenience typedefs for the ExceptionBarrierT specializations.
190 typedef ExceptionBarrierT
<EBReportAllTraits
> ExceptionBarrier
;
191 typedef ExceptionBarrierT
<EBReportOnlyThisModuleTraits
>
192 ExceptionBarrierReportOnlyModule
;
193 typedef ExceptionBarrierCustomHandlerT
<EBCustomHandlerTraits
>
194 ExceptionBarrierCustomHandler
;
196 #endif // CHROME_FRAME_EXCEPTION_BARRIER_H_