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#ifndef CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_ 6#define CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_ 7 8 9#if !defined(_M_IX86) 10#error only x86 is supported for now. 11#endif 12 13// Create dump policy: 14// 1. Scan SEH chain, if there is a handler/filter that belongs to our 15// module - assume we expect this one and hence do nothing here. 16// 2. If the address of the exception is in our module - create dump. 17// 3. If our module is in somewhere in callstack - create dump. 18// The E class is supposed to provide external/API functions. Using template 19// make testability easier. It shall confirm the following concept/archetype: 20//struct E { 21// void WriteDump(EXCEPTION_POINTERS* p) { 22// } 23// 24// // Used mainly to ignore exceptions from IsBadRead/Write/Ptr. 25// bool ShouldIgnoreException(const EXCEPTION_POINTERS* exptr) { 26// return 0; 27// } 28// 29// // Retrieve the SEH list head. 30// EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() { 31// return NULL; 32// } 33// 34// // Get the stack trace as correctly as possible. 35// WORD RtlCaptureStackBackTrace(DWORD FramesToSkip, DWORD FramesToCapture, 36// void** BackTrace, DWORD* BackTraceHash) { 37// return 0; 38// } 39// 40// // Check whether the stack guard page is in place. 41// bool CheckForStackOverflow(EXCEPTION_POINTERS* p) { 42// return 0; 43// } 44// 45// bool IsOurModule(const void* address) { 46// return 0; 47// } 48//}; 49// The methods shall be placed in .text$veh_m 50template <typename E> 51class VectoredHandlerT { 52 public: 53 VectoredHandlerT(E* api); 54 ~VectoredHandlerT(); 55 56 // TODO(stoyan): Come with better way to skip initial stack frames. 57 FORCEINLINE LONG Handler(EXCEPTION_POINTERS* exceptionInfo); 58 long get_exceptions_seen() const { 59 return exceptions_seen_; 60 } 61 62 private: 63 bool ModuleHasInstalledSEHFilter(); 64 E* api_; 65 long exceptions_seen_; 66}; 67 68// Maintains start and end address of a single module of interest. If we want 69// do check for multiple modules, this class has to be extended to support a 70// list of modules (DLLs). 71struct ModuleOfInterest { 72 // The callback from VectoredHandlerT::Handler(). 73 inline bool IsOurModule(const void* address) { 74 return (start_ <= address && address < end_); 75 } 76 77 // Helpers. 78 inline void SetModule(const void* module_start, const void* module_end) { 79 start_ = module_start; 80 end_ = module_end; 81 } 82 83 inline void SetCurrentModule() { 84 // Find current module boundaries. 85 const void* start = &__ImageBase; 86 const char* s = reinterpret_cast<const char*>(start); 87 const IMAGE_NT_HEADERS32* nt = reinterpret_cast<const IMAGE_NT_HEADERS32*> 88 (s + __ImageBase.e_lfanew); 89 const void* end = s + nt->OptionalHeader.SizeOfImage; 90 SetModule(start, end); 91 } 92 93 const void* start_; 94 const void* end_; 95}; 96 97struct ModuleOfInterestWithExcludedRegion : public ModuleOfInterest { 98 inline bool IsOurModule(const void* address) { 99 return (start_ <= address && address < end_) && 100 (address < special_region_start_ || special_region_end_ <= address); 101 } 102 103 inline void SetExcludedRegion(const void* start, const void* end) { 104 special_region_start_ = start; 105 special_region_end_ = end; 106 } 107 108 const void* special_region_start_; 109 const void* special_region_end_; 110}; 111 112 113#endif // CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_ 114