[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