- add sources.
[platform/framework/web/crosswalk.git] / src / chrome_frame / crash_reporting / vectored_handler.h
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_