excepthandler.cpp
上传用户:glass0516
上传日期:2010-01-11
资源大小:104k
文件大小:8k
源码类别:

传真(Fax)编程

开发平台:

Visual C++

  1. /*****************************************************************************
  2. * RelayFax Open Source Project
  3. * Copyright 1996-2004 Alt-N Technologies, Ltd.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted only as authorized by the RelayFax Open 
  8. * Source License.  A copy of this license is available in file LICENSE 
  9. * in the top-level directory of the distribution.
  10. *
  11. * RelayFax is a registered trademark of Alt-N Technologies, Ltd.
  12. *
  13. * Individual files and/or contributed packages may be copyright by
  14. * other parties and subject to additional restrictions.
  15. *****************************************************************************/
  16. #include "stdafx.h"
  17. #include "excepthandler.h"
  18. //////////////////////////////// Externals /////////////////////////////////////
  19. int g_nExceptionCount = 0;
  20. //////////////////////////////////////////////////////////////////////
  21. // Log it
  22. //////////////////////////////////////////////////////////////////////
  23. void ExceptionLog( LPCSTR szFormat, ... )
  24. {
  25. char Buffer[RFLOGGER_BUFSIZE+2];
  26. va_list va;
  27. int nRet;
  28. va_start( va, szFormat );
  29. nRet = _vsnprintf( Buffer, RFLOGGER_BUFSIZE, szFormat, va );
  30. if( nRet < 0 )
  31. {
  32. Buffer[RFLOGGER_BUFSIZE-1] = 'n';
  33. Buffer[RFLOGGER_BUFSIZE] = '';
  34. }
  35. else
  36. {
  37. Buffer[nRet] = 'n';
  38. Buffer[nRet+1] = '';
  39. }
  40. #ifdef DEBUG
  41. OutputDebugString( Buffer );
  42. #endif
  43. va_end(va);
  44. }
  45. //////////////////////////////////////////////////////////////////////
  46. // Given an exception code, returns a pointer to a static string with a 
  47. // description of the exception                                         
  48. //////////////////////////////////////////////////////////////////////
  49. LPTSTR GetExceptionString( DWORD dwCode )
  50. {
  51.     #define EXCEPTION( x ) case EXCEPTION_##x: return _T(#x);
  52.     switch ( dwCode )
  53.     {
  54.         EXCEPTION( ACCESS_VIOLATION )
  55.         EXCEPTION( DATATYPE_MISALIGNMENT )
  56.         EXCEPTION( BREAKPOINT )
  57.         EXCEPTION( SINGLE_STEP )
  58.         EXCEPTION( ARRAY_BOUNDS_EXCEEDED )
  59.         EXCEPTION( FLT_DENORMAL_OPERAND )
  60.         EXCEPTION( FLT_DIVIDE_BY_ZERO )
  61.         EXCEPTION( FLT_INEXACT_RESULT )
  62.         EXCEPTION( FLT_INVALID_OPERATION )
  63.         EXCEPTION( FLT_OVERFLOW )
  64.         EXCEPTION( FLT_STACK_CHECK )
  65.         EXCEPTION( FLT_UNDERFLOW )
  66.         EXCEPTION( INT_DIVIDE_BY_ZERO )
  67.         EXCEPTION( INT_OVERFLOW )
  68.         EXCEPTION( PRIV_INSTRUCTION )
  69.         EXCEPTION( IN_PAGE_ERROR )
  70.         EXCEPTION( ILLEGAL_INSTRUCTION )
  71.         EXCEPTION( NONCONTINUABLE_EXCEPTION )
  72.         EXCEPTION( STACK_OVERFLOW )
  73.         EXCEPTION( INVALID_DISPOSITION )
  74.         EXCEPTION( GUARD_PAGE )
  75.         EXCEPTION( INVALID_HANDLE )
  76.     }
  77.     // If not one of the "known" exceptions, try to get the string
  78.     // from NTDLL.DLL's message table.
  79.     static TCHAR szBuffer[512] = { 0 };
  80.     FormatMessage(  FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE,
  81.                     GetModuleHandle( _T("NTDLL.DLL") ),
  82.                     dwCode, 0, szBuffer, sizeof( szBuffer ), 0 );
  83.     return szBuffer;
  84. }
  85. //////////////////////////////////////////////////////////////////////
  86. // Given a linear address, locates the module, section, and offset containing  
  87. // that address.                                                               
  88. //                                                                             
  89. // Note: the szModule paramater buffer is an output buffer of length specified 
  90. // by the len parameter (in characters!)                                       
  91. //////////////////////////////////////////////////////////////////////
  92. BOOL GetLogicalAddress( PVOID addr, PTSTR szModule, DWORD len, DWORD& section, DWORD& offset )
  93. {
  94.     MEMORY_BASIC_INFORMATION mbi;
  95.     if ( !VirtualQuery( addr, &mbi, sizeof(mbi) ) )
  96.         return FALSE;
  97.     DWORD hMod = (DWORD)mbi.AllocationBase;
  98.     if ( !GetModuleFileName( (HMODULE)hMod, szModule, len ) )
  99.         return FALSE;
  100.     // Point to the DOS header in memory
  101.     PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
  102.     // From the DOS header, find the NT (PE) header
  103.     PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)(hMod + pDosHdr->e_lfanew);
  104.     PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION( pNtHdr );
  105.     DWORD rva = (DWORD)addr - hMod; // RVA is offset from module load address
  106.     // Iterate through the section table, looking for the one that encompasses
  107.     // the linear address.
  108.     for (   unsigned i = 0;
  109.             i < pNtHdr->FileHeader.NumberOfSections;
  110.             i++, pSection++ )
  111.     {
  112.         DWORD sectionStart = pSection->VirtualAddress;
  113.         DWORD sectionEnd = sectionStart
  114.                     + max(pSection->SizeOfRawData, pSection->Misc.VirtualSize);
  115.         // Is the address in this section???
  116.         if ( (rva >= sectionStart) && (rva <= sectionEnd) )
  117.         {
  118.             // Yes, address is in the section.  Calculate section and offset,
  119.             // and store in the "section" & "offset" params, which were
  120.             // passed by reference.
  121.             section = i+1;
  122.             offset = rva - sectionStart;
  123.             return TRUE;
  124.         }
  125.     }
  126.     return FALSE;   // Should never get here!
  127. }
  128. //////////////////////////////////////////////////////////////////////
  129. // Walks the stack, and writes the results to the report file 
  130. //////////////////////////////////////////////////////////////////////
  131. void IntelStackWalk( PCONTEXT pContext )
  132. {
  133.     DWORD pc = pContext->Eip;
  134.     PDWORD pFrame, pPrevFrame;
  135.     
  136.     pFrame = (PDWORD)pContext->Ebp;
  137.     do
  138.     {
  139.         TCHAR szModule[MAX_PATH];
  140.         DWORD section = 0, offset = 0;
  141. szModule[0] = '';
  142.         GetLogicalAddress((PVOID)pc, szModule,sizeof(szModule),section,offset );
  143. szModule[MAX_PATH-1] = '';
  144.         ExceptionLog( "%08X  %08X  %04X:%08X %s", pc, pFrame, section, offset, szModule );
  145. if ( IsBadWritePtr(pFrame+1, sizeof(PVOID) ) )
  146.             break;
  147.         pc = pFrame[1];
  148.         pPrevFrame = pFrame;
  149.         pFrame = (PDWORD)pFrame[0]; // precede to next higher frame on stack
  150.         if ( (DWORD)pFrame & 3 )    // Frame pointer must be aligned on a
  151.             break;                  // DWORD boundary.  Bail if not so.
  152.         if ( pFrame <= pPrevFrame )
  153.             break;
  154.         // Can two DWORDs be read from the supposed frame address?          
  155.         if ( IsBadWritePtr(pFrame, sizeof(PVOID)*2) )
  156.             break;
  157.     } while ( 1 );
  158. }
  159. //////////////////////////////////////////////////////////////////////
  160. // ExceptionHandler
  161. //////////////////////////////////////////////////////////////////////
  162. DWORD ExceptionHandler( LPEXCEPTION_POINTERS pExceptionInfo, 
  163.     LPCSTR szThreadName,
  164. LPCSTR szWhere )
  165. {
  166. PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
  167.     // First print information about the type of fault
  168.     ExceptionLog( "%s: Exception %08X %s in %s",
  169.  szThreadName,
  170.                      pExceptionRecord->ExceptionCode,
  171.                      GetExceptionString(pExceptionRecord->ExceptionCode),
  172.  szWhere );
  173. OSVERSIONINFO osv;
  174. // What version of Windows are you running?
  175. osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  176. GetVersionEx(&osv);
  177. ExceptionLog( "OS version: %d.%d Platform ID: %d Build: %d", 
  178.  osv.dwMajorVersion, osv.dwMinorVersion, osv.dwPlatformId, osv.dwBuildNumber );
  179. IntelStackWalk( pExceptionInfo->ContextRecord );
  180. ExceptionLog( "----------" );
  181. g_nExceptionCount++;
  182. return EXCEPTION_EXECUTE_HANDLER ;
  183. }