[Piglit] [PATCH] tests: Narrow down the scope of Windows unhandled exception filter.
Brian Paul
brianp at vmware.com
Tue Apr 21 07:06:57 PDT 2015
On 04/17/2015 04:16 PM, Jose Fonseca wrote:
> The previous unhandled exception filter had two problems:
>
> - Vectored exceptions filter are too big of a hammer for this, as they
> intercept any exception on any thread, regardless they have a regular
> handler that will catch them or not. Whereas we're only interested
> in the uncaught exceptions inside WndProc callback.
>
> - Waffle does not need this. Unlike GLUT, Waffle lets the piglit
> framework run the main loop, and the display callback function is not
> called inside WndProc callback.
>
> In short, the exception filter could very easily be called for harmless
> exceptions (such as internal exceptions used by the OpenGL driver.)
>
> That said, we can't use SetUnhandledExceptionFilter and must actually
> use the MSVC's __try/__except keywords, but these are not supported by
> MinGW, which only provides much less friendlier __try1/__except1 macros.
>
> Tested Mingw32, Mingw64, and MSVC32 builds of build with FreeGLUT.
"builds of piglit" I presume.
Acked-by: Brian Paul <brianp at vmware.com>
> ---
> .../piglit-framework-gl/piglit_glut_framework.c | 79 ++++++++++++++++++++++
> tests/util/piglit-util.c | 64 ------------------
> 2 files changed, 79 insertions(+), 64 deletions(-)
>
> diff --git a/tests/util/piglit-framework-gl/piglit_glut_framework.c b/tests/util/piglit-framework-gl/piglit_glut_framework.c
> index 71c640a..dd5eaae 100644
> --- a/tests/util/piglit-framework-gl/piglit_glut_framework.c
> +++ b/tests/util/piglit-framework-gl/piglit_glut_framework.c
> @@ -56,14 +56,93 @@ destroy(struct piglit_gl_framework *gl_fw)
> glut_fw.window = 0;
> }
>
> +
> +#ifdef _WIN32
> +
> +/* Catch any exceptions and abort immediately.
> + *
> + * At least with certain implementations of GLUT (namely
> + * freeglut-2.8.1), the glutDisplayFunc()'s callback called inside a
> + * WindowProc callback function.
> + *
> + * And on certain cases (depending on the Windows version and 32 vs 64
> + * bits processes) uncaught exceptions inside WindowProc callbacks are
> + * silently ignored! (See Remarks section of
> + * http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573.aspx
> + * page.) The end result is that automatic tests end up blocking
> + * waiting for user input when an uncaught exceptionhappens, as control
> + * flow is interrupted before it reaches piglit_report_result(), and
> + * the process never aborts.
> + *
> + * By installing our own exception handler we can ensure that uncaught
> + * exceptions will never be silently ignored.
> + *
> + * NOTE: SetUnhandledExceptionFilter does not work here, as some Windows
> + * versions never call the unhandled exception filter. We must use MSVC
> + * __try/__except statements, or in MinGW, the __try1/__except1 macros.
> + */
> +static LONG WINAPI
> +exception_filter(PEXCEPTION_POINTERS pExceptionInfo)
> +{
> + PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
> +
> + fflush(stdout);
> + fprintf(stderr, "error: caught unhandled exception 0x%08lx\n", pExceptionRecord->ExceptionCode);
> + fflush(stderr);
> +
> + _exit(pExceptionRecord->ExceptionCode);
> +}
> +
> +# ifdef __MINGW32__
> +
> +// http://www.programmingunlimited.net/siteexec/content.cgi?page=mingw-seh
> +// http://www.microsoft.com/msj/0197/exception/exception.aspx
> +EXCEPTION_DISPOSITION
> +exception_handler(struct _EXCEPTION_RECORD *ExceptionRecord, void *EstablisherFrame, struct _CONTEXT *ContextRecord, void *DispatcherContext)
> +{
> + EXCEPTION_POINTERS ExceptionInfo = {ExceptionRecord, ContextRecord};
> + switch (exception_filter(&ExceptionInfo)) {
> + case EXCEPTION_EXECUTE_HANDLER:
> + return ExceptionExecuteHandler;
> + case EXCEPTION_CONTINUE_SEARCH:
> + return ExceptionContinueSearch;
> + case EXCEPTION_CONTINUE_EXECUTION:
> + return ExceptionContinueExecution;
> + default:
> + return ExceptionContinueSearch;
> + }
> +}
> +
> +# define TRY __try1(exception_handler);
> +# define CATCH_ALL __except1;
> +
> +# else
> +
> +# define TRY __try {
> +# define CATCH_ALL } __except(exception_filter(GetExceptionInformation())) {}
> +
> +# endif
> +
> +#else
> +
> +# define TRY
> +# define CATCH_ALL
> +
> +#endif
> +
> +
> static void
> display(void)
> {
> const struct piglit_gl_test_config *test_config = glut_fw.gl_fw.test_config;
>
> + TRY
> +
> if (test_config->display)
> glut_fw.result = test_config->display();
>
> + CATCH_ALL
> +
> if (piglit_automatic) {
> glutDestroyWindow(glut_fw.window);
> #ifdef FREEGLUT
> diff --git a/tests/util/piglit-util.c b/tests/util/piglit-util.c
> index 743373a..9bd0cd2 100644
> --- a/tests/util/piglit-util.c
> +++ b/tests/util/piglit-util.c
> @@ -289,50 +289,6 @@ piglit_report_subtest_result(enum piglit_result result, const char *format, ...)
> va_end(ap);
> }
>
> -#ifdef _WIN32
> -
> -#ifndef DBG_PRINTEXCEPTION_C
> -#define DBG_PRINTEXCEPTION_C 0x40010006
> -#endif
> -
> -static LONG WINAPI
> -exception_handler(PEXCEPTION_POINTERS pExceptionInfo)
> -{
> - PEXCEPTION_RECORD pExceptionRecord = pExceptionInfo->ExceptionRecord;
> -
> - /* Ignore OutputDebugStringA exceptions. */
> - if (pExceptionRecord->ExceptionCode == DBG_PRINTEXCEPTION_C) {
> - return EXCEPTION_CONTINUE_SEARCH;
> - }
> -
> - /* Ignore C++ exceptions
> - * http://support.microsoft.com/kb/185294
> - * http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx
> - */
> - if (pExceptionRecord->ExceptionCode == 0xe06d7363) {
> - return EXCEPTION_CONTINUE_SEARCH;
> - }
> -
> - /* Ignore thread naming exception.
> - * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
> - */
> - if (pExceptionRecord->ExceptionCode == 0x406d1388) {
> - return EXCEPTION_CONTINUE_SEARCH;
> - }
> -
> - fflush(stdout);
> - fprintf(stderr, "error: uncaught exception 0x%08lx\n",
> - pExceptionRecord->ExceptionCode);
> - fflush(stderr);
> -
> - TerminateProcess(GetCurrentProcess(),
> - pExceptionRecord->ExceptionCode);
> -
> - return EXCEPTION_CONTINUE_SEARCH;
> -}
> -
> -#endif /* _WIN32 */
> -
>
> void
> piglit_disable_error_message_boxes(void)
> @@ -367,26 +323,6 @@ piglit_disable_error_message_boxes(void)
> _set_abort_behavior(0, _WRITE_ABORT_MSG | _CALL_REPORTFAULT);
> #endif
> }
> -
> - /* Catch any exceptions and abort immediately.
> - *
> - * At least with certain implementations of GLUT (namely
> - * freeglut-2.8.1), the glutDisplayFunc()'s callback called inside a
> - * WindowProc callback function.
> - *
> - * And on certain cases (depending on the Windows version and 32 vs 64
> - * bits processes) uncaught exceptions inside WindowProc callbacks are
> - * silently ignored! (See Remarks section of
> - * http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573.aspx
> - * page.) The end result is that automatic tests end up blocking
> - * waiting for user input when an uncaught exceptionhappens, as control
> - * flow is interrupted before it reaches piglit_report_result(), and
> - * the process never aborts.
> - *
> - * By installing our own exception handler we can ensure that uncaught
> - * exceptions will never be silently ignored.
> - */
> - AddVectoredExceptionHandler(0, exception_handler);
> #endif /* _WIN32 */
> }
>
>
More information about the Piglit
mailing list