| Index: chrome_frame/vectored_handler.h
|
| ===================================================================
|
| --- chrome_frame/vectored_handler.h (revision 0)
|
| +++ chrome_frame/vectored_handler.h (revision 0)
|
| @@ -0,0 +1,87 @@
|
| +// Copyright (c) 2009 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#ifndef CHROME_FRAME_VECTORED_HANDLER_H_
|
| +#define CHROME_FRAME_VECTORED_HANDLER_H_
|
| +
|
| +// Base class for VectoredHandlerT just to hold some members (independent of
|
| +// template parameter)
|
| +class VectoredHandlerBase {
|
| + public:
|
| + // For RtlCaptureStackBackTrace MSDN says:
|
| + // Windows Server 2003 and Windows XP: The sum of the FramesToSkip and
|
| + // FramesToCapture parameters must be less than 64.
|
| + // In practice (on XPSP2) it has to be less than 63, hence leaving us with
|
| + // max back trace of 62.
|
| + static const DWORD max_back_trace = 62;
|
| + static unsigned long g_exceptions_seen;
|
| + protected:
|
| + static void* g_handler;
|
| +};
|
| +
|
| +DECLSPEC_SELECTANY void* VectoredHandlerBase::g_handler;
|
| +DECLSPEC_SELECTANY unsigned long VectoredHandlerBase::g_exceptions_seen;
|
| +
|
| +// The E class is supposed to provide external/API functions. Using template
|
| +// make testability easier. It shall confirm the following concept/archetype:
|
| +// void* Register(PVECTORED_EXCEPTION_HANDLER,
|
| +// const void* module_start, const void* module_end)
|
| +// Registers Vectored Exception Handler, non-unittest implementation shall call
|
| +// ::AddVectoredExceptionHandler Win32 API
|
| +// ULONG Unregister(void*) - ::RemoveVectoredExceptionHandler Win32 API
|
| +// int IsOurModule(const void* address) -
|
| +// void WriteDump(EXCEPTION_POINTERS*) -
|
| +// WORD RtlCaptureStackBackTrace(..) - same as Win32 API
|
| +// EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() - same as Win32 API
|
| +// You may want to derive own External class by deriving from
|
| +// VEHExternalBase helper (see below).
|
| +// Create dump policy:
|
| +// 1. Scan SEH chain, if there is a handler/filter that belongs to our
|
| +// module - assume we expect this one and hence do nothing here.
|
| +// 2. If the address of the exception is in our module - create dump.
|
| +// 3. If our module is in somewhere in callstack - create dump.
|
| +template <class E>
|
| +class VectoredHandlerT : public VectoredHandlerBase {
|
| + public:
|
| + static void* Register(const void* module_start, const void* module_end) {
|
| + g_exceptions_seen = 0;
|
| + g_handler = E::Register(&VectoredHandler, module_start, module_end);
|
| + return g_handler;
|
| + }
|
| +
|
| + static ULONG Unregister() {
|
| + if (g_handler)
|
| + return E::Unregister(g_handler);
|
| + return 0;
|
| + }
|
| +
|
| + static LONG WINAPI VectoredHandler(EXCEPTION_POINTERS* exceptionInfo);
|
| + private:
|
| + static BOOL ModuleHasInstalledSEHFilter();
|
| +};
|
| +
|
| +// Handy class supposed to act as a base class for classes used as template
|
| +// parameter of VectoredHandlerT<E>
|
| +class VEHTraitsBase {
|
| + public:
|
| + static const void* g_module_start;
|
| + static const void* g_module_end;
|
| +
|
| + static inline int IsOurModule(const void* address) {
|
| + return (g_module_start <= address && address < g_module_end);
|
| + }
|
| +
|
| + static inline void SetModule(const void* module_start,
|
| + const void* module_end) {
|
| + g_module_start = module_start;
|
| + g_module_end = module_end;
|
| + }
|
| +};
|
| +
|
| +DECLSPEC_SELECTANY const void* VEHTraitsBase::g_module_start;
|
| +DECLSPEC_SELECTANY const void* VEHTraitsBase::g_module_end;
|
| +
|
| +class Win32VEHTraits;
|
| +typedef class VectoredHandlerT<Win32VEHTraits> VectoredHandler;
|
| +#endif // CHROME_FRAME_VECTORED_HANDLER_H_
|
|
|