1 // Copyright (c) 2010 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 #ifndef CHROME_FRAME_CRASH_REPORTING_VEH_TEST_H_ 5 #define CHROME_FRAME_CRASH_REPORTING_VEH_TEST_H_ 6 7 #include <windows.h> 8 #include "base/logging.h" 9 10 #ifndef EXCEPTION_CHAIN_END 11 #define EXCEPTION_CHAIN_END ((struct _EXCEPTION_REGISTRATION_RECORD*)-1) 12 #if !defined(_WIN32_WINNT_WIN8) 13 typedef struct _EXCEPTION_REGISTRATION_RECORD { 14 struct _EXCEPTION_REGISTRATION_RECORD* Next; 15 PVOID Handler; 16 } EXCEPTION_REGISTRATION_RECORD; 17 // VEH handler flags settings. 18 // These are grabbed from winnt.h for PocketPC. 19 // Only EXCEPTION_NONCONTINUABLE in defined in "regular" winnt.h 20 // #define EXCEPTION_NONCONTINUABLE 0x1 // Noncontinuable exception 21 #define EXCEPTION_UNWINDING 0x2 // Unwind is in progress 22 #define EXCEPTION_EXIT_UNWIND 0x4 // Exit unwind is in progress 23 #define EXCEPTION_STACK_INVALID 0x8 // Stack out of limits or unaligned 24 #define EXCEPTION_NESTED_CALL 0x10 // Nested exception handler call 25 #define EXCEPTION_TARGET_UNWIND 0x20 // Target unwind in progress 26 #define EXCEPTION_COLLIDED_UNWIND 0x40 // Collided exception handler call 27 28 #define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | \ 29 EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND) 30 31 #define IS_UNWINDING(Flag) (((Flag) & EXCEPTION_UNWIND) != 0) 32 #define IS_DISPATCHING(Flag) (((Flag) & EXCEPTION_UNWIND) == 0) 33 #define IS_TARGET_UNWIND(Flag) ((Flag) & EXCEPTION_TARGET_UNWIND) 34 #endif // !defined(_WIN32_WINNT_WIN8) 35 #endif // EXCEPTION_CHAIN_END 36 37 class ExceptionInfo : public _EXCEPTION_POINTERS { 38 public: 39 ExceptionInfo() { 40 Clear(); 41 } 42 43 ExceptionInfo(DWORD code, void* address) { 44 Clear(); 45 Set(code, address, 0); 46 } 47 48 void Set(DWORD code, void* address, DWORD flags) { 49 er_.ExceptionCode = code; 50 er_.ExceptionAddress = address; 51 er_.ExceptionFlags = flags; 52 ctx_.Eip = reinterpret_cast<DWORD>(address); 53 } 54 55 EXCEPTION_RECORD er_; 56 CONTEXT ctx_; 57 private: 58 void Clear() { 59 ExceptionRecord = &er_; 60 ContextRecord = &ctx_; 61 ZeroMemory(&er_, sizeof(er_)); 62 ZeroMemory(&ctx_, sizeof(ctx_)); 63 } 64 }; 65 66 struct SEHChain { 67 SEHChain(const void* p, ...) { 68 va_list vl; 69 va_start(vl, p); 70 int i = 0; 71 for (; p; ++i) { 72 CHECK(i + 1 < arraysize(chain_)); 73 chain_[i].Handler = 74 reinterpret_cast<PEXCEPTION_ROUTINE>(const_cast<void*>(p)); 75 chain_[i].Next = &chain_[i + 1]; 76 p = va_arg(vl, const void*); 77 } 78 79 chain_[i].Next = EXCEPTION_CHAIN_END; 80 } 81 82 EXCEPTION_REGISTRATION_RECORD chain_[25]; 83 }; 84 85 struct StackHelper { 86 StackHelper(const void* p, ...) { 87 va_list vl; 88 va_start(vl, p); 89 count_ = 0; 90 for (; p; ++count_) { 91 CHECK(count_ < arraysize(stack_)); 92 stack_[count_] = p; 93 p = va_arg(vl, const void*); 94 } 95 } 96 const void* stack_[64]; 97 WORD count_; 98 }; 99 100 #endif // CHROME_FRAME_CRASH_REPORTING_VEH_TEST_H_ 101