windows-nt/Source/XPSP1/NT/base/crts/crtw32/eh/unhandld.cpp
2020-09-26 16:20:57 +08:00

120 lines
3.4 KiB
C++

/***
*unhandld.cxx - Wrapper to call terminate() when an exception goes unhandled.
*
* Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
*
*Purpose:
* Wrapper to call terminate() when an exception goes unhandled.
*
*Description:
* This module makes use of the Win32 API SetUnhandledExceptionFilter.
* This assumes the call to main() is wrapped with
* __try { ... }
* __except(UnhandledExceptionFilter(_exception_info())) { ... }
*
*Revision History:
* 10-04-93 BS Module created
* 10-17-94 BWT Disable code for PPC.
* 02-09-95 JWM Mac merge.
* 02-16-95 JWM Added __CxxRestoreUnhandledExceptionFilter().
* 11-19-96 GJF Install handler during C initializers, remove it
* during C termination. Also, reformatted the source a
* bit for readability.
* 04-28-99 PML Wrap __declspec(allocate()) in _CRTALLOC macro.
* 05-17-99 PML Remove all Macintosh support.
* 03-27-01 PML .CRT$XI routines must now return 0 or _RT_* fatal
* error code (vs7#231220)
*
****/
#include <windows.h>
#include <ehdata.h>
#include <eh.h>
#include <ehhooks.h>
#include <ehassert.h>
#include <internal.h>
#include <stdlib.h>
#pragma hdrstop
#include <sect_attribs.h>
int __cdecl __CxxSetUnhandledExceptionFilter(void);
void __cdecl __CxxRestoreUnhandledExceptionFilter(void);
#pragma data_seg(".CRT$XIY")
_CRTALLOC(".CRT$XIY") static _PIFV pinit = &__CxxSetUnhandledExceptionFilter;
#pragma data_seg(".CRT$XTB")
_CRTALLOC(".CRT$XTB") static _PVFV pterm = &__CxxRestoreUnhandledExceptionFilter;
#pragma data_seg()
static LPTOP_LEVEL_EXCEPTION_FILTER pOldExceptFilter;
/////////////////////////////////////////////////////////////////////////////
//
// __CxxUnhandledExceptionFilter - if the exception is ours, call terminate();
//
// Returns:
// If the exception was MSVC C++ EH, does not return.
// If the previous filter was NULL, returns EXCEPTION_CONTINUE_SEARCH.
// Otherwise returns value returned by previous filter.
//
LONG WINAPI __CxxUnhandledExceptionFilter(
LPEXCEPTION_POINTERS pPtrs
)
{
if (PER_IS_MSVC_EH((EHExceptionRecord*)(pPtrs->ExceptionRecord))) {
terminate(); // Does not return
return EXCEPTION_EXECUTE_HANDLER;
}
else {
#pragma warning(disable:4191)
if ( pOldExceptFilter != NULL &&
_ValidateExecute((FARPROC)pOldExceptFilter) )
#pragma warning(default:4191)
{
return pOldExceptFilter(pPtrs);
}
else {
return EXCEPTION_CONTINUE_SEARCH;
}
}
}
/////////////////////////////////////////////////////////////////////////////
//
// __CxxSetUnhandledExceptionFilter - sets unhandled exception filter to be
// __CxxUnhandledExceptionFilter.
//
// Returns:
// Returns 0 to indicate no error.
//
int __cdecl __CxxSetUnhandledExceptionFilter(void)
{
pOldExceptFilter = SetUnhandledExceptionFilter(&__CxxUnhandledExceptionFilter);
return 0;
}
/////////////////////////////////////////////////////////////////////////////
//
// __CxxRestoreUnhandledExceptionFilter - on exit, restores OldExceptFilter
//
// Returns:
// Nothing.
//
void __cdecl __CxxRestoreUnhandledExceptionFilter(void)
{
SetUnhandledExceptionFilter(pOldExceptFilter);
}