3GL   4GL   5GL  

  1. (SEH) C++
  2. C++
  3. SEH- ++-
  4. API-SetUnhandledExceptionFilter
  5. CrashHandler API.
  6. EXCEPTION_POINTERS

: , , Application Error, . , , , . , , , .

, Application Error, , , , , . , , , Dr. Watson, , , ? , , bug-tracking?

(crash handlers). , , (exception handlers), (unhandled exception filters). C++ . , , , (Application Error), . C++, Microsoft Visual C++, Microsoft Visual Basic.

, , . , , , . , 32- Microsoft (Win32).

 

(SEH) C++

(exeption handling) , C++ : (Structured Exception Handling SEH), , C++. , , , , . , . , , . . , , .

(SEH) . , . SEH- C/C++ _try/_except _try/_finally. _try/_except : _try, , _except ( (exception handler)). _try/_finally _finally ( (termination handler)) , ( _try/_except), _try .

9-1 SEH-. _except , , (exception filter). 9-1 (EXCEPTION_ EXECUTE_HANDLER) , except , try - () . EXCEPTION_CONTINUE_EXECUTION ( ) EXCEPTION_CONTINUE_SEARCH ( except). , , , .

9-1. SEH-

void Foo ( void) {

__try

{

_try

{

// (). 

}

_except ( EXCEPTION_EXECUTE_HANDLER)

{

// , try 

//  

// . . 

}

_finally

 {

// ,  

// .

 // . 

}

(unwinding the exception). . ( ) . , , , . "" , , . "" , Application Error.

GetExceptionCode, . , , , , " " NaN ( ). 9-2. GetExceptionCode, " ", . , EXCEPTION_CONTINUE_SEARCH , _except ( ).

9-2. SEH-

long IntegerDivide ( long x, long )

 {

long IRet; _try 

{

IRet = x / y; 

}

_except ( EXCEPTION_INT_DIVIDE_BY_ZERO == 

GetExceptionCode ()

? EXCEPTION_EXECUTE_HANDLER

 : EXCEPTION_CONTTNUE_SEARCH 

{

IRet = NaN; 

}

return ( IRet); 

}

, ( , , ). GetExceptionCode, GetExceptionlnformation ( ). EXCEPTION_POINTERS, CPU . , EXCEPTION_POINTERS .

SEH- . API- RaiseException. , . RaiseException , setjmp longjmp ( ).

SEH- , . (): . : SEH- C++, C++- SEH-, . , SEH- , , . C++ (, ), .

, SEH- , ( MSDN). SEH- (Jeffrey Richter, Programming Applications for Microsoft Windows, Microsoft Press, 1999). SEH-, Matt Pietrek, "A Crash Course on the Depths of Win32 Structured Exception Handling" Microsoft Systems Journal 1997 .

 

C++

C++, , , , SEH-. C++ try catch. throw . SEH- , catch C++ , . , . MFC (Microsoft Foundation Class) CException. 9-3 C++ MFC- CFiie.

9-3. ++

BOOL ReadFileHeader ( CFile * pFile, LPHEADERINFO pHeader) 

{

ASSERT ( FALSE == IsBadReadPtr ( pFile, sizeof ( CFile *))); 

ASSERT ( FALSE == IsBadReadPtr ( pHeader,

sizeof ( LPHEADERINFO)) ) ;

if ( ( TRUE == IsBadReadPtr ( pFile, sizeof ( CFile *))) ||

 ( TRUE = IsBadReadPtr ( pHeader,

Sizeof ( LPHEADERINFO) )) ) 

{

return ( FALSE) ; 

}

BOOL bRet;

try ;

{

pFile->Read ( pHeader, sizeof ( HEADERINFO));

 bRet = TRUE; 

}

catch ( CFileException * e) 

{

// - ,

// , ; , 

if ( CFileException:rendOfFile == e->m_cause) 

{

e->Delete(); bRet = false;

}

else {

 

// throw ,

 // catch-.

throw; 

}

return ( bRet); 

}

C++ . -, . ( .) -, C++ . , try catch, , , . , . C++, MSDN , .

 

SEH- ++-

, SEH- ++-. C++. _set_se_transiator C++ , , , C++. . , -:

void SEHToCPPException ( UINT uiEx,

EXCEPTION_POINTERS * pExp) 

{

// CSEHException , MFC- CException

throw CSEHException ( uiEx, pExp); 

}

SEH-, GetExceptionCode, GetExceptionlnformation.

_set_se_transiator , , . , DLL, DLL try.. .catch. , SEH-, . . , , .

, , SEH- C++, , . . , , . -, , EXCEPTION_STACK_OVERFLOW, , .

( SEH- C++), (), . ; , EXCEPTION_POINTERS . C++.

 

C++

C++ . , C++. C++ : , , , .

C++ , , . Visual C++ 5 . , "" . ( ).

, Visual C++ 6, , throw. , , "", throw. : " , , ".

, () _set_se_translator , , ( !). /GX /EHSC ( ), , , /a ( ). , .

( /a), , , _decispec(nothrow). , , _set_se_translator "" .

9-4 , _set_se_ translator, , (. . ) . /. , _set_se_transiator, , , / . ( , C++ MFC) , _set_se_transiator, (-) .

9-4. ,

// () Win32, /GX,

// , - .

// ( /GX /EHsc.)

// , /.

#include "stdafx.h" 

class CSEHError 

{

 public :

CSEHError ( void) 

{

m_uiErrCode = 0; 

}

CSEHError ( unsigned int u) 

{

m_uiErrCode = u; 

}

~CSEHError ( void) 

}

unsigned int m_uiErrCode; 

};

void TransFunc ( unsigned int u, EXCEPTION_POINTERS * pEP) 

{

printf ( "In TransFuncXn"); 

throw CSEHError ( u); 

}

void GrungyFunc ( char * p) 

{.

*P = 'p';

printf ( "This output should never be seen!\n"); 

}

void DoBadThings ( void)

 {

try 

{

GrungyFunc ( (char*)0xl); 

}

catch ( CSEHError e) 

{

printf ( "Got an exception! -> Ox%08X\n", e.m_uiErrCode);

}

int main ( int argc, char* argv[]) 

{

_set_se_translator ( TransFunc);

DoBadThings ();

return 0; 

}

 

API- SetUnhandledExceptionFilter

C++ , , , , . , , , . , , Application Error , , Dr. Watson . , , , . , API- SetUnhandledExceptionFilter , . . , Win32 Microsoft Windows NT 3.5, . (1999) MSDN .

, . , , , , ( ), . . . !

, SetUnhandledExceptionFilter . (SetUnhandledExceptionFilter), , , , . , _except- . , : EXCEPTION_EXECUTE_HANDLER, EXCEPTION_CONTINUE_EXECUTION EXCEPTION_CONTINUE_SEARCH. - , , ++- _set_se_transiator, , . , , MFC. Visual Basic, , Visual Basic. , , - - , - ( , , , , ).

EXCEPTION_POINTERS. 9-5 , . , .

, setunhandiedExceptionFiiter. : , . . Q173652 Knowledge Base , . , C++ : SEH- . Baz CHJTESTS.CPP, , .

: , SetunhandiedExceptionFiiter, . ActiveX- , , . SetunhandiedExceptionFiiter; , .

 

CrashHandler API

BUGSLAYERUTIL.DLL CrashHandler API, . , , , . , . , , ( ), , . , CrashHandler API, . CrashHandler API 9-5.

9-5. CrashHandler.PP

/*- - - - - - - - - - - - - - - - - - - - 

"Debugging Applications" (Microsoft Press)

Copyright () 1997-2000 John Robbing All rights reserved.

:

WORK_AROUND_SRCLINE_BUG  

SymGetLineFromAddr; PDB-. DBGHELP.DLL, , IMAGEHLP.DLL.

 - - - - - - - - - - - - - - - - - - - - - - - - -*/

#include "pch.h"

#include "BugslayerUtil.h"

#include "CrashHandler.h"

//

#include "Internal.h"

/*////////////////////////////////////

////////////////////////////////////////////////* 

,  

#define MAX_SYM_SIZE 256

#define BUFF_SIZE 1024

#define SYM_BUFF_SIZE 512

/*///////////////////////////////////////////////////

////////////////////////////////////////////////////*

// ( )

 static PFNCHFILTFN g_pfnCallBack = NULL;

 //

 static LPTOP_LEVEL_EXCEPTION_FILTER g_pfnOrigFilt = NULL;

 //  

static HMODULE * g_ahMod = NULL; 

// g_ahMod ( )

 static UINT g_uiModCount = 0;

// , .  

// , 

static TCHAR g_szBuff [ BUFF_SIZE ]; 

//

 static BYTE g_stSymbol [ SYM_BUFF_SIZE ];

//

static IMAGEHLP_LINE g_stLine;

// ,

static STACKFRAME g_stFrame;

// , ,

static BOOL g_bSymEngInit = FALSE;

/*////////////////////////////////////////////////////

/////////////////////////////////////////////////////*/

//

LONG _stdcall CrashHandlerExceptionFilter ( EXCEPTION_POINTERS *

pExPtrs );

//  

LPCTSTR ConvertSimpleException ( DWORD dwExcept);

 // ,

 LPCTSTR _stdcall

InternalGetStackTraceString ( DWORD dwOpts ,

EXCEPTION_POINTERS * pExPtrs); 

// SymGetLineFromAddr

BOOL InternalSymGetLineFromAddr ( IN HANDLE hProcess ,

IN DWORD dwAddr , 

OUT PDWORD pdwDisplacement, 

OUT PIMAGEHLP_LINE Line , );

// , void InitSymEng ( void);

// ,

 void CleanupSymEng ( void); 

/*/////////////////////////////////////////////////

//////////////////////////////////////////////////*/ 

// . MEMDUMPVALIDATOR.CPP . 

// : initializers put in library initialization 

// area ( )

 #pragma warning (disable : 4073) 

#pragma init_seg(lib) 

class CleanUpCrashHandler

 {

 public :

CleanUpCrashHandler ( void)

{

}

--CleanUpCrashHandler ( void)

{

// ?

 if ( NULL != g_ahMod)

{

VERIFY ( HeapFree ( GetProcessHeap (), 

0

g_ahMod )); 

g_ahMod = NULL; 

}

if ( NULL != g_pfnOrigFilt) 

{

/  

// .

SetUnhandledExceptionFilter ( g_pfnOrigFilt);

 }

}

};

//

static CleanUpCrashHandler g_cBeforeAndAfter;

 /*/////////////////////////////////////////////////

////////////////////////////////////////////////*/ 

BOOL _stdcall SetCrashHandlerFilter ( PFNCHFILTFN pFn) 

{

// NULL- "" .

if { NULL == pFn)

{

if ( NULL != g_pfnOrigFilt) 

{

//  

// .

SetUnhandledExceptionFilter ( g_pfnOrigFilt); 

g_pfnOrigFilt = NULL;

 if ( NULL ! = g_ahMod) 

{

free ( g_ahMod);

 g_ahMod = NULL; 

}

g_pfnCallBack = NULL;

}

else 

{

ASSERT ( FALSE == IsBadCodePtr ( (FARPROC)pFn));

if ( TRUE == IsBadCodePtr { (FARPROC)pFn))

{

return ( FALSE);

 }

g_pfnCallBack = pFn;

// ,

// CrashHandlerExceptionFilter

// .

if ( NULL = = g_pfnOrigFilt)

{

g_pfnOrigFilt =

SetUnhandledExceptionFilter( CrashHandlerExceptionFilter); 

 }

return ( TRUE); 

}

BOOL _stdcall AddCrashHandlerLimitModule ( HMODULE hMod)

 {

//

 ASSERT ( NULL != hMod);

 if ( NULL == hMod) 

{

return ( FALSE); 

}_

// .

 // , , // . ,

 // , , ,  

// . 

HMODULE * phTemp = (HMODULE*)

HeapAlloc ( GetProcessHeap () ,

 HEAP_ZERO_MEMORY |

HEAP_GENERATE_EXCEPTIONS , 

( sizeof ( HMODULE) * ( g_uiModCount+l)) );

 ASSERT ( NULL != phTemp);

 if ( NULL = phTemp) 

{

TRACE0 ( "Serious trouble in the house! _ "

 "HeapAlloc failed!!!\n" );

return ( FALSE); 

}

if ( NULL = g_ahMod) 

{

g_ahMod = phTemp;

  g_ahMod[ 0 ] = hMod;

 g_uiModCount++; 

}

else

 {

// . 

CopyMemory ( phTemp ,

 g_ahMod ,

sizeof ( HMODULE) * g_uiModCount) ; 

// .

VERIFY ( HeapFree ( GetProcessHeap (), 0, g_ahMod));

 g_ahMod = phTemp; 

g_ahMod[ g_uiModCount ] = hMod; 

g_uiModCount++; 

}

return ( TRUE);

 }

UINT _stdcall GetLimitModuleCount ( void) 

{

return ( g_uiModCount); 

}

int _stdcall GetLimitModulesArray ( HMODULE * pahMod, UINT uiSize)

 {

int iRet;

_try

{

ASSERT ( FALSE == IsBadWritePtr ( pahMod,

uiSize * sizeof ( HMODULE)));

 if ( TRUE == IsBadWritePtr ( pahMod,

uiSize * sizeof ( HMODULE)))

 {

iRet = GLMA_BADPARAM;

 _leave;

 }.

if ( uiSize < g_uiModCount) 

{

iRet = GLMA_BUFFTOOSMALL; 

_leave; 

}

CopyMemory ( pahMod ,

 g_ahMod ,

sizeof ( HMODULE) * g_uiModCount);

 iRet = GLMA_SUCCESS;

 }

_except ( EXCEPTION_EXECUTE_HANDLER) 

{

iRet = GLMA_FAILURE; 

}

return ( iRet); 

}

LONG _stdcall GrashHandlerExceptionFilter ( EXCEPTION_POINTERS* pExPtrs) { 

 LONG IRet = EXCEPTION_CONTINUE_SEARCH;

// EXCEPTION_STACK_OVERFLOW ( 

// ), ,  

// . , , // . 

// ,  

// ,  

// . , // , .

 // // OutputDebugString. ,  

// , OutputDebugString

 // ( 8-16 ), .

 //

 // DebugView/Enterprise Edition

// (Mark Russinovich) www.sysinternals.com.

 //

// , ,

 // . 

// , EXCEPTION_STACK_OVERFLOW .

 // , .

 // ,

 // , .

 if ( EXCEPTION_STACK_OVERFLOW ==

pExPtrs->ExceptionRecord->ExceptionCode)

 {

OutputDebugString ( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); 

OutputDebugString ( "EXCEPTION_STACK_OVERFLOW occurred\n"); OutputDebugString ( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); 

}

_try

 {

if ( NULL != g_pfnCallBack)

 {

// ,

//

// ,

// .

InitSymEng ();

// g_ahMod.

BOOL bCalllt = FALSE;

if ( 0 == g_uiModCount)

{

bCalllt = TRUE;

}

else {

HINSTANCE hBaseAddr = (HINSTANCE)

SymGetModuleBase ((HANDLE)GetCurrentProcessId (), (DWORD)pExPtrs->

ExceptionRecord->

ExceptionAddress);

 if ( NULL != hBaseAddr) 

{

for ( UINT i = 0; i < g__uiModCount; i ++) 

{

if ( hBaseAddr == g_ahMod[ i ]) 

{

bCalllt = TRUE; break; 

}

 }

 }

if ( TRUE == bCalllt) 

{

// ,

 // .

// ,

 // ,  

// . , -  

// , .

ASSERT ( FALSE == IsBadCodePtr( (FARPROC)g_pfnCallBack));

 if ( FALSE == IsBadCodePtr ( (FARPROC)g_pfnCallBack)) 

{

IRet = g_pfnCallBack ( pExPtrs); 

}

else 

{

// , , 

// . !:) 

ASSERT ( FALSE == IsBadCodePtr ( (FARPROC) g__pfnOrigFilt) ) ;

 if ( FALSE == IsBadCodePtr ( (FARPROC)g_pfnOrigFiIt)) 

{

IRet = g_pfnOrigFilt ( pExPtrs); 

}

}

CleanupSymEng (); 

}

_except ( EXCEPTION_EXECUTE_HANDLER) 

{

IRet = EXCEPTION_CONTINUE_SEARCH; 

}

return ( IRet); 

/*/////////////////////////////////////////////

- EXCEPTION_POINTER-yp

//////////////////////////////////////////////*/

 LPCTSTR _stdcall GetFaultReason ( EXCEPTION_POINTERS * pExPtrs) {

ASSERT ( FALSE == IsBadReadPtr ( pExPtrs,

sizeof ( EXCEPTION_POINTERS)));

 if ( TRUE = IsBadReadPtr ( pExPtrs,

sizeof ( EXCEPTION_POINTERS))) 

{

TRACEO ( "Bad parameter to GetFaultReasonA\n"); 

return ( NULL); 

}

// ,

 LPCTSTR szRet;

 _try 

{

// ,

 // . 

InitSymEng (); 

//

int iCurr = 0;

// .  

// .

 DWORD dwTemp;

iCurr += BSUGetModuleBaseName ( GetCurrentProcess (),

NULL 

, g_szBuff , 

BUFF_SIZE );

iCurr += wsprintf ( g_szBuff + iCurr, _T ( " caused an "));

 dwTemp = (DWORD)

ConvertSimpleException ( pExPtrs->ExceptionRecord->

ExceptionCode);

 if ( NULL != dwTemp)

 {

iCurr += wsprintf ( g_szBuff + iCurr, _T ( "%s") dwTemp );

 }

else 

{

iCurr += ( FormatMessage ( FORMAT_MESSAGE_IGNORE_INSERTS |

FORMAT_MESSAGE_FROM_HMODULE,

 GetModuleHandle (_T("NTDLL.DLL")), 

pExPtrs->ExceptionRecord->

ExceptionCode,

0,

g_szBuff + iCurr ,

 BUFF_SIZE,

0 )

 * sizeof ( TCHAR)); 

}

ASSERT ( iCurr < ( BUFF_SIZE - MAX_PATH));

iCurr += wsprintf ( g_szBuff + i.Curr, _T ( " in module ") ) ;

 dwTemp =

SymGetModuleBase ( (HANDLE)GetCurrentProcessId (),

(DWORD)pExPtrs->ExceptionRecord->

ExceptionAddress); 

ASSERT ( NULL != dwTemp);

 if ( NULL == dwTemp) 

{

iCurr += wsprintf ( g_szBuff + iCurr, _T ( "<UNKNOWN>")); 

}

else 

{

iCurr += BSUGetModuleBaseName ( GetCurrentProcess () ,

(HINSTANCE)dwTemp , 

g_szBuff + iCurr

 BUFF_SIZE - iCurr ); 

#ifdef _WIN64

iCurr += wsprintf ( g_szBuff + iCurr ,

 _T ( " at %016X") ,

pExPtrs->ExceptionRecord->ExceptionAddress); 

#else

iCurr += wsprintf ( g_szBuff + iCurr , 

_T ( " at %04X:%08X") ,

 pExPtrs->ContextRecord->SegCs ,

 pExPtrs->ExceptionRecord->ExceptionAddress);

 #endif

ASSERT ( iCurr < ( BUFF_SIZE _ 200)); 

// .

PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)&g_stSymbol;

 FillMemory ( pSym, NULL, SYM_BUFF_SIZE);

pSym->SizeOfStruct = sizeof ( IMAGEHLP_SYMBOL);

pSym->MaxNameLength = SYM_BUFF_SIZE - sizeof ( IMAGEHLP_SYMBOL); 

DWORD dwDisp;

 if ( TRUE ==

SymGetSymFromAddr ( (HANDLE)GetCurrentProcessId () ,

 (DWORD)pExPtrs->ExceptionRecord->

ExceptionAddress ,

SdwDisp , 

pSym ) ) 

iCurr += wsprintf ( g_szBuff + iCurr, _T ( ", ")); 

// ,

 // .

 dwTemp = Istrlen ( pSym->Name);

// ,

 // .

if ( (int)dwTemp > ( ( BUFF_SIZE _ iCurr) -

( MAX_SYM_SIZE +50) ))

 {

Istrcpyn ( g_szBuff + iCurr , 

pSym->Name , 

BUFF_SIZE - iCurr - 1 );

 //

 szRet = g_szBuff; _leave; 

}

else

 {

if ( dwDisp > 0)

 {

iCurr += wsprintf ( g_szBuff + iCurr , 

_T ( "%s()+%04d byte(s)"), 

pSym->Name , 

dwDisp ); 

}

else 

{

iCurr += wsprintf ( g_szBuff + iCurr, 

_T ( "%s ") pSym->Name ) ; 

}

else 

{

// ,  

// , .

 szRet = g_szBuff;

_leave; 

}

ASSERT ( iCurr < ( BUFF_SIZE _ 200));

 // .

 ZeroMemory ( &g_stLine, sizeof ( IMAGEHLP_LINE));

 g_stLine.SizeOfStruct = sizeof ( IMAGEHLP_LINE);

if ( TRUE ==

InternalSymGetLineFromAddr ( (HANDLE)

GetCurrentProcessId () , 

(DWORD)pExPtrs->

ExceptionRecord->

ExceptionAddress, 

SdwDisp ,

 &g_stLine )) 

{

iCurr += wsprintf ( g_szBuff + iCurr, _T ( ", ")); 

//  

// , . 

dwTemp = Istrlen ( g_stLine.FileName);

 if ( (int)dwTemp > ( BUFF_SIZE - iCurr

_ MAX_PATH _ 50 ))

{

Istrcpyn ( g_szBuff + iCurr ,

g_stLine.FileName , 

BUFF_SIZE - iCurr - 1); 

//  

szRet = g_szBuff; 

_leave;

}

else 

{

if ( dwDisp > 0)

 {

iCurr += wsprintf ( g_szBuff + iCurr ,

 _T("%s, line %04d+%04d byte(s)"),

 g_stLine.FileName ,

 g_stLine. LineNumber , 

dwDisp ) ; 

}

 else

{

iCurr += wsprintf ( g_szBuff + iCurr , 

_T ( "%s, line %04d"),

g_stLine.FileName , 

g_stLine.LineNumber); 

}

szRet = g_szBuff; 

}

_except ( EXCEPTION_EXECUTE_HANDLER)

 {

ASSERT ( !"Crashed in GetFaultReason"); 

szRet = NULL;

 }

return ( szRet); 

}

BOOL _stdcall GetFaultReasonVB ( EXCEPTION_POINTERS * pExPtrs,

LPTSTR szBuff , UINT uiSize ) 

{

ASSERT ( FALSE == IsBadWritePtr ( szBuff, uiSize));

if ( TRUE == IsBadWritePtr ( szBuff, uiSize))

{

return ( FALSE); 

}

LPCTSTR szRet;  

__try 

{

szRet = GetFaultReason ( pExPtrs); 

ASSERT ( NULL != szRet);

 if ( NULL == szRet) 

{

_leave; 

}

Istrcpyn ( szBuff , 

szRet ,

min ( (UINT)Istrlen ( szRet) + 1, uiSize)); 

}

_except ( EXCEPTION_EXECUTE_HANDLER) 

{

szRet = NULL; 

}

return ( NULL != szRet); 

}

LPCTSTR BUGSUTIL_DLLINTERFACE _stdcall

GetFirstStackTraceString ( DWORD dwOpts ,

EXCEPTION_POINTERS * pExPtrs)

{

//  

// InternalGetStackTraceString

// STACKFRAME . 

ZeroMemory ( &g_stFrame, sizeof ( STACKFRAME));

#ifdef _X86_

g_stFrame.AddrPC.Offset = pExPtrs->ContextRecord->Eip;

 g_stFrame.AddrPC.Mode  = AddrModeFlat ; 

g_stFrame.AddrStack.Offset = pExPtrs->ContextRecord->Esp;

 g_stFrame.AddrStack.Mode = AddrModeFlat ;

g_stFrame.AddrFrame.Offset = pExPtrs->ContextRecord->Ebp;

 g_stFrame.AddrFrame.Mode = AddrModeFlat ;

#else

g_stFrame.AddrPC.Offset = (DWORD)pExPtrs->ContextRecord->Fir;

 g_stFrame.AddrPC.Mode = AddrModeFlat;

 g_stFrame.AddrReturn.Offset =

(DWORD)pExPtrs->ContextRecord->IntRa; 

g_stFrame.AddrReturn.Mode = AddrModeFlat; 

g_stFrame.AddrStack.Offset =

(DWORD)pExPtrs->ContextRecord->IntSp; 

g_stFrame.AddrStack.Mode = AddrModeFlat; 

g_stFrame.AddrFrame.Offset -

(DWORD)pExPtrs->ContextRecord->IntFp; 

g_stFrame.AddrFrame.Mode = AddrModeFlat;

#endif

return ( InternalGetStackTraceString ( dwOpts, pExPtrs)); 

}

 LPCTSTR BUGSUTIL_DLLINTERFACE _stdcall

GetNextStackTraceString ( DWORD dwOpts ,

EXCEPTION_POINTERS * pExPtrs) 

{

// InternalGetStackTraceString.

 // , GetFirstStackTraceString  

// ,

 return ( InternalGetStackTraceString ( dwOpts, pExPtrs)); 

}

BOOL _stdcall CH__ReadProcessMemory ( HANDLE ,

LPCVOID IpBaseAddress ,

 LPVOID IpBuffer , 

DWORD nSize ,

 LPDWORD IpNumberOfBytesRead ) 

{

return ( ReadProcessMemory ( GetCurrentProcess (),

IpBaseAddress ,

 IpBuffer ,

nSize , 

IpNumberOfBytesRead ));

}

// ,

LPCTSTR _stdcall

InternalGetStackTraceString ( DWORD dwOpts ,

EXCEPTION_POINTERS * pExPtrs ) 

{

ASSERT ( FALSE == IsBadReadPtr ( pExPtrs

sizeof ( EXCEPTION_POINTERS)));

 if ( TRUE == IsBadReadPtr ( pExPtrs ,

sizeof ( EXCEPTION_POINTERS))) 

{

TRACED ( "GetStackTraceString invalid pExPtrs!\n");

 return ( NULL); 

}

// LPCTSTR szRet;

// .  

// . DWORD dwTemp;

// .

 // , , . 

DWORD dwModBase; 

_try 

{

// ,

 // . 

InitSymEng ();

#ifdef _WIN64

#define CH_MACHINE IMAGE_FILE_MACHINE_IA64

 #else

#define CH_MACHINE IMAGE_FILE_MACHINE_I386

#endif

// :

// , StackWalk

// .

BOOL bSWRet = StackWalk ( CH_MACHINE ,

(HANDLE)GetCurrentProcessId () , 

GetCurrentThread () , 

&g_stFrame , 

pExPtrs->ContextRecord ,

 (PREAD_PROCESS_MEMORY_ROUTINE)

CH_ReadProcessMemory , 

SymFunctionTableAccess ,

 SymGetModuleBase , 

NULL ) ;

if ( ( FALSE = bSWKet) 11(0= g_stFrame.AddrFrame.Offset)) 

{

szRet = NULL; 

_leave; 

}

// ,

// , ,

 // StackWalk, . ,

 // StackWalk, TRUE,  

// . 

dwModBase = SymGetModuleBase ( (HANDLE)GetCurrentProcessId (),

g_stFrame.AddrPC.Offset ); 

if ( 0 == dwModBase) 

{

szRet = NULL;

 _leave; 

}

int iCurr = 0;

// , 

#ifdef _WIN64

iCurr += wsprintf ( g_szBuff + iCurr , 

_T ( "Ox%016X") ,

g_stFrame.AddrPC.Offset );

 #else

iCurr += wsprintf ( g_szBuff + iCurr , 

_T ( "%04X:%08X") 

pExPtrs->ContextReeord->SegCs, g_stFrame.AddrPC.Offset ); 

#endif

// ?

if ( GSTSO_PARAMS == ( dwOpts & GSTSO_PARAMS))

{

iCurr += wsprintf ( g_szBuff + iCurr , 

_T ( " ( Ox%08X Ox%08X "\

"Ox%08X Ox%08X)"), 

g_stFrame.Params[ 0 ] ,

 g_stFrame.Params[ 1 ] ,

 g_stFrame.Params[ 2 ] ,

 g_stFrame.Params[ 3 ] ); 

}

// .

if ( GSTSO_MODULE = ( dwOpts & GSTSO_MODULE)) 

{

iCurr += wsprintf ( g_szBuff + iCurr , _T ( " ")); 

ASSERT ( iCurr < ( BUFF_SIZE - MAX_PATH));

iCurr += BSUGetModuleBaseName ( GetCurrentProcess (),

(HINSTANCE)dwModBase,

 g_szBuff + iCurr , 

BUFF_SIZE - iCurr ); 

}

ASSERT ( iCurr < ( BUFF_SIZE - MAX_PATH)); 

DWORD dwDisp; 

// ?

if ( GSTSO_SYMBOL == ( dwOpts & GSTSO_SYMBOL)) 

{

// .

PIMAGEHLP_SYMBOL pSym = (PIMAGEHLP_SYMBOL)Sg_stSymbol;

ZeroMemory ( pSym, SYM_BUFF_SIZE);

pSym->SizeOfStruct = sizeof ( IMAGEHLP_SYMBOL);

pSym->MaxNameLength = SYM_BUFF_SIZE -

sizeof ( IMAGEHLP_SYMBOL); 

if ( TRUE ==

SymGetSymFromAddr ( (HANDLE)GetCurrentProcessId () ,

g_stFrame.AddrPC.Offset , 

sdwDisp , 

pSym )) 

{

iCurr += wsprintf ( g_szBuff + iCurr, _T ( ", ")); 

// ,  

// . 

dwTeitip = Istrlen ( pSym->Name) ;

 if ( dwTeitip > (DWORD) ( BUFF_SIZE - iCurr _

 ( MAX_SYM_SIZE + 50)))

 {

Istrcpyn ( g_szBuff + iCurr ,

 pSym->Name , 

BUFF_SIZE - iCurr - 1 );

 //  

szRet = g_szBuff;

_leave;

 }

else 

{

if ( dwDisp > 0)

 {

iCurr += wsprintf ( g_szBuff + iCurr , 

_T( "%s()+%04d byte(s)"), 

pSym->Name , 

dwDisp ) ;

 }

else 

{

iCurr += wsprintf ( g_szBuff + iCurr,

 _T ( "%s") 

pSym->Name ) ; 

}

 } 

}

else 

{

// ,  

// , .

 szRet = g_szBuff;

_leave; 

}

ASSERT ( iCurr < ( BUFF_SIZE - MAX_PATH)); 

// ?

 if ( GSTSO_SRCLINE == ( dwOpts & GSTSO_SRCLINE))

{

ZeroMemory ( &g_stLine, sizeof ( IMAGEHLP_LINE));

 g_stLine.SizeOfStruct = sizeof ( IMAGEHLP_LINE);

 if ( TRUE ==

InternalSymGetLineFromAddr ( (HANDLE)

GetCurrentProcessId (), 

g_stFrame.AddrPC.Offset , 

SdwDisp , 

&g_stLine ))

{

iCurr += wsprintf ( g_szBuff + iCurr, _T ( ", "));

 //  

// , .

 dwTemp = Istrlen ( g_stLine.FileName); 

if ( dwTerap > (DWORD)( BUFF_SIZE - iCurr 

_ ( MAX_PATH +50 ))) {

Istrcpyn ( g_szBuff + iCurr ,

 g_stLine.FileName , 

BUFF_SIZE - iCurr - 1 );

 //

 szRet = g_szBuff; 

_leave; 

}

else

 {

if { dwDisp > 0)

{

iCurr += wsprintf(g_szBuff + iCurr ,

_T("%s, line %04d+%04d byte(s)"),

g_stLine.FileName ,

g_s tLine.LineNumbe r ,

dwDisp ) ;

}

else

 {

iCurr += wsprintf ( g_szBuff + iCurr ,

 _T ( "%s, line %04d") ,

 g_stLine.FileName ,

 g_stLine.LineNumber ); 

}

}

 }

szRet = g_szBuff; 

}

_except ( EXCEPTION_EXECUTE_HANDLER)

 {

ASSERT ( !"Crashed in InternalGetStackTraceString"); 

szRet = NULL; 

}

return ( szRet); 

BOOL _stdcall

GetFirstStackTraceStringVB ( DWORD dwOpts ,

EXCEPTION_POINTERS * pExPtrs, 

LPTSTR szBuff , 

UINT uiSize ) 

{

ASSERT ( FALSE == IsBadWritePtr ( szBuff, uiSize));

if ( TRUE = IsBadWritePtr ( szBuff, uiSize))

{

return ( FALSE); 

}

LPCTSTR szRet; 

_try 

{

szRet = GetNextStackTraceString ( dwOpts, pExPtrs);

if ( NULL == szRet)

{

_leave;

 }

Istrcpyn ( szBuff , szRet ,

min ( (UINT)lstrlen ( szRet) + I, uiSize)); 

}

_except ( EXCEPTION_EXECUTE_HANDLER) 

{

szRet = NULL; 

}

return ( NULL != szRet); 

}

LPCTSTR _stdcall GetRegisterString ( EXCEPTION_POINTERS * pExPtrs) {

// .

ASSERT ( FALSE = IsBadReadPtr ( pExPtrs ,

sizeof ( EXCEPTION_POINTERS)));

 if { TRUE = IsBadReadPtr ( pExPtrs ,

sizeof ( EXCEPTION_POINTERS))) 

{

TRACED ( "GetRegisterString - invalid pExPtrs!\n"); 

return ( NULL); 

}

#ifdef _WIN64

ASSERT ( !"IA64 is not supported (YET!) ");

#else

// 48 , ,

 // ,

 wsprintf ( g_szBuff,

_ ( "=%08 =%08 =%08 EDX=%08X ESI=%08X\n"\

"EDI=%08X EBP=%08X ESP=%08X EIP=%08X FLG=%08X\n"\

"CS=%04X DS=%04X SS=%04X ES=%04X "\

"FS=%04X GS=%04X"),

pExPtrs->ContextRecord->Eax ,

pExPtrs->ContextRecord->Ebx ,

pExPtrs->ContextRecord->Ecx ,

pExPtrs->ContextRecord->Edx ,

pExPtrs->ContextRecord->Esi ,

pExPtrs->ContextRecord->Edi ,

pExPtrs->ContextRecord->Ebp ,

pExPtrs->ContextRecord->Esp ,

pExPtrs->ContextRecord->Eip ,

pExPtrs->ContextRecord->EFlags ,

pExPtrs->ContextRecord->SegCs ,

pExPtrs->ContextRecord->SegDs ,

pExPtrs->ContextRecord->SegSs ,

pExPtrs->ContextRecord->SegEs ,

pExPtrs->ContextRecord->SegFs ,

 pExPtrs->ContextRecord->SegGs ); 

#endif

return ( g_szBuff); 

}

BOOL _stdcall GetRegisterStringVB ( EXCEPTION_POINTERS * pExPtrs,

LPTSTR szBuff , UINT uiSize )

 {

ASSERT ( FALSE == IsBadWritePtr ( szBuff, uiSize));

if ( TRUE == IsBadWritePtr ( szBuff, uiSize))

{

return ( FALSE); 

}

LPCTSTR szRet; 

_try 

{

szRet = GetRegisterString ( pExPtrs);

if ( NULL = szRet)

{

_leave; 

}

Istrcpyn ( szBuff , szRet ,

min ( (UINT)Istrlen ( szRet) + 1, uiSize)); 

}

_except ( EXCEPTION_EXECUTE_HANDLER) {

szRet = NULL; 

}

return ( NULL != szRet); 

}

LPCTSTR ConvertSimpleException ( DWORD dwExcept) 

{

switch ( dwExcept) 

{

case EXCEPTION_ACCESS_VIOLATION :

return ( _T ( "EXCEPTION_ACCESS_VIOLATION")); 

break;

 case EXCEPTION_DATATYPE_MISALIGNMENT :

return ( _T ( "EXCEPTION_DATATYPE_MISALIGNMENT"));

 break; 

case EXCEPTION_BREAKPOINT :

return ( _T ( "EXCEPTION_BREAKPOINT")); 

break;

case EXCEPTION_SINGLE_STEP :

return ( _T ( "EXCEPTION_SINGLE_STEP")); 

break; 

case EXCEPTION_ARRAY_BOUNDSJEXCEEDED

return ( _T ( "EXCEPTION_ARRAY_BOUNDS_EXCEEDED")); 

break; 

case EXCEPTION_FLT_DENORMAL_OPERAND :

return ( _T ( "EXCEPTION_FLT_DENORMAL_OPERAND")); 

break; 

case EXCEPTION_FLT_DIVIDE_BY_ZERO :

return ( _T ( "EXCEPTION_FLT_DIVIDE_BY_ZERO")); 

break;

 case EXCEPTION_FLT_INEXACT_RESULT :

return ( _T ( "EXCEPTION_FLT_INEXACT_RESULT")); 

break;

 case EXCEPTION_FLT_INVALID_OPERATION :

return ( _T ( "EXCEPTION_FLT_INVALID_OPERATION")); 

break; 

case EXCEPTION_FLT_OVERFLOW :

return ( _T ( "EXCEPTION_FLT_OVERFLOW"));

 break; 

case EXCEPTION_FLT_STACK_CHECK :

return ( _T ( "EXCEPTION_FLT_STACK_CHECK")); 

break; 

case EXCEPTION_FLT_UNDERFLOW :

return ( _T ( "EXCEPTION_FLT_UNDERFLOW")); break; case EXCEPTION_INT_DIVIDE_BY_ZERO :

return ( _T ( "EXCEPTION_INT_DIVIDE_BY_ZERO")); 

break;

 case EXCEPTION_INT_OVERFLOW :

return ( _T ( "EXCEPTION_INT_OVERFLOW")); 

break;

 case EXCEPTION_PRIV_INSTRUCTION :

return ( _T ( "EXCEPTION_PRIV_INSTRUCTION"));

 break; 

case EXCEPTION_IN_PAGE_ERROR :

return ( _T ( "EXCEPTION_IN_PAGE_ERROR"));

 break; 

case EXCEPTION_ILLEGAL_INSTRUCTION :

return ( _T ( "EXCEPTION_ILLEGAL_INSTRUCTION"));

 break; 

case EXCEPTION_NONCONTINUABLE_EXCEPTION :

return ( _T ( "EXCEPTION_NONCONTINUABLE_EXCEPTION")); break;

case EXCEPTION_STACK_OVERFLOW :

return ( _T ( "EXCEPTION_STACK_OVERFLOW")); 

break;

 case EXCEPTION_INVALID_DISPOSITION :

return ( _T ( "EXCEPTION_INVALID_DISPOSITION")); 

break; 

case EXCEPTION_GUARD_PAGE :

return ( _T ( "EXCEPTION_GUARD_PAGE")); 

break; 

case EXCEPTION_INVALID_HANDLE :

return ( _T ( "EXCEPTION_INVALID_HANDLE"));

 break;

 default :

return ( NULL); 

break; 

}

BOOL InternalSymGetLineFromAddr ( IN HANDLE hProcess ,

IN DWORD dwAddr ,

 OUT PDWORD pdwDisplacement, 

OUT PIMAGEHLP_LINE Line ) 

#ifdef WORK_AROUND_SRCLINE_BUG

// ,  

// ( ),  

// . 100 , 

// , .

 DWORD dwTempDis = 0;

while ( FALSE == SymGetLineFromAddr ( hProcess ,

dwAddr -

dwTempDis ,

 pdwDisplacement, 

Line ) ) 

{

dwTempDis += 1;

if ( 100 == dwTempDis)

{

return ( FALSE);

 } 

}

// , 

// ,  

// , ,

 if ( 0 != dwTempDis) 

{

*pdwDisplacement = dwTempDis; 

}

return ( TRUE);

#else // WORK_AROUND_SRCLINE_BUG

return ( SymGetLineFromAddr ( hProcess ,

dwAddr ,

 pdwDisplacement , 

Line ));

#endif

}

// ,

void InitSymEng ( void)

{

if ( FALSE == g_bSymEngInit)

{

// .

DWORD dwOpts = SymGetOptions ();

// .

 SymSetOptions ( dwOpts |

 SYMOPT_DEFERRED_LOADS |

 SYMOPT_LOAD_LINES );

// ,

 // , . 

HANDLE hPID = (HANDLE)GetCurrentProcessId (); 

VERIFY ( BSUSymlnitialize ( (DWORD)hPID,

hPID , 

NULL , 

TRUE ));

 g_bSymEngInit = TRUE; 

}

// , ,

 void CleanupSymEng ( void) CrashHandler

{

if ( TRUE == g_bSymEngInit) 

{

VERIFY ( SymCleanup ( (HANDLE)GetCurrentProcessId ()));

 g_bSymEngInit = FALSE;

 } 

}

, SetCrashHandierFiiter, SetUnhandledExceptionFilter, CrashHandlerExceptionFilter. - , , CrashHandlerExceptionFilter , , . , , , , API-. SetCrashHandierFiiter , NULL- , .

AddCrashHandierLimitModuie , , . , ( HMODULE hMod). , AddCrashHandierLimitModuie . .

9-5, , - (run-time) C++. , , . , , , BUGSLAYERUTIL.DLL . GetLimitModuleCount GetLimitModulesArray, . RemoveCrashHandlerLimitModule .

CRASHHANDLER.CPP DBGHELP.DLL. , , . Syminitiaiize, (finvadeProcess) TRUE. , Windows 2000, Windows 98. Windows 98, Bsusyminitialize BUGSLAYERUTIL.DLL, .

 

EXCEPTION_POINTERS

, EXCEPTION_POINTERS, . , , , . ( ). 9-5.

, . , EXCEPTION_POINTERS. , . , , "", "VB1". , VB- , -. , EXCEPTION_POINTERS , , . , , Visual Basic , . -, - , . Visual Basic , .

  Visual Basic. .

GetRegisterString . GetFauitReason , . , , , , , , , :

CH_TESTS.EXE caused an EXCEPTION_ACCESS_VIOLATION in module CH_TESTS.EXE at 001B:004010FB, Baz()+0064 bytes, CHJTests.cpp, line 0060+0003 bytes

GetFirstStackTraceString GetNextstackTracestring. , . API- FindFirstFiie FindNextFile, GetFirstStackTraceString , GetNextstackTracestring , FALSE. EXCEPTION_POINTERS, , , . , () :

001:004018 (0x00000001 Ox008COF90 Ox008C0200 Ox77F8FE94) CH_TESTS.EXE, main()+1857 bytes, CHJTests., line 0341+0007 bytes

. . 9.1 .

9.1. GetFirststackTraceString GetNextStackTraceString

0

GSTSO_PARAMS

GSTSO MODULE

GSTSO SYMBOL

GSTSO_SRCLINE

 

. 9.1. CrashTest

, CD . , CH_TEST, C/C++, , CrashTest, Visual Basic. , . . 9.1 CrashTest .

 

, . . Visual C++, Visual Basic, Visual C++.

C++- SEH-. C++, SEH- . . , C++- SHE- _set_se_translator C++. , C++. : " , , ".

SetunhandiedExceptionFiiter, SEH- . , Application Error, . (CrashHandler) , .

        3GL   4GL   5GL  

, , Statechart diagram - - , .




 10.11.2021 - 12:37: - Personalias -> WHO IS WHO - - _.
10.11.2021 - 12:36: - Conscience -> . ? - _.
10.11.2021 - 12:36: , , - Upbringing, Inlightening, Education -> ... - _.
10.11.2021 - 12:35: - Ecology -> - _.
10.11.2021 - 12:34: , - War, Politics and Science -> - _.
10.11.2021 - 12:34: , - War, Politics and Science -> . - _.
10.11.2021 - 12:34: , , - Upbringing, Inlightening, Education -> , - _.
10.11.2021 - 09:18: - New Technologies -> , 5G- - _.
10.11.2021 - 09:18: - Ecology -> - _.
10.11.2021 - 09:16: - Ecology -> - _.
10.11.2021 - 09:15: , , - Upbringing, Inlightening, Education -> - _.
10.11.2021 - 09:13: , , - Upbringing, Inlightening, Education -> - _.
Bourabai Research -  XXI Bourabai Research Institution