blob: 1466bb5db17157750b4f8cb584186144a6edc71b [file] [log] [blame]
// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_
#define CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_
#if !defined(_M_IX86)
#error only x86 is supported for now.
#endif
// Create dump policy:
// 1. Scan SEH chain, if there is a handler/filter that belongs to our
// module - assume we expect this one and hence do nothing here.
// 2. If the address of the exception is in our module - create dump.
// 3. If our module is in somewhere in callstack - create dump.
// The E class is supposed to provide external/API functions. Using template
// make testability easier. It shall confirm the following concept/archetype:
//struct E {
// void WriteDump(EXCEPTION_POINTERS* p) {
// }
//
// // Used mainly to ignore exceptions from IsBadRead/Write/Ptr.
// bool ShouldIgnoreException(const EXCEPTION_POINTERS* exptr) {
// return 0;
// }
//
// // Retrieve the SEH list head.
// EXCEPTION_REGISTRATION_RECORD* RtlpGetExceptionList() {
// return NULL;
// }
//
// // Get the stack trace as correctly as possible.
// WORD RtlCaptureStackBackTrace(DWORD FramesToSkip, DWORD FramesToCapture,
// void** BackTrace, DWORD* BackTraceHash) {
// return 0;
// }
//
// // Check whether the stack guard page is in place.
// bool CheckForStackOverflow(EXCEPTION_POINTERS* p) {
// return 0;
// }
//
// bool IsOurModule(const void* address) {
// return 0;
// }
//};
// The methods shall be placed in .text$veh_m
template <typename E>
class VectoredHandlerT {
public:
VectoredHandlerT(E* api);
~VectoredHandlerT();
// TODO(stoyan): Come with better way to skip initial stack frames.
FORCEINLINE LONG Handler(EXCEPTION_POINTERS* exceptionInfo);
long get_exceptions_seen() const {
return exceptions_seen_;
}
private:
bool ModuleHasInstalledSEHFilter();
E* api_;
long exceptions_seen_;
};
// Maintains start and end address of a single module of interest. If we want
// do check for multiple modules, this class has to be extended to support a
// list of modules (DLLs).
struct ModuleOfInterest {
// The callback from VectoredHandlerT::Handler().
inline bool IsOurModule(const void* address) {
return (start_ <= address && address < end_);
}
// Helpers.
inline void SetModule(const void* module_start, const void* module_end) {
start_ = module_start;
end_ = module_end;
}
inline void SetCurrentModule() {
// Find current module boundaries.
const void* start = &__ImageBase;
const char* s = reinterpret_cast<const char*>(start);
const IMAGE_NT_HEADERS32* nt = reinterpret_cast<const IMAGE_NT_HEADERS32*>
(s + __ImageBase.e_lfanew);
const void* end = s + nt->OptionalHeader.SizeOfImage;
SetModule(start, end);
}
const void* start_;
const void* end_;
};
struct ModuleOfInterestWithExcludedRegion : public ModuleOfInterest {
inline bool IsOurModule(const void* address) {
return (start_ <= address && address < end_) &&
(address < special_region_start_ || special_region_end_ <= address);
}
inline void SetExcludedRegion(const void* start, const void* end) {
special_region_start_ = start;
special_region_end_ = end;
}
const void* special_region_start_;
const void* special_region_end_;
};
#endif // CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_H_