blob: ed0d3ca83e59e5265b5b1c33e9aa08a5aa8b805a [file] [log] [blame]
// Copyright (c) 2010 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_VEH_TEST_H_
#define CHROME_FRAME_CRASH_REPORTING_VEH_TEST_H_
#include <windows.h>
#include "base/logging.h"
#ifndef EXCEPTION_CHAIN_END
#define EXCEPTION_CHAIN_END ((struct _EXCEPTION_REGISTRATION_RECORD*)-1)
#if !defined(_WIN32_WINNT_WIN8)
typedef struct _EXCEPTION_REGISTRATION_RECORD {
struct _EXCEPTION_REGISTRATION_RECORD* Next;
PVOID Handler;
} EXCEPTION_REGISTRATION_RECORD;
// VEH handler flags settings.
// These are grabbed from winnt.h for PocketPC.
// Only EXCEPTION_NONCONTINUABLE in defined in "regular" winnt.h
// #define EXCEPTION_NONCONTINUABLE 0x1 // Noncontinuable exception
#define EXCEPTION_UNWINDING 0x2 // Unwind is in progress
#define EXCEPTION_EXIT_UNWIND 0x4 // Exit unwind is in progress
#define EXCEPTION_STACK_INVALID 0x8 // Stack out of limits or unaligned
#define EXCEPTION_NESTED_CALL 0x10 // Nested exception handler call
#define EXCEPTION_TARGET_UNWIND 0x20 // Target unwind in progress
#define EXCEPTION_COLLIDED_UNWIND 0x40 // Collided exception handler call
#define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | \
EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND)
#define IS_UNWINDING(Flag) (((Flag) & EXCEPTION_UNWIND) != 0)
#define IS_DISPATCHING(Flag) (((Flag) & EXCEPTION_UNWIND) == 0)
#define IS_TARGET_UNWIND(Flag) ((Flag) & EXCEPTION_TARGET_UNWIND)
#endif // !defined(_WIN32_WINNT_WIN8)
#endif // EXCEPTION_CHAIN_END
class ExceptionInfo : public _EXCEPTION_POINTERS {
public:
ExceptionInfo() {
Clear();
}
ExceptionInfo(DWORD code, void* address) {
Clear();
Set(code, address, 0);
}
void Set(DWORD code, void* address, DWORD flags) {
er_.ExceptionCode = code;
er_.ExceptionAddress = address;
er_.ExceptionFlags = flags;
ctx_.Eip = reinterpret_cast<DWORD>(address);
}
EXCEPTION_RECORD er_;
CONTEXT ctx_;
private:
void Clear() {
ExceptionRecord = &er_;
ContextRecord = &ctx_;
ZeroMemory(&er_, sizeof(er_));
ZeroMemory(&ctx_, sizeof(ctx_));
}
};
struct SEHChain {
SEHChain(const void* p, ...) {
va_list vl;
va_start(vl, p);
int i = 0;
for (; p; ++i) {
CHECK(i + 1 < arraysize(chain_));
chain_[i].Handler =
reinterpret_cast<PEXCEPTION_ROUTINE>(const_cast<void*>(p));
chain_[i].Next = &chain_[i + 1];
p = va_arg(vl, const void*);
}
chain_[i].Next = EXCEPTION_CHAIN_END;
}
EXCEPTION_REGISTRATION_RECORD chain_[25];
};
struct StackHelper {
StackHelper(const void* p, ...) {
va_list vl;
va_start(vl, p);
count_ = 0;
for (; p; ++count_) {
CHECK(count_ < arraysize(stack_));
stack_[count_] = p;
p = va_arg(vl, const void*);
}
}
const void* stack_[64];
WORD count_;
};
#endif // CHROME_FRAME_CRASH_REPORTING_VEH_TEST_H_