Chromium Code Reviews| 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,32 @@ |
| BackTrace, BackTraceHash); |
| } |
| - static bool ShouldIgnoreException(const EXCEPTION_POINTERS* exceptionInfo) { |
| + static bool ShouldIgnoreException(const EXCEPTION_POINTERS* exceptionInfo, |
|
stoyan
2010/12/09 09:58:23
Hm.. if a module had installed SEH filter it does
amit
2010/12/09 17:58:59
True, there's a chance that the module's SEH filte
|
| + 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 = NULL; |
| + ::GetModuleHandleEx(flags, reinterpret_cast<LPCWSTR>(address), |
|
stoyan
2010/12/09 09:58:23
Beware - IIRC GetModuleHandle obtains loader lock.
amit
2010/12/09 17:58:59
Good point, changed it to use VirtualQuery
|
| + &crashing_module); |
| + HMODULE top_seh_module = NULL; |
| + if (EXCEPTION_CHAIN_END != seh_record) { |
| + ::GetModuleHandleEx(flags, reinterpret_cast<LPCWSTR>(seh_record->Handler), |
|
stoyan
2010/12/09 09:58:23
if crashing_module == NULL you don't have to call
amit
2010/12/09 17:58:59
Yupp, added the check for crashing_module and chan
|
| + &top_seh_module); |
| } |
| + // 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 && (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 (crashing_module && nt_loader::OwnsLoaderLock()) { |
| nt_loader::LDR_DATA_TABLE_ENTRY* entry = |
| nt_loader::GetLoaderEntry(crashing_module); |
| @@ -225,44 +231,12 @@ |
| 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 const int kIgnoreEntries = 4; |
| - static CodeBlock IgnoreExceptions[kIgnoreEntries]; |
| }; |
| -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 +253,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 |