| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ | 5 #ifndef CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ |
| 6 #define CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ | 6 #define CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ |
| 7 #include "chrome_frame/crash_reporting/vectored_handler.h" | 7 #include "chrome_frame/crash_reporting/vectored_handler.h" |
| 8 #include "chrome_frame/crash_reporting/nt_loader.h" |
| 8 | 9 |
| 9 #if defined(_M_IX86) | 10 #if defined(_M_IX86) |
| 10 #ifndef EXCEPTION_CHAIN_END | 11 #ifndef EXCEPTION_CHAIN_END |
| 11 #define EXCEPTION_CHAIN_END ((struct _EXCEPTION_REGISTRATION_RECORD*)-1) | 12 #define EXCEPTION_CHAIN_END ((struct _EXCEPTION_REGISTRATION_RECORD*)-1) |
| 12 typedef struct _EXCEPTION_REGISTRATION_RECORD { | 13 typedef struct _EXCEPTION_REGISTRATION_RECORD { |
| 13 struct _EXCEPTION_REGISTRATION_RECORD* Next; | 14 struct _EXCEPTION_REGISTRATION_RECORD* Next; |
| 14 PVOID Handler; | 15 PVOID Handler; |
| 15 } EXCEPTION_REGISTRATION_RECORD; | 16 } EXCEPTION_REGISTRATION_RECORD; |
| 16 #endif // EXCEPTION_CHAIN_END | 17 #endif // EXCEPTION_CHAIN_END |
| 17 #else | 18 #else |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 if (IS_DISPATCHING(exceptionFlags)) { | 92 if (IS_DISPATCHING(exceptionFlags)) { |
| 92 if (ModuleHasInstalledSEHFilter()) | 93 if (ModuleHasInstalledSEHFilter()) |
| 93 return ExceptionContinueSearch; | 94 return ExceptionContinueSearch; |
| 94 | 95 |
| 95 if (api_->IsOurModule(exceptionInfo->ExceptionRecord->ExceptionAddress)) { | 96 if (api_->IsOurModule(exceptionInfo->ExceptionRecord->ExceptionAddress)) { |
| 96 api_->WriteDump(exceptionInfo); | 97 api_->WriteDump(exceptionInfo); |
| 97 return ExceptionContinueSearch; | 98 return ExceptionContinueSearch; |
| 98 } | 99 } |
| 99 | 100 |
| 100 // See whether our module is somewhere in the call stack. | 101 // See whether our module is somewhere in the call stack. |
| 101 void* back_trace[api_->max_back_trace] = {0}; | 102 void* back_trace[E::max_back_trace] = {0}; |
| 102 DWORD captured = api_->RtlCaptureStackBackTrace(0, api_->max_back_trace, | 103 DWORD captured = api_->RtlCaptureStackBackTrace(0, api_->max_back_trace, |
| 103 &back_trace[0], NULL); | 104 &back_trace[0], NULL); |
| 104 for (DWORD i = 0; i < captured; ++i) { | 105 for (DWORD i = 0; i < captured; ++i) { |
| 105 if (api_->IsOurModule(back_trace[i])) { | 106 if (api_->IsOurModule(back_trace[i])) { |
| 106 api_->WriteDump(exceptionInfo); | 107 api_->WriteDump(exceptionInfo); |
| 107 return ExceptionContinueSearch; | 108 return ExceptionContinueSearch; |
| 108 } | 109 } |
| 109 } | 110 } |
| 110 } | 111 } |
| 111 | 112 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 132 | 133 |
| 133 // Here comes the default Windows 32-bit implementation. | 134 // Here comes the default Windows 32-bit implementation. |
| 134 namespace { | 135 namespace { |
| 135 __declspec(naked) | 136 __declspec(naked) |
| 136 static EXCEPTION_REGISTRATION_RECORD* InternalRtlpGetExceptionList() { | 137 static EXCEPTION_REGISTRATION_RECORD* InternalRtlpGetExceptionList() { |
| 137 __asm { | 138 __asm { |
| 138 mov eax, fs:0 | 139 mov eax, fs:0 |
| 139 ret | 140 ret |
| 140 } | 141 } |
| 141 } | 142 } |
| 143 |
| 142 __declspec(naked) | 144 __declspec(naked) |
| 143 static char* GetStackTopLimit() { | 145 static char* GetStackTopLimit() { |
| 144 __asm { | 146 __asm { |
| 145 mov eax, fs:8 | 147 mov eax, fs:8 |
| 146 ret | 148 ret |
| 147 } | 149 } |
| 148 } | 150 } |
| 149 } // end of namespace | 151 } // end of namespace |
| 150 | 152 |
| 151 // Class which methods simply forwards to Win32 API. | 153 // Class which methods simply forwards to Win32 API. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 169 const void* address = exceptionInfo->ExceptionRecord->ExceptionAddress; | 171 const void* address = exceptionInfo->ExceptionRecord->ExceptionAddress; |
| 170 for (int i = 0; i < kIgnoreEntries; i++) { | 172 for (int i = 0; i < kIgnoreEntries; i++) { |
| 171 const CodeBlock& code_block = IgnoreExceptions[i]; | 173 const CodeBlock& code_block = IgnoreExceptions[i]; |
| 172 DCHECK(code_block.code) << "Win32VEHTraits::CodeBlocks not initialized!"; | 174 DCHECK(code_block.code) << "Win32VEHTraits::CodeBlocks not initialized!"; |
| 173 if ((CodeOffset(code_block.code, code_block.begin_offset) <= address) && | 175 if ((CodeOffset(code_block.code, code_block.begin_offset) <= address) && |
| 174 (address < CodeOffset(code_block.code, code_block.end_offset))) { | 176 (address < CodeOffset(code_block.code, code_block.end_offset))) { |
| 175 return true; | 177 return true; |
| 176 } | 178 } |
| 177 } | 179 } |
| 178 | 180 |
| 181 // We don't want to report exceptions that occur during DLL loading, |
| 182 // as those are captured and ignored by the NT loader. If this thread |
| 183 // is holding the loader's lock, there's a possiblity that the crash |
| 184 // is occurring in a loading DLL, in which case we resolve the |
| 185 // crash address to a module and check on the module's status. |
| 186 const DWORD flags = GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | |
| 187 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS; |
| 188 HMODULE crashing_module = NULL; |
| 189 if (nt_loader::OwnsLoaderLock() && ::GetModuleHandleEx( |
| 190 flags, reinterpret_cast<LPCWSTR>(address), &crashing_module)) { |
| 191 nt_loader::LDR_DATA_TABLE_ENTRY* entry = |
| 192 nt_loader::GetLoaderEntry(crashing_module); |
| 193 |
| 194 // If: |
| 195 // 1. we found the entry in question, and |
| 196 // 2. the entry is a DLL (has the IMAGE_DLL flag set), and |
| 197 // 3. the DLL has a non-null entrypoint, and |
| 198 // 4. the loader has not tagged it with the process attached called flag |
| 199 // we conclude that the crash is most likely during the loading of the |
| 200 // module and bail on reporting the crash to avoid false positives |
| 201 // during crashes that occur during module loads, such as e.g. when |
| 202 // the hook manager attempts to load buggy window hook DLLs. |
| 203 if (entry && |
| 204 (entry->Flags & LDRP_IMAGE_DLL) != 0 && |
| 205 (entry->EntryPoint != NULL) && |
| 206 (entry->Flags & LDRP_PROCESS_ATTACH_CALLED) == 0) |
| 207 return true; |
| 208 } |
| 209 |
| 179 return false; | 210 return false; |
| 180 } | 211 } |
| 181 | 212 |
| 182 static bool CheckForStackOverflow() { | 213 static bool CheckForStackOverflow() { |
| 183 MEMORY_BASIC_INFORMATION mi; | 214 MEMORY_BASIC_INFORMATION mi; |
| 184 const DWORD kPageSize = 0x1000; | 215 const DWORD kPageSize = 0x1000; |
| 185 void* stack_top = GetStackTopLimit() - kPageSize; | 216 void* stack_top = GetStackTopLimit() - kPageSize; |
| 186 ::VirtualQuery(stack_top, &mi, sizeof(mi)); | 217 ::VirtualQuery(stack_top, &mi, sizeof(mi)); |
| 187 // The above call may result in moving the top of the stack. | 218 // The above call may result in moving the top of the stack. |
| 188 // Check once more. | 219 // Check once more. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 | 256 |
| 226 DECLSPEC_SELECTANY Win32VEHTraits::CodeBlock | 257 DECLSPEC_SELECTANY Win32VEHTraits::CodeBlock |
| 227 Win32VEHTraits::IgnoreExceptions[kIgnoreEntries] = { | 258 Win32VEHTraits::IgnoreExceptions[kIgnoreEntries] = { |
| 228 { "kernel32.dll", "IsBadReadPtr", 0, 100, NULL }, | 259 { "kernel32.dll", "IsBadReadPtr", 0, 100, NULL }, |
| 229 { "kernel32.dll", "IsBadWritePtr", 0, 100, NULL }, | 260 { "kernel32.dll", "IsBadWritePtr", 0, 100, NULL }, |
| 230 { "kernel32.dll", "IsBadStringPtrA", 0, 100, NULL }, | 261 { "kernel32.dll", "IsBadStringPtrA", 0, 100, NULL }, |
| 231 { "kernel32.dll", "IsBadStringPtrW", 0, 100, NULL }, | 262 { "kernel32.dll", "IsBadStringPtrW", 0, 100, NULL }, |
| 232 }; | 263 }; |
| 233 | 264 |
| 234 #endif // CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ | 265 #endif // CHROME_FRAME_CRASH_REPORTING_VECTORED_HANDLER_IMPL_H_ |
| OLD | NEW |