15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2010 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_FRAME_CRASH_REPORTING_VEH_TEST_H_
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_FRAME_CRASH_REPORTING_VEH_TEST_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef EXCEPTION_CHAIN_END
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXCEPTION_CHAIN_END ((struct _EXCEPTION_REGISTRATION_RECORD*)-1)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(_WIN32_WINNT_WIN8)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _EXCEPTION_REGISTRATION_RECORD {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct _EXCEPTION_REGISTRATION_RECORD* Next;
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PVOID Handler;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} EXCEPTION_REGISTRATION_RECORD;
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// VEH handler flags settings.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These are grabbed from winnt.h for PocketPC.
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Only EXCEPTION_NONCONTINUABLE in defined in "regular" winnt.h
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// #define EXCEPTION_NONCONTINUABLE 0x1    // Noncontinuable exception
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXCEPTION_UNWINDING 0x2         // Unwind is in progress
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXCEPTION_EXIT_UNWIND 0x4       // Exit unwind is in progress
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXCEPTION_STACK_INVALID 0x8     // Stack out of limits or unaligned
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXCEPTION_NESTED_CALL 0x10      // Nested exception handler call
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXCEPTION_TARGET_UNWIND 0x20    // Target unwind in progress
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXCEPTION_COLLIDED_UNWIND 0x40  // Collided exception handler call
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | \
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IS_UNWINDING(Flag)  (((Flag) & EXCEPTION_UNWIND) != 0)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IS_DISPATCHING(Flag)  (((Flag) & EXCEPTION_UNWIND) == 0)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IS_TARGET_UNWIND(Flag)  ((Flag) & EXCEPTION_TARGET_UNWIND)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(_WIN32_WINNT_WIN8)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // EXCEPTION_CHAIN_END
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ExceptionInfo : public _EXCEPTION_POINTERS {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExceptionInfo() {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Clear();
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExceptionInfo(DWORD code, void* address) {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Clear();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Set(code, address, 0);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Set(DWORD code, void* address, DWORD flags) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    er_.ExceptionCode = code;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    er_.ExceptionAddress = address;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    er_.ExceptionFlags = flags;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctx_.Eip = reinterpret_cast<DWORD>(address);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXCEPTION_RECORD er_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CONTEXT ctx_;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Clear() {
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExceptionRecord = &er_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ContextRecord = &ctx_;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ZeroMemory(&er_, sizeof(er_));
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ZeroMemory(&ctx_, sizeof(ctx_));
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SEHChain {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SEHChain(const void* p, ...) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    va_list vl;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    va_start(vl, p);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i = 0;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (; p; ++i) {
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(i + 1 < arraysize(chain_));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chain_[i].Handler =
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          reinterpret_cast<PEXCEPTION_ROUTINE>(const_cast<void*>(p));
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chain_[i].Next = &chain_[i + 1];
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p = va_arg(vl, const void*);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chain_[i].Next = EXCEPTION_CHAIN_END;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXCEPTION_REGISTRATION_RECORD chain_[25];
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct StackHelper {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StackHelper(const void* p, ...) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    va_list vl;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    va_start(vl, p);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    count_ = 0;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (; p; ++count_) {
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CHECK(count_ < arraysize(stack_));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      stack_[count_] = p;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      p = va_arg(vl, const void*);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* stack_[64];
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WORD count_;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_FRAME_CRASH_REPORTING_VEH_TEST_H_
101