December 01, 2002
Visual C++ Exception-Handling Instrumentation
December 2002/Visual C++ Exception-Handling Instrumentation
Listing 3 Logging an exception
void PreviewException(void * pObject,
void * pThrowAddress,
const type_info * pObjectInfo)
{
pObject; //reference parameter
if (pObjectInfo)
std::cout << "Exception of type \""
<< pObjectInfo->name()
<< "\" occured at "
<< pThrowAddress
<< "\n";
}
// this processor-specific function returns
// the return address of the caller
// assuming that callers frame was not optimized
__declspec(naked)
void * GetReturnAddress()
{
__asm
{
mov eax, [ebp + 4]
ret
}
}
// this processor-specific function returns
// the stack frame of the caller's caller
// assuming that frames were not optimized
__declspec(naked)
void * GetCallerFrame()
{
__asm
{
mov eax, [ebp]
ret
}
}
// imhibit optimization of frames
#pragma optimize("y",off)
extern "C"
void __stdcall _CxxThrowException(void * pObject,
_s__ThrowInfo const * pObjectInfo)
{
void * paddr = GetReturnAddress();
// call __CxxThrowException@8 is 5 bytes
// long on i386. Subtracting 5 from return address
// gives us the address of call instruction
paddr = (void*)((DWORD_PTR)paddr - 5);
void * pframe = GetCallerFrame();
type_info * pti = 0;
// since we can get here when an exception is rethrown
// pObjectInfo could be 0. Also it is a good idea to
// make a sanity check
if (pObjectInfo &&
pObjectInfo->pCatchableTypeArray &&
pObjectInfo->pCatchableTypeArray->nCatchableTypes > 0)
{
const _s__CatchableTypeArray * pTypes =
pObjectInfo->pCatchableTypeArray;
pti = (type_info*)
((*(pTypes->arrayOfCatchableTypes))[0].pType);
}
//call the hook function
PreviewException(pObject,paddr,pti);
const ULONG_PTR args[] = {MS_MAGIC,
(ULONG_PTR)pObject,
(ULONG_PTR)pObjectInfo};
RaiseException(CPP_EXCEPTION,
EXCEPTION_NONCONTINUABLE,
sizeof(args)/sizeof(args[0]),
args);
}
//restore optimization settings
#pragma optimize("",on)
Previous Page |
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
Next Page