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)
13typedef 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
37class 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
66struct 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
85struct 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