C++ tips: AddVectoredExceptionHandler, AddVectoredContinueHandler and SetUnhandledExceptionFilter
I write below code to verify the behaviors of AddVectoredExceptionHandler, AddVectoredContinueHandler and SetUnhandledExceptionFilter:
#include "stdafx.h"
LONG WINAPI MyVectorContinueHandler(PEXCEPTION_POINTERS p)
{
printf("in my vectored continue handler\r\n");
return EXCEPTION_CONTINUE_SEARCH;
}
LONG WINAPI MyVectorExceptionFilter(PEXCEPTION_POINTERS p)
{
printf("in my vectored exception filter\r\n");
return EXCEPTION_CONTINUE_SEARCH;
}
LONG WINAPI MyUnhandledExceptionFilter(PEXCEPTION_POINTERS p)
{
printf("in my unhandled excepiton filter\r\n");
return EXCEPTION_CONTINUE_SEARCH;
}
LONG MyExceptFilter()
{
printf("in my filter\r\n");
return EXCEPTION_CONTINUE_SEARCH;
}
int _tmain(int argc, _TCHAR* argv[])
{
LPTOP_LEVEL_EXCEPTION_FILTER pOriginalFilter = SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);
AddVectoredExceptionHandler(1,MyVectorExceptionFilter);
AddVectoredContinueHandler(1,MyVectorContinueHandler);
__try
{
//trigger an access violation here
int* p;
p = 0;
*p = 10;
}
__except(MyExceptFilter())
{
printf("in my handler\r\n");
printf("exception code: 0x%x\r\n",GetExceptionCode());
}
}
Build and then run the code on Windows 2003, get below result which is as expected:
in my vectored exception filter
in my filter
in my unhandled excepiton filter
in my vectored continue handler
We can see that:
1. The vectored exception filter (MyVectorExceptionFilter) is called before the frame based SEH filter.
2. MyUnhandledExceptionFilter gets called since the exception is not handled (EXCEPTION_CONTINUE_SEARCH is returned from previous filters).
3. Finally, the vectored continue handler (MyVectorContinueHandler) gets called.
However, runs the same code on Windows 7, we get below result:
in my vectored exception filter
in my filter
in my unhandled excepiton filter
then Windows Error Reporting gets involved and below window pops up, the vectored continue handler is not called:
Another thing to note: we know that MyUnhandledExceptionFilter is called by the kernel32!UnhandledExceptionFilter:
ChildEBP RetAddr
0020f880 77ec2c4a test!MyUnhandledExceptionFilter+0x1e
0020f908 77d85a74 kernel32!UnhandledExceptionFilter+0x127
0020f910 77d2d950 ntdll!__RtlUserThreadStart+0x62
0020f924 77d2d7ec ntdll!_EH4_CallFilterFunc+0x12
0020f94c 77d565f9 ntdll!_except_handler4+0x8e
0020f970 77d565cb ntdll!ExecuteHandler2+0x26
0020fa20 77d56457 ntdll!ExecuteHandler+0x24
0020fa20 00000000 ntdll!KiUserExceptionDispatcher+0xf
If you debug the code in Visual Studio (or run it under other debugger such as windbg), if you set a break point in test!MyUnhandledExceptionFilter and you will find the break point cannot be hit. This is because in kernel32!UnhandledExceptionFilter, it detects if the code is runs under a debugger if so, it just returns EXCEPTION_CONTINUE_SEARCH and the customized unhandled exception filter (test!MyUnhandledExceptionFilter in this case) is not called at all.