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