| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 // Copyright (c) 2009 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 | 
|  | 5 #ifndef CHROME_FRAME_VECTORED_HANDLER_IMPL_H_ | 
|  | 6 #define CHROME_FRAME_VECTORED_HANDLER_IMPL_H_ | 
|  | 7 #include "chrome_frame/vectored_handler.h" | 
|  | 8 | 
|  | 9 #if defined(_M_IX86) | 
|  | 10 typedef struct _EXCEPTION_REGISTRATION_RECORD { | 
|  | 11   struct _EXCEPTION_REGISTRATION_RECORD* Next; | 
|  | 12   PVOID Handler; | 
|  | 13 } EXCEPTION_REGISTRATION_RECORD; | 
|  | 14 #define EXCEPTION_CHAIN_END ((struct _EXCEPTION_REGISTRATION_RECORD*)-1) | 
|  | 15 #else | 
|  | 16 #error only x86 is supported for now. | 
|  | 17 #endif | 
|  | 18 | 
|  | 19 | 
|  | 20 // VEH handler flags settings. | 
|  | 21 // These are grabbed from winnt.h for PocketPC. | 
|  | 22 // Only EXCEPTION_NONCONTINUABLE in defined in "regular" winnt.h | 
|  | 23 // #define EXCEPTION_NONCONTINUABLE 0x1    // Noncontinuable exception | 
|  | 24 #define EXCEPTION_UNWINDING 0x2         // Unwind is in progress | 
|  | 25 #define EXCEPTION_EXIT_UNWIND 0x4       // Exit unwind is in progress | 
|  | 26 #define EXCEPTION_STACK_INVALID 0x8     // Stack out of limits or unaligned | 
|  | 27 #define EXCEPTION_NESTED_CALL 0x10      // Nested exception handler call | 
|  | 28 #define EXCEPTION_TARGET_UNWIND 0x20    // Target unwind in progress | 
|  | 29 #define EXCEPTION_COLLIDED_UNWIND 0x40  // Collided exception handler call | 
|  | 30 | 
|  | 31 #define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | \ | 
|  | 32     EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND) | 
|  | 33 | 
|  | 34 #define IS_UNWINDING(Flag)  (((Flag) & EXCEPTION_UNWIND) != 0) | 
|  | 35 #define IS_DISPATCHING(Flag)  (((Flag) & EXCEPTION_UNWIND) == 0) | 
|  | 36 #define IS_TARGET_UNWIND(Flag)  ((Flag) & EXCEPTION_TARGET_UNWIND) | 
|  | 37 // End of grabbed section | 
|  | 38 | 
|  | 39 template <class E> | 
|  | 40 LONG WINAPI VectoredHandlerT<E>::VectoredHandler( | 
|  | 41     EXCEPTION_POINTERS* exceptionInfo) { | 
|  | 42   // TODO(stoyan): Consider reentrancy | 
|  | 43   const DWORD exceptionCode = exceptionInfo->ExceptionRecord->ExceptionCode; | 
|  | 44 | 
|  | 45   // Not interested in non-error exceptions. In this category falls exceptions | 
|  | 46   // like: | 
|  | 47   // 0x40010006 - OutputDebugStringA. Seen when no debugger is attached | 
|  | 48   //              (otherwise debugger swallows the exception and prints | 
|  | 49   //              the string). | 
|  | 50   // 0x406D1388 - DebuggerProbe. Used by debug CRT - for example see source | 
|  | 51   //              code of isatty(). Used to name a thread as well. | 
|  | 52   // RPC_E_DISCONNECTED and Co. - COM IPC non-fatal warnings | 
|  | 53   // STATUS_BREAKPOINT and Co. - Debugger related breakpoints | 
|  | 54 | 
|  | 55   if ((exceptionCode & ERROR_SEVERITY_ERROR) != ERROR_SEVERITY_ERROR) { | 
|  | 56     return ExceptionContinueSearch; | 
|  | 57   } | 
|  | 58 | 
|  | 59   ++VectoredHandlerT<E>::g_exceptions_seen; | 
|  | 60 | 
|  | 61   // TODO(stoyan): Check whether exception address is inbetween | 
|  | 62   // [IsBadReadPtr, IsBadReadPtr + 0xXX] | 
|  | 63 | 
|  | 64   const DWORD exceptionFlags = exceptionInfo->ExceptionRecord->ExceptionFlags; | 
|  | 65   // I don't think VEH is called on unwind. Just to be safe. | 
|  | 66   if (IS_DISPATCHING(exceptionFlags)) { | 
|  | 67     if (ModuleHasInstalledSEHFilter()) | 
|  | 68       return ExceptionContinueSearch; | 
|  | 69 | 
|  | 70     if (E::IsOurModule(exceptionInfo->ExceptionRecord->ExceptionAddress)) { | 
|  | 71       E::WriteDump(exceptionInfo); | 
|  | 72       return ExceptionContinueSearch; | 
|  | 73     } | 
|  | 74 | 
|  | 75     // See whether our module is somewhere in the call stack. | 
|  | 76     void* back_trace[max_back_trace] = {0}; | 
|  | 77     // Skip RtlCaptureStackBackTrace and VectoredHandler itself. | 
|  | 78     DWORD captured = E::RtlCaptureStackBackTrace(2, max_back_trace - 2, | 
|  | 79                                                  &back_trace[0], NULL); | 
|  | 80     for (DWORD i = 0; i < captured; ++i) { | 
|  | 81      if (E::IsOurModule(back_trace[i])) { | 
|  | 82        E::WriteDump(exceptionInfo); | 
|  | 83        return ExceptionContinueSearch; | 
|  | 84      } | 
|  | 85     } | 
|  | 86   } | 
|  | 87 | 
|  | 88   return ExceptionContinueSearch; | 
|  | 89 } | 
|  | 90 | 
|  | 91 template <class E> | 
|  | 92 BOOL VectoredHandlerT<E>::ModuleHasInstalledSEHFilter() { | 
|  | 93   EXCEPTION_REGISTRATION_RECORD* RegistrationFrame = E::RtlpGetExceptionList(); | 
|  | 94   // TODO(stoyan): Add the stack limits check and some sanity checks like | 
|  | 95   // decreasing addresses of registration records | 
|  | 96   while (RegistrationFrame != EXCEPTION_CHAIN_END) { | 
|  | 97     if (E::IsOurModule(RegistrationFrame->Handler)) { | 
|  | 98       return TRUE; | 
|  | 99     } | 
|  | 100 | 
|  | 101     RegistrationFrame = RegistrationFrame->Next; | 
|  | 102   } | 
|  | 103 | 
|  | 104   return FALSE; | 
|  | 105 } | 
|  | 106 #endif  // CHROME_FRAME_VECTORED_HANDLER_IMPL_H_ | 
| OLD | NEW | 
|---|