excepthandler.cpp
上传用户:glass0516
上传日期:2010-01-11
资源大小:104k
文件大小:8k
- /*****************************************************************************
- * RelayFax Open Source Project
- * Copyright 1996-2004 Alt-N Technologies, Ltd.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted only as authorized by the RelayFax Open
- * Source License. A copy of this license is available in file LICENSE
- * in the top-level directory of the distribution.
- *
- * RelayFax is a registered trademark of Alt-N Technologies, Ltd.
- *
- * Individual files and/or contributed packages may be copyright by
- * other parties and subject to additional restrictions.
- *****************************************************************************/
- #include "stdafx.h"
- #include "excepthandler.h"
- //////////////////////////////// Externals /////////////////////////////////////
- int g_nExceptionCount = 0;
- //////////////////////////////////////////////////////////////////////
- // Log it
- //////////////////////////////////////////////////////////////////////
- void ExceptionLog( LPCSTR szFormat, ... )
- {
- char Buffer[RFLOGGER_BUFSIZE+2];
- va_list va;
- int nRet;
- va_start( va, szFormat );
-
- nRet = _vsnprintf( Buffer, RFLOGGER_BUFSIZE, szFormat, va );
-
- if( nRet < 0 )
- {
- Buffer[RFLOGGER_BUFSIZE-1] = 'n';
- Buffer[RFLOGGER_BUFSIZE] = ' ';
- }
- else
- {
- Buffer[nRet] = 'n';
- Buffer[nRet+1] = ' ';
- }
- #ifdef DEBUG
- OutputDebugString( Buffer );
- #endif
- va_end(va);
- }
- //////////////////////////////////////////////////////////////////////
- // Given an exception code, returns a pointer to a static string with a
- // description of the exception
- //////////////////////////////////////////////////////////////////////
- LPTSTR GetExceptionString( DWORD dwCode )
- {
- #define EXCEPTION( x ) case EXCEPTION_##x: return _T(#x);
- switch ( dwCode )
- {
- EXCEPTION( ACCESS_VIOLATION )
- EXCEPTION( DATATYPE_MISALIGNMENT )
- EXCEPTION( BREAKPOINT )
- EXCEPTION( SINGLE_STEP )
- EXCEPTION( ARRAY_BOUNDS_EXCEEDED )
- EXCEPTION( FLT_DENORMAL_OPERAND )
- EXCEPTION( FLT_DIVIDE_BY_ZERO )
- EXCEPTION( FLT_INEXACT_RESULT )
- EXCEPTION( FLT_INVALID_OPERATION )
- EXCEPTION( FLT_OVERFLOW )
- EXCEPTION( FLT_STACK_CHECK )
- EXCEPTION( FLT_UNDERFLOW )
- EXCEPTION( INT_DIVIDE_BY_ZERO )
- EXCEPTION( INT_OVERFLOW )
- EXCEPTION( PRIV_INSTRUCTION )
- EXCEPTION( IN_PAGE_ERROR )
- EXCEPTION( ILLEGAL_INSTRUCTION )
- EXCEPTION( NONCONTINUABLE_EXCEPTION )
- EXCEPTION( STACK_OVERFLOW )
- EXCEPTION( INVALID_DISPOSITION )
- EXCEPTION( GUARD_PAGE )
- EXCEPTION( INVALID_HANDLE )
- }
- // If not one of the "known" exceptions, try to get the string
- // from NTDLL.DLL's message table.
- static TCHAR szBuffer[512] = { 0 };
- FormatMessage( FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
- GetModuleHandle( _T("NTDLL.DLL") ),
- dwCode, 0, szBuffer, sizeof( szBuffer ), 0 );
- return szBuffer;
- }
- //////////////////////////////////////////////////////////////////////
- // Given a linear address, locates the module, section, and offset containing
- // that address.
- //
- // Note: the szModule paramater buffer is an output buffer of length specified
- // by the len parameter (in characters!)
- //////////////////////////////////////////////////////////////////////
- BOOL GetLogicalAddress( PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset )
- {
- MEMORY_BASIC_INFORMATION mbi;
- if ( !VirtualQuery( addr, &mbi, sizeof(mbi) ) )
- return FALSE;
- DWORD hMod = (DWORD)mbi.AllocationBase;
- if ( !GetModuleFileName( (HMODULE)hMod, szModule, len ) )
- return FALSE;
- // Point to the DOS header in memory
- PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
- // From the DOS header, find the NT (PE) header
- PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew);
- PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr );
- DWORD rva = (DWORD)addr - hMod; // RVA is offset from module load address
- // Iterate through the section table, looking for the one that encompasses
- // the linear address.
- for ( unsigned i = 0;
- i < pNtHdr->FileHeader.NumberOfSections;
- i++, pSection++ )
- {
- DWORD sectionStart = pSection->VirtualAddress;
- DWORD sectionEnd = sectionStart
- + max(pSection->SizeOfRawData, pSection->Misc.VirtualSize);
- // Is the address in this section???
- if ( (rva >= sectionStart) && (rva <= sectionEnd) )
- {
- // Yes, address is in the section. Calculate section and offset,
- // and store in the "section" & "offset" params, which were
- // passed by reference.
- section = i+1;
- offset = rva - sectionStart;
- return TRUE;
- }
- }
- return FALSE; // Should never get here!
- }
- //////////////////////////////////////////////////////////////////////
- // Walks the stack, and writes the results to the report file
- //////////////////////////////////////////////////////////////////////
- void IntelStackWalk( PCONTEXT pContext )
- {
- DWORD pc = pContext->Eip;
- PDWORD pFrame, pPrevFrame;
-
- pFrame = (PDWORD)pContext->Ebp;
- do
- {
- TCHAR szModule[MAX_PATH];
- DWORD section = 0, offset = 0;
- szModule[0] = ' ';
- GetLogicalAddress((PVOID)pc, szModule,sizeof(szModule),section,offset );
- szModule[MAX_PATH-1] = ' ';
- ExceptionLog( "%08X %08X %04X:%08X %s", pc, pFrame, section, offset, szModule );
- if ( IsBadWritePtr(pFrame+1, sizeof(PVOID) ) )
- break;
- pc = pFrame[1];
- pPrevFrame = pFrame;
- pFrame = (PDWORD)pFrame[0]; // precede to next higher frame on stack
- if ( (DWORD)pFrame & 3 ) // Frame pointer must be aligned on a
- break; // DWORD boundary. Bail if not so.
- if ( pFrame <= pPrevFrame )
- break;
- // Can two DWORDs be read from the supposed frame address?
- if ( IsBadWritePtr(pFrame, sizeof(PVOID)*2) )
- break;
- } while ( 1 );
- }
- //////////////////////////////////////////////////////////////////////
- // ExceptionHandler
- //////////////////////////////////////////////////////////////////////
- DWORD ExceptionHandler( LPEXCEPTION_POINTERS pExceptionInfo,
- LPCSTR szThreadName,
- LPCSTR szWhere )
- {
- PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
- // First print information about the type of fault
- ExceptionLog( "%s: Exception %08X %s in %s",
- szThreadName,
- pExceptionRecord->ExceptionCode,
- GetExceptionString(pExceptionRecord->ExceptionCode),
- szWhere );
- OSVERSIONINFO osv;
- // What version of Windows are you running?
- osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetVersionEx(&osv);
- ExceptionLog( "OS version: %d.%d Platform ID: %d Build: %d",
- osv.dwMajorVersion, osv.dwMinorVersion, osv.dwPlatformId, osv.dwBuildNumber );
- IntelStackWalk( pExceptionInfo->ContextRecord );
- ExceptionLog( "----------" );
- g_nExceptionCount++;
- return EXCEPTION_EXECUTE_HANDLER ;
- }