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 50 template <typename E> 51 class 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). 71 struct 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 97 struct 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