Allow any redirects within frame for GAIA auth extension.
[chromium-blink-merge.git] / chrome_frame / exception_barrier.h
blobe3e5350262dcb45e28034848c0bf8184796a7737
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.
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 //
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
10 // boundaries.
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:
19 // @code
20 // ExceptionBarrierBase::set_crash_handling(true)
21 // @endcode
23 // somewhere in your initialization code.
25 // Then, to use this class, simply instantiate an ExceptionBarrier just inside
26 // the code boundary, like this:
27 // @code
28 // HRESULT SomeObject::SomeCOMMethod(...) {
29 // ExceptionBarrier report_crashes;
31 // ... other code here ...
32 // }
33 // @endcode
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
38 // in this module.
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_
48 #include <windows.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,
58 void* reserved);
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,
72 void* reserved);
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,
82 void* reserved);
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,
92 void* reserved);
95 // @name These are implemented in the associated .asm file
96 // @{
97 extern "C" void WINAPI RegisterExceptionRecord(
98 EXCEPTION_REGISTRATION* registration,
99 ExceptionHandlerFunc func);
100 extern "C" void WINAPI UnregisterExceptionRecord(
101 EXCEPTION_REGISTRATION* registration);
102 // @}
105 // Traits classes for ExceptionBarrierT.
106 class EBTraitsBase {
107 public:
108 static void UnregisterException(EXCEPTION_REGISTRATION* registration) {
109 UnregisterExceptionRecord(registration);
113 class EBReportAllTraits : public EBTraitsBase {
114 public:
115 static void RegisterException(EXCEPTION_REGISTRATION* registration) {
116 RegisterExceptionRecord(registration, ExceptionBarrierHandler);
120 class EBReportOnlyThisModuleTraits : public EBTraitsBase {
121 public:
122 static void RegisterException(EXCEPTION_REGISTRATION* registration) {
123 RegisterExceptionRecord(registration,
124 ExceptionBarrierReportOnlyModuleHandler);
128 class EBCustomHandlerTraits : public EBTraitsBase {
129 public:
130 static void RegisterException(EXCEPTION_REGISTRATION* registration) {
131 RegisterExceptionRecord(registration,
132 ExceptionBarrierCallCustomHandler);
136 class ExceptionBarrierConfig {
137 public:
138 // Used to globally enable or disable crash handling by ExceptionBarrierBase
139 // instances.
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 {
151 public:
152 // Register the barrier in the SEH chain
153 ExceptionBarrierT() {
154 RegistrarTraits::RegisterException(&registration_);
157 // Unregister on destruction
158 virtual ~ExceptionBarrierT() {
159 RegistrarTraits::UnregisterException(&registration_);
162 protected:
163 // Our SEH frame
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> {
173 public:
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_; }
185 private:
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_