Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(744)

Side by Side Diff: chrome_frame/crash_reporting/vectored_handler.h

Issue 557021: Prevent excessive crash reporting due stack overflow (due exception in SEH fi... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_ 5 #ifndef CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_
6 #define CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_ 6 #define CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_
7 7
8 // Base class for VectoredHandlerT just to hold some members (independent of
9 // template parameter)
10 class VectoredHandlerBase {
11 public:
12 // For RtlCaptureStackBackTrace MSDN says:
13 // Windows Server 2003 and Windows XP: The sum of the FramesToSkip and
14 // FramesToCapture parameters must be less than 64.
15 // In practice (on XPSP2) it has to be less than 63, hence leaving us with
16 // max back trace of 62.
17 static const DWORD max_back_trace = 62;
18 static unsigned long g_exceptions_seen;
19 protected:
20 static void* g_handler;
21 };
22 8
23 DECLSPEC_SELECTANY void* VectoredHandlerBase::g_handler; 9 #if !defined(_M_IX86)
24 DECLSPEC_SELECTANY unsigned long VectoredHandlerBase::g_exceptions_seen; 10 #error only x86 is supported for now.
11 #endif
25 12
26 // The E class is supposed to provide external/API functions. Using template
27 // make testability easier. It shall confirm the following concept/archetype:
28 // void* Register(PVECTORED_EXCEPTION_HANDLER,
29 // const void* module_start, const void* module_end)
30 // Registers Vectored Exception Handler, non-unittest implementation shall call
31 // ::AddVectoredExceptionHandler Win32 API
32 // ULONG Unregister(void*) - ::RemoveVectoredExceptionHandler Win32 API
33 // int IsOurModule(const void* address) -
34 // void WriteDump(EXCEPTION_POINTERS*) -
35 // WORD RtlCaptureStackBackTrace(..) - same as Win32 API
36 // EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() - same as Win32 API
37 // You may want to derive own External class by deriving from
38 // VEHExternalBase helper (see below).
39 // Create dump policy: 13 // Create dump policy:
40 // 1. Scan SEH chain, if there is a handler/filter that belongs to our 14 // 1. Scan SEH chain, if there is a handler/filter that belongs to our
41 // module - assume we expect this one and hence do nothing here. 15 // module - assume we expect this one and hence do nothing here.
42 // 2. If the address of the exception is in our module - create dump. 16 // 2. If the address of the exception is in our module - create dump.
43 // 3. If our module is in somewhere in callstack - create dump. 17 // 3. If our module is in somewhere in callstack - create dump.
44 template <class E> 18 // The E class is supposed to provide external/API functions. Using template
45 class VectoredHandlerT : public VectoredHandlerBase { 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 // int 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 // int StackOverflow(EXCEPTION_POINTERS* p) {
42 // return 0;
43 // }
44 //
45 // int 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 {
46 public: 52 public:
47 static void* Register(const void* module_start, const void* module_end) { 53 VectoredHandlerT(E* api);
48 g_exceptions_seen = 0; 54 ~VectoredHandlerT();
49 g_handler = E::Register(&VectoredHandler, module_start, module_end); 55
50 return g_handler; 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_;
51 } 60 }
52 61
53 static ULONG Unregister() { 62 private:
54 if (g_handler) 63 BOOL ModuleHasInstalledSEHFilter();
55 return E::Unregister(g_handler); 64 E* api_;
56 return 0; 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 int IsOurModule(const void* address) {
74 return (start_ <= address && address < end_);
57 } 75 }
58 76
59 static LONG WINAPI VectoredHandler(EXCEPTION_POINTERS* exceptionInfo); 77 // Helpers.
60 private: 78 inline void SetModule(const void* module_start, const void* module_end) {
61 static BOOL ModuleHasInstalledSEHFilter(); 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_;
62 }; 95 };
63 96
64 // Handy class supposed to act as a base class for classes used as template 97 struct ModuleOfInterestWithExcludedRegion : public ModuleOfInterest {
65 // parameter of VectoredHandlerT<E> 98 inline int IsOurModule(const void* address) {
66 class VEHTraitsBase { 99 return (start_ <= address && address < end_) &&
67 public: 100 (address < special_region_start_ || special_region_end_ <= address);
68 static const void* g_module_start;
69 static const void* g_module_end;
70
71 static inline int IsOurModule(const void* address) {
72 return (g_module_start <= address && address < g_module_end);
73 } 101 }
74 102
75 static inline void SetModule(const void* module_start, 103 inline void SetExcludedRegion(const void* start, const void* end) {
76 const void* module_end) { 104 special_region_start_ = start;
77 g_module_start = module_start; 105 special_region_end_ = end;
78 g_module_end = module_end;
79 } 106 }
80 107
81 static bool ShouldIgnoreException(const EXCEPTION_POINTERS* exceptionInfo) { 108 const void* special_region_start_;
82 return false; 109 const void* special_region_end_;
83 }
84 }; 110 };
85 111
86 DECLSPEC_SELECTANY const void* VEHTraitsBase::g_module_start;
87 DECLSPEC_SELECTANY const void* VEHTraitsBase::g_module_end;
88 112
89 class Win32VEHTraits;
90 typedef class VectoredHandlerT<Win32VEHTraits> VectoredHandler;
91 #endif // CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_ 113 #endif // CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698