Merging MinGW changes
This commit is contained in:
@ -1,112 +1,112 @@
|
||||
int
|
||||
__except_handler3(
|
||||
struct _EXCEPTION_RECORD* pExceptionRecord,
|
||||
struct EXCEPTION_REGISTRATION* pRegistrationFrame,
|
||||
struct _CONTEXT* pContextRecord,
|
||||
void* pDispatcherContext
|
||||
)
|
||||
{
|
||||
LONG filterFuncRet;
|
||||
LONG trylevel;
|
||||
EXCEPTION_POINTERS exceptPtrs;
|
||||
PSCOPETABLE pScopeTable;
|
||||
|
||||
|
||||
CLD // Clear the direction flag (make no assumptions!)
|
||||
|
||||
// if neither the EXCEPTION_UNWINDING nor EXCEPTION_EXIT_UNWIND bit
|
||||
// is set... This is true the first time through the handler (the
|
||||
// non-unwinding case)
|
||||
|
||||
if ( ! (pExceptionRecord->ExceptionFlags
|
||||
& (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)
|
||||
) )
|
||||
{
|
||||
// Build the EXCEPTION_POINTERS structure on the stack
|
||||
exceptPtrs.ExceptionRecord = pExceptionRecord;
|
||||
exceptPtrs.ContextRecord = pContextRecord;
|
||||
|
||||
// Put the pointer to the EXCEPTION_POINTERS 4 bytes below the
|
||||
// establisher frame. See ASM code for GetExceptionInformation
|
||||
*(PDWORD)((PBYTE)pRegistrationFrame - 4) = &exceptPtrs;
|
||||
|
||||
// Get initial "trylevel" value
|
||||
trylevel = pRegistrationFrame->trylevel
|
||||
|
||||
// Get a pointer to the scopetable array
|
||||
scopeTable = pRegistrationFrame->scopetable;
|
||||
|
||||
search_for_handler:
|
||||
if ( pRegistrationFrame->trylevel != TRYLEVEL_NONE )
|
||||
{
|
||||
if ( pRegistrationFrame->scopetable[trylevel].lpfnFilter )
|
||||
{
|
||||
|
||||
PUSH EBP // Save this frame EBP
|
||||
|
||||
// !!!Very Important!!! Switch to original EBP. This is
|
||||
// what allows all locals in the frame to have the same
|
||||
// value as before the exception occurred.
|
||||
|
||||
EBP = &pRegistrationFrame->_ebp
|
||||
|
||||
// Call the filter function
|
||||
filterFuncRet = scopetable[trylevel].lpfnFilter();
|
||||
|
||||
POP EBP // Restore handler frame EBP
|
||||
|
||||
if ( filterFuncRet != EXCEPTION_CONTINUE_SEARCH )
|
||||
{
|
||||
if ( filterFuncRet < 0 ) // EXCEPTION_CONTINUE_EXECUTION
|
||||
return ExceptionContinueExecution;
|
||||
|
||||
// If we get here, EXCEPTION_EXECUTE_HANDLER was specified
|
||||
scopetable == pRegistrationFrame->scopetable
|
||||
|
||||
// Does the actual OS cleanup of registration frames
|
||||
// Causes this function to recurse
|
||||
__global_unwind2( pRegistrationFrame );
|
||||
|
||||
|
||||
// Once we get here, everything is all cleaned up, except
|
||||
// for the last frame, where we'll continue execution
|
||||
EBP = &pRegistrationFrame->_ebp
|
||||
|
||||
__local_unwind2( pRegistrationFrame, trylevel );
|
||||
|
||||
// NLG == "non-local-goto" (setjmp/longjmp stuff)
|
||||
__NLG_Notify( 1 ); // EAX == scopetable->lpfnHandler
|
||||
|
||||
// Set the current trylevel to whatever SCOPETABLE entry
|
||||
// was being used when a handler was found
|
||||
pRegistrationFrame->trylevel = scopetable->previousTryLevel;
|
||||
|
||||
// Call the _except {} block. Never returns.
|
||||
pRegistrationFrame->scopetable[trylevel].lpfnHandler();
|
||||
}
|
||||
}
|
||||
|
||||
scopeTable = pRegistrationFrame->scopetable;
|
||||
trylevel = scopeTable->previousTryLevel
|
||||
|
||||
goto search_for_handler;
|
||||
}
|
||||
else // trylevel == TRYLEVEL_NONE
|
||||
{
|
||||
retvalue == DISPOSITION_CONTINUE_SEARCH;
|
||||
}
|
||||
}
|
||||
else // EXCEPTION_UNWINDING or EXCEPTION_EXIT_UNWIND flags are set
|
||||
{
|
||||
PUSH EBP // Save EBP
|
||||
|
||||
EBP = pRegistrationFrame->_ebp // Set EBP for __local_unwind2
|
||||
|
||||
__local_unwind2( pRegistrationFrame, TRYLEVEL_NONE )
|
||||
|
||||
POP EBP // Restore EBP
|
||||
|
||||
retvalue == DISPOSITION_CONTINUE_SEARCH;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
__except_handler3(
|
||||
struct _EXCEPTION_RECORD* pExceptionRecord,
|
||||
struct EXCEPTION_REGISTRATION* pRegistrationFrame,
|
||||
struct _CONTEXT* pContextRecord,
|
||||
void* pDispatcherContext
|
||||
)
|
||||
{
|
||||
LONG filterFuncRet;
|
||||
LONG trylevel;
|
||||
EXCEPTION_POINTERS exceptPtrs;
|
||||
PSCOPETABLE pScopeTable;
|
||||
|
||||
|
||||
CLD // Clear the direction flag (make no assumptions!)
|
||||
|
||||
// if neither the EXCEPTION_UNWINDING nor EXCEPTION_EXIT_UNWIND bit
|
||||
// is set... This is true the first time through the handler (the
|
||||
// non-unwinding case)
|
||||
|
||||
if ( ! (pExceptionRecord->ExceptionFlags
|
||||
& (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND)
|
||||
) )
|
||||
{
|
||||
// Build the EXCEPTION_POINTERS structure on the stack
|
||||
exceptPtrs.ExceptionRecord = pExceptionRecord;
|
||||
exceptPtrs.ContextRecord = pContextRecord;
|
||||
|
||||
// Put the pointer to the EXCEPTION_POINTERS 4 bytes below the
|
||||
// establisher frame. See ASM code for GetExceptionInformation
|
||||
*(PDWORD)((PBYTE)pRegistrationFrame - 4) = &exceptPtrs;
|
||||
|
||||
// Get initial "trylevel" value
|
||||
trylevel = pRegistrationFrame->trylevel
|
||||
|
||||
// Get a pointer to the scopetable array
|
||||
scopeTable = pRegistrationFrame->scopetable;
|
||||
|
||||
search_for_handler:
|
||||
if ( pRegistrationFrame->trylevel != TRYLEVEL_NONE )
|
||||
{
|
||||
if ( pRegistrationFrame->scopetable[trylevel].lpfnFilter )
|
||||
{
|
||||
|
||||
PUSH EBP // Save this frame EBP
|
||||
|
||||
// !!!Very Important!!! Switch to original EBP. This is
|
||||
// what allows all locals in the frame to have the same
|
||||
// value as before the exception occurred.
|
||||
|
||||
EBP = &pRegistrationFrame->_ebp
|
||||
|
||||
// Call the filter function
|
||||
filterFuncRet = scopetable[trylevel].lpfnFilter();
|
||||
|
||||
POP EBP // Restore handler frame EBP
|
||||
|
||||
if ( filterFuncRet != EXCEPTION_CONTINUE_SEARCH )
|
||||
{
|
||||
if ( filterFuncRet < 0 ) // EXCEPTION_CONTINUE_EXECUTION
|
||||
return ExceptionContinueExecution;
|
||||
|
||||
// If we get here, EXCEPTION_EXECUTE_HANDLER was specified
|
||||
scopetable == pRegistrationFrame->scopetable
|
||||
|
||||
// Does the actual OS cleanup of registration frames
|
||||
// Causes this function to recurse
|
||||
__global_unwind2( pRegistrationFrame );
|
||||
|
||||
|
||||
// Once we get here, everything is all cleaned up, except
|
||||
// for the last frame, where we'll continue execution
|
||||
EBP = &pRegistrationFrame->_ebp
|
||||
|
||||
__local_unwind2( pRegistrationFrame, trylevel );
|
||||
|
||||
// NLG == "non-local-goto" (setjmp/longjmp stuff)
|
||||
__NLG_Notify( 1 ); // EAX == scopetable->lpfnHandler
|
||||
|
||||
// Set the current trylevel to whatever SCOPETABLE entry
|
||||
// was being used when a handler was found
|
||||
pRegistrationFrame->trylevel = scopetable->previousTryLevel;
|
||||
|
||||
// Call the _except {} block. Never returns.
|
||||
pRegistrationFrame->scopetable[trylevel].lpfnHandler();
|
||||
}
|
||||
}
|
||||
|
||||
scopeTable = pRegistrationFrame->scopetable;
|
||||
trylevel = scopeTable->previousTryLevel
|
||||
|
||||
goto search_for_handler;
|
||||
}
|
||||
else // trylevel == TRYLEVEL_NONE
|
||||
{
|
||||
retvalue == DISPOSITION_CONTINUE_SEARCH;
|
||||
}
|
||||
}
|
||||
else // EXCEPTION_UNWINDING or EXCEPTION_EXIT_UNWIND flags are set
|
||||
{
|
||||
PUSH EBP // Save EBP
|
||||
|
||||
EBP = pRegistrationFrame->_ebp // Set EBP for __local_unwind2
|
||||
|
||||
__local_unwind2( pRegistrationFrame, TRYLEVEL_NONE )
|
||||
|
||||
POP EBP // Restore EBP
|
||||
|
||||
retvalue == DISPOSITION_CONTINUE_SEARCH;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,68 +1,68 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <excpt.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "exutil.h"
|
||||
|
||||
void
|
||||
WalkExceptionHandlers ()
|
||||
{
|
||||
PEXCEPTION_REGISTRATION_RECORD p;
|
||||
int i;
|
||||
|
||||
__asm__("movl %%fs:0,%%eax;movl %%eax,%0" : "=g" (p) : : "%eax");
|
||||
|
||||
i = 0;
|
||||
while (p != (PEXCEPTION_REGISTRATION_RECORD) -1 && p)
|
||||
{
|
||||
printf ("Registration %d at %08x : ", i, p);
|
||||
printf ("Handler = %08x ", p->handler);
|
||||
printf ("Next Registration = %08x\n", p->prev);
|
||||
p = p->prev;
|
||||
i++;
|
||||
}
|
||||
printf ("End of exception handler list.\n");
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
void
|
||||
DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec)
|
||||
{
|
||||
printf ("Exception: Code = %08x Flags %08x", pExRec->ExceptionCode,
|
||||
pExRec->ExceptionFlags);
|
||||
|
||||
if (pExRec->ExceptionFlags)
|
||||
{
|
||||
printf (" ( ");
|
||||
if (pExRec->ExceptionFlags & EH_NONCONTINUABLE)
|
||||
{
|
||||
printf ("EH_NONCONTINUABLE ");
|
||||
}
|
||||
if (pExRec->ExceptionFlags & EH_UNWINDING)
|
||||
{
|
||||
printf ("EH_UNWINDING ");
|
||||
}
|
||||
if (pExRec->ExceptionFlags & EH_EXIT_UNWIND)
|
||||
{
|
||||
printf ("EH_EXIT_UNWIND ");
|
||||
}
|
||||
if (pExRec->ExceptionFlags & EH_STACK_INVALID)
|
||||
{
|
||||
printf ("EH_STACK_INVALID ");
|
||||
}
|
||||
if (pExRec->ExceptionFlags & EH_NESTED_CALL)
|
||||
{
|
||||
printf ("EH_NESTED_CALL ");
|
||||
}
|
||||
printf (")\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <excpt.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "exutil.h"
|
||||
|
||||
void
|
||||
WalkExceptionHandlers ()
|
||||
{
|
||||
PEXCEPTION_REGISTRATION_RECORD p;
|
||||
int i;
|
||||
|
||||
__asm__("movl %%fs:0,%%eax;movl %%eax,%0" : "=g" (p) : : "%eax");
|
||||
|
||||
i = 0;
|
||||
while (p != (PEXCEPTION_REGISTRATION_RECORD) -1 && p)
|
||||
{
|
||||
printf ("Registration %d at %08x : ", i, p);
|
||||
printf ("Handler = %08x ", p->handler);
|
||||
printf ("Next Registration = %08x\n", p->prev);
|
||||
p = p->prev;
|
||||
i++;
|
||||
}
|
||||
printf ("End of exception handler list.\n");
|
||||
fflush (stdout);
|
||||
}
|
||||
|
||||
void
|
||||
DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec)
|
||||
{
|
||||
printf ("Exception: Code = %08x Flags %08x", pExRec->ExceptionCode,
|
||||
pExRec->ExceptionFlags);
|
||||
|
||||
if (pExRec->ExceptionFlags)
|
||||
{
|
||||
printf (" ( ");
|
||||
if (pExRec->ExceptionFlags & EH_NONCONTINUABLE)
|
||||
{
|
||||
printf ("EH_NONCONTINUABLE ");
|
||||
}
|
||||
if (pExRec->ExceptionFlags & EH_UNWINDING)
|
||||
{
|
||||
printf ("EH_UNWINDING ");
|
||||
}
|
||||
if (pExRec->ExceptionFlags & EH_EXIT_UNWIND)
|
||||
{
|
||||
printf ("EH_EXIT_UNWIND ");
|
||||
}
|
||||
if (pExRec->ExceptionFlags & EH_STACK_INVALID)
|
||||
{
|
||||
printf ("EH_STACK_INVALID ");
|
||||
}
|
||||
if (pExRec->ExceptionFlags & EH_NESTED_CALL)
|
||||
{
|
||||
printf ("EH_NESTED_CALL ");
|
||||
}
|
||||
printf (")\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
EXPORTS
|
||||
WalkExceptionHandlers
|
||||
DumpExceptionRecord
|
||||
EXPORTS
|
||||
WalkExceptionHandlers
|
||||
DumpExceptionRecord
|
||||
|
@ -1,23 +1,23 @@
|
||||
/*
|
||||
* Definitions of some internal stuff for exception handling, including
|
||||
* a version of the all-important EXCEPTION_REGISTRATION_RECORD.
|
||||
*/
|
||||
|
||||
#ifndef _EXUTIL_H_
|
||||
#define _EXUTIL_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <excpt.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void WalkExceptionHandlers ();
|
||||
void DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Definitions of some internal stuff for exception handling, including
|
||||
* a version of the all-important EXCEPTION_REGISTRATION_RECORD.
|
||||
*/
|
||||
|
||||
#ifndef _EXUTIL_H_
|
||||
#define _EXUTIL_H_
|
||||
|
||||
#include <windows.h>
|
||||
#include <excpt.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void WalkExceptionHandlers ();
|
||||
void DumpExceptionRecord (struct _EXCEPTION_RECORD* pExRec);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,13 +1,13 @@
|
||||
|
||||
Dll exutil.dll : exutil.c ;
|
||||
|
||||
ImportLib libexutil.a : exutil.def ;
|
||||
|
||||
Main sehtest.exe : sehtest.c ;
|
||||
|
||||
Main sehfix.exe : sehfix.c ;
|
||||
|
||||
Main sehsub.exe : sehsub.c ;
|
||||
|
||||
LinkLibraries sehtest.exe sehfix.exe sehsub.exe : libexutil.a ;
|
||||
|
||||
|
||||
Dll exutil.dll : exutil.c ;
|
||||
|
||||
ImportLib libexutil.a : exutil.def ;
|
||||
|
||||
Main sehtest.exe : sehtest.c ;
|
||||
|
||||
Main sehfix.exe : sehfix.c ;
|
||||
|
||||
Main sehsub.exe : sehsub.c ;
|
||||
|
||||
LinkLibraries sehtest.exe sehfix.exe sehsub.exe : libexutil.a ;
|
||||
|
||||
|
@ -1,60 +1,60 @@
|
||||
/*
|
||||
* sehfix.c
|
||||
*
|
||||
* A test program involving an exception handler that fixes the exception
|
||||
* causing condition.
|
||||
*
|
||||
* In this code we install an exception handler my_handler and then a piece
|
||||
* of inline assembly attempts to write at the address marked in eax, after
|
||||
* setting eax to 10. This should produce an exception. The handler then
|
||||
* changes the eax register of the exception context to be the address of
|
||||
* a static variable and restarts the code. This should allow everything
|
||||
* to continue.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <excpt.h>
|
||||
|
||||
#include "exutil.h"
|
||||
|
||||
int x;
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
my_handler (
|
||||
struct _EXCEPTION_RECORD* pExceptionRec,
|
||||
void* pEstablisherFrame,
|
||||
struct _CONTEXT* pContextRecord,
|
||||
void* pDispatcherContext
|
||||
)
|
||||
{
|
||||
printf ("In my exception handler!\n");
|
||||
DumpExceptionRecord (pExceptionRec);
|
||||
pContextRecord->Eax = (DWORD) &x;
|
||||
return ExceptionContinueExecution;
|
||||
}
|
||||
|
||||
main ()
|
||||
{
|
||||
x = 2;
|
||||
|
||||
printf ("x = %d\n", x);
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
__try1(my_handler)
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
/* This assembly code should produce an exception. */
|
||||
__asm__("movl $10,%%eax;movl $1,(%%eax);" : : : "%eax");
|
||||
|
||||
__except1
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
printf ("x = %d\n", x);
|
||||
|
||||
printf ("Finished!\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sehfix.c
|
||||
*
|
||||
* A test program involving an exception handler that fixes the exception
|
||||
* causing condition.
|
||||
*
|
||||
* In this code we install an exception handler my_handler and then a piece
|
||||
* of inline assembly attempts to write at the address marked in eax, after
|
||||
* setting eax to 10. This should produce an exception. The handler then
|
||||
* changes the eax register of the exception context to be the address of
|
||||
* a static variable and restarts the code. This should allow everything
|
||||
* to continue.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <excpt.h>
|
||||
|
||||
#include "exutil.h"
|
||||
|
||||
int x;
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
my_handler (
|
||||
struct _EXCEPTION_RECORD* pExceptionRec,
|
||||
void* pEstablisherFrame,
|
||||
struct _CONTEXT* pContextRecord,
|
||||
void* pDispatcherContext
|
||||
)
|
||||
{
|
||||
printf ("In my exception handler!\n");
|
||||
DumpExceptionRecord (pExceptionRec);
|
||||
pContextRecord->Eax = (DWORD) &x;
|
||||
return ExceptionContinueExecution;
|
||||
}
|
||||
|
||||
main ()
|
||||
{
|
||||
x = 2;
|
||||
|
||||
printf ("x = %d\n", x);
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
__try1(my_handler)
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
/* This assembly code should produce an exception. */
|
||||
__asm__("movl $10,%%eax;movl $1,(%%eax);" : : : "%eax");
|
||||
|
||||
__except1
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
printf ("x = %d\n", x);
|
||||
|
||||
printf ("Finished!\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,43 +1,43 @@
|
||||
/*
|
||||
* sehsub.c
|
||||
*
|
||||
* In an attempt to see what might be going on inside CRTDLL, this program
|
||||
* walks the exception list after creating a new thread with _beginthread.
|
||||
*
|
||||
* It turns out that _beginthread DOES install an exception handler, as
|
||||
* expected, but this handler is NOT exported by CRTDLL (it is certainly
|
||||
* not _except_handler2 or _XcptFilter)... an odd and unpleasant turn of
|
||||
* events.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <excpt.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "exutil.h"
|
||||
|
||||
extern void* __imp__except_handler3;
|
||||
|
||||
unsigned
|
||||
my_thread (void * p)
|
||||
{
|
||||
printf ("In my thread.\n");
|
||||
WalkExceptionHandlers();
|
||||
return 0;
|
||||
}
|
||||
|
||||
main ()
|
||||
{
|
||||
unsigned long h;
|
||||
unsigned id;
|
||||
printf ("In main.\n");
|
||||
WalkExceptionHandlers();
|
||||
|
||||
printf ("Except_handler3 %08x\n", __imp__except_handler3);
|
||||
h = _beginthreadex (NULL, 0, my_thread, NULL, 0, &id);
|
||||
|
||||
WaitForSingleObject ((HANDLE) h, INFINITE);
|
||||
CloseHandle ((HANDLE) h);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* sehsub.c
|
||||
*
|
||||
* In an attempt to see what might be going on inside CRTDLL, this program
|
||||
* walks the exception list after creating a new thread with _beginthread.
|
||||
*
|
||||
* It turns out that _beginthread DOES install an exception handler, as
|
||||
* expected, but this handler is NOT exported by CRTDLL (it is certainly
|
||||
* not _except_handler2 or _XcptFilter)... an odd and unpleasant turn of
|
||||
* events.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <excpt.h>
|
||||
#include <process.h>
|
||||
|
||||
#include "exutil.h"
|
||||
|
||||
extern void* __imp__except_handler3;
|
||||
|
||||
unsigned
|
||||
my_thread (void * p)
|
||||
{
|
||||
printf ("In my thread.\n");
|
||||
WalkExceptionHandlers();
|
||||
return 0;
|
||||
}
|
||||
|
||||
main ()
|
||||
{
|
||||
unsigned long h;
|
||||
unsigned id;
|
||||
printf ("In main.\n");
|
||||
WalkExceptionHandlers();
|
||||
|
||||
printf ("Except_handler3 %08x\n", __imp__except_handler3);
|
||||
h = _beginthreadex (NULL, 0, my_thread, NULL, 0, &id);
|
||||
|
||||
WaitForSingleObject ((HANDLE) h, INFINITE);
|
||||
CloseHandle ((HANDLE) h);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,72 +1,72 @@
|
||||
/*
|
||||
* This file tests some of the basics of structured exception handling as
|
||||
* implemented in excpt.h and the Windows API header files.
|
||||
*
|
||||
* The program installs two exception handlers, then attempts to write to
|
||||
* a pointer to an invalid address. This causes an exception which passes
|
||||
* through the exception handlers and on to the default system exception
|
||||
* handler. That handler brings up the dialog box all Windows users know
|
||||
* and love, and then the program is terminated.
|
||||
*
|
||||
* You might note that after the initial run up through our exception frames
|
||||
* we get a second run up through them with the exception code
|
||||
* STATUS_INVALID_DISPOSITION and the code EH_UNWINDING. This seems normal
|
||||
* except that the code got changed from the previous STATUS_ACCESS_VIOLATION.
|
||||
* I don't understand that bit particularly.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <excpt.h>
|
||||
|
||||
#include "exutil.h"
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
my_handler (
|
||||
struct _EXCEPTION_RECORD* pExceptionRec,
|
||||
void* pEstablisherFrame,
|
||||
struct _CONTEXT* pContextRecord,
|
||||
void* pDispatcherContext
|
||||
)
|
||||
{
|
||||
printf ("In my exception handler!\n");
|
||||
DumpExceptionRecord (pExceptionRec);
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
my_handler2 (
|
||||
struct _EXCEPTION_RECORD* pExceptionRec,
|
||||
void* pEstablisherFrame,
|
||||
struct _CONTEXT* pContextRecord,
|
||||
void* pDispatcherContext
|
||||
)
|
||||
{
|
||||
printf ("In top exception handler!\n");
|
||||
DumpExceptionRecord (pExceptionRec);
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
main ()
|
||||
{
|
||||
char* x;
|
||||
|
||||
printf ("my_handler2 = %08x\n", my_handler2);
|
||||
printf ("my_handler = %08x\n", my_handler);
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
__try1(my_handler2)
|
||||
x = (char*) 10;
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
__try1(my_handler)
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
*x = 1;
|
||||
__except1
|
||||
__except1
|
||||
printf ("Finished!\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* This file tests some of the basics of structured exception handling as
|
||||
* implemented in excpt.h and the Windows API header files.
|
||||
*
|
||||
* The program installs two exception handlers, then attempts to write to
|
||||
* a pointer to an invalid address. This causes an exception which passes
|
||||
* through the exception handlers and on to the default system exception
|
||||
* handler. That handler brings up the dialog box all Windows users know
|
||||
* and love, and then the program is terminated.
|
||||
*
|
||||
* You might note that after the initial run up through our exception frames
|
||||
* we get a second run up through them with the exception code
|
||||
* STATUS_INVALID_DISPOSITION and the code EH_UNWINDING. This seems normal
|
||||
* except that the code got changed from the previous STATUS_ACCESS_VIOLATION.
|
||||
* I don't understand that bit particularly.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <excpt.h>
|
||||
|
||||
#include "exutil.h"
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
my_handler (
|
||||
struct _EXCEPTION_RECORD* pExceptionRec,
|
||||
void* pEstablisherFrame,
|
||||
struct _CONTEXT* pContextRecord,
|
||||
void* pDispatcherContext
|
||||
)
|
||||
{
|
||||
printf ("In my exception handler!\n");
|
||||
DumpExceptionRecord (pExceptionRec);
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
EXCEPTION_DISPOSITION
|
||||
my_handler2 (
|
||||
struct _EXCEPTION_RECORD* pExceptionRec,
|
||||
void* pEstablisherFrame,
|
||||
struct _CONTEXT* pContextRecord,
|
||||
void* pDispatcherContext
|
||||
)
|
||||
{
|
||||
printf ("In top exception handler!\n");
|
||||
DumpExceptionRecord (pExceptionRec);
|
||||
return ExceptionContinueSearch;
|
||||
}
|
||||
|
||||
main ()
|
||||
{
|
||||
char* x;
|
||||
|
||||
printf ("my_handler2 = %08x\n", my_handler2);
|
||||
printf ("my_handler = %08x\n", my_handler);
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
__try1(my_handler2)
|
||||
x = (char*) 10;
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
__try1(my_handler)
|
||||
|
||||
WalkExceptionHandlers();
|
||||
|
||||
*x = 1;
|
||||
__except1
|
||||
__except1
|
||||
printf ("Finished!\n");
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user