Home | History | Annotate | Download | only in crash_reporting
      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