Index: chrome_frame/crash_reporting/vectored_handler-impl.h |
=================================================================== |
--- chrome_frame/crash_reporting/vectored_handler-impl.h (revision 68282) |
+++ chrome_frame/crash_reporting/vectored_handler-impl.h (working copy) |
@@ -83,9 +83,10 @@ |
return ExceptionContinueSearch; |
} |
- // Check whether exception address is inbetween |
- // [IsBadReadPtr, IsBadReadPtr + 0xXX] |
- if (api_->ShouldIgnoreException(exceptionInfo)) { |
+ // Check whether exception will be handled by the module that cuased it. |
+ // This should automatically handle the case of IsBadReadPtr and family. |
+ const EXCEPTION_REGISTRATION_RECORD* seh = api_->RtlpGetExceptionList(); |
+ if (api_->ShouldIgnoreException(exceptionInfo, seh)) { |
return ExceptionContinueSearch; |
} |
@@ -169,27 +170,31 @@ |
BackTrace, BackTraceHash); |
} |
- static bool ShouldIgnoreException(const EXCEPTION_POINTERS* exceptionInfo) { |
+ static bool ShouldIgnoreException(const EXCEPTION_POINTERS* exceptionInfo, |
+ const EXCEPTION_REGISTRATION_RECORD* seh_record) { |
const void* address = exceptionInfo->ExceptionRecord->ExceptionAddress; |
- for (int i = 0; i < kIgnoreEntries; i++) { |
- const CodeBlock& code_block = IgnoreExceptions[i]; |
- DCHECK(code_block.code) << "Win32VEHTraits::CodeBlocks not initialized!"; |
- if ((CodeOffset(code_block.code, code_block.begin_offset) <= address) && |
- (address < CodeOffset(code_block.code, code_block.end_offset))) { |
- return true; |
- } |
- } |
+ const DWORD flags = GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | |
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS; |
+ HMODULE crashing_module = GetModuleHandleFromAddress(address); |
+ if (!crashing_module) |
+ return false; |
+ HMODULE top_seh_module = NULL; |
+ if (EXCEPTION_CHAIN_END != seh_record) |
+ top_seh_module = GetModuleHandleFromAddress(seh_record->Handler); |
+ |
+ // check if the crash address belongs in a module that's expecting |
+ // and handling it. This should address cases like kernel32!IsBadXXX |
+ // and urlmon!IsValidInterface |
+ if (crashing_module == top_seh_module) |
+ return true; |
+ |
// We don't want to report exceptions that occur during DLL loading, |
// as those are captured and ignored by the NT loader. If this thread |
// is holding the loader's lock, there's a possiblity that the crash |
// is occurring in a loading DLL, in which case we resolve the |
// crash address to a module and check on the module's status. |
- const DWORD flags = GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | |
- GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS; |
- HMODULE crashing_module = NULL; |
- if (nt_loader::OwnsLoaderLock() && ::GetModuleHandleEx( |
- flags, reinterpret_cast<LPCWSTR>(address), &crashing_module)) { |
+ if (nt_loader::OwnsLoaderLock()) { |
nt_loader::LDR_DATA_TABLE_ENTRY* entry = |
nt_loader::GetLoaderEntry(crashing_module); |
@@ -213,7 +218,7 @@ |
} |
static bool CheckForStackOverflow() { |
- MEMORY_BASIC_INFORMATION mi; |
+ MEMORY_BASIC_INFORMATION mi = {0}; |
const DWORD kPageSize = 0x1000; |
void* stack_top = GetStackTopLimit() - kPageSize; |
::VirtualQuery(stack_top, &mi, sizeof(mi)); |
@@ -225,44 +230,22 @@ |
return !(mi.Protect & PAGE_GUARD); |
} |
- static void InitializeIgnoredBlocks() { |
- // Initialize ignored exception list |
- for (int i = 0; i < kIgnoreEntries; i++) { |
- CodeBlock& code_block = IgnoreExceptions[i]; |
- if (!code_block.code) { |
- HMODULE module = GetModuleHandleA(code_block.module); |
- DCHECK(module) << "GetModuleHandle error: " << GetLastError(); |
- code_block.code = GetProcAddress(module, code_block.function); |
- DCHECK(code_block.code) << "GetProcAddress error: "<< GetLastError(); |
- } |
- } |
- } |
- |
private: |
static inline const void* CodeOffset(const void* code, int offset) { |
return reinterpret_cast<const char*>(code) + offset; |
} |
- // Block of code to be ignored for exceptions |
- struct CodeBlock { |
- char* module; |
- char* function; |
- int begin_offset; |
- int end_offset; |
- const void* code; |
- }; |
+ static HMODULE GetModuleHandleFromAddress(const void* p) { |
+ HMODULE module_at_address = NULL; |
+ MEMORY_BASIC_INFORMATION mi = {0}; |
+ if (::VirtualQuery(p, &mi, sizeof(mi)) && (mi.Type & MEM_IMAGE)) { |
+ module_at_address = reinterpret_cast<HMODULE>(mi.AllocationBase); |
+ } |
- static const int kIgnoreEntries = 4; |
- static CodeBlock IgnoreExceptions[kIgnoreEntries]; |
+ return module_at_address; |
+ } |
}; |
-DECLSPEC_SELECTANY Win32VEHTraits::CodeBlock |
-Win32VEHTraits::IgnoreExceptions[kIgnoreEntries] = { |
- { "kernel32.dll", "IsBadReadPtr", 0, 100, NULL }, |
- { "kernel32.dll", "IsBadWritePtr", 0, 100, NULL }, |
- { "kernel32.dll", "IsBadStringPtrA", 0, 100, NULL }, |
- { "kernel32.dll", "IsBadStringPtrW", 0, 100, NULL }, |
-}; |
// Use Win32 API; checks for single (current) module. Will call a specified |
// CrashHandlerTraits::DumpHandler when taking a dump. |
@@ -279,7 +262,6 @@ |
DumpHandler dump_handler) { |
DCHECK(dump_handler); |
dump_handler_ = dump_handler; |
- Win32VEHTraits::InitializeIgnoredBlocks(); |
ModuleOfInterestWithExcludedRegion::SetCurrentModule(); |
// Pointers to static (non-extern) functions take the address of the |
// function's first byte, as opposed to an entry in the compiler generated |