[Piglit] [PATCH] egl-1.4: Add test egl-terminate-then-unbind-context

Chad Versace chad.versace at linux.intel.com
Fri Sep 20 12:38:39 PDT 2013


This test makes current a context, terminates the context's display, then
unbinds the context. According to the EGL 1.4 spec (2011.04.06), Section
3.2 Initialization, no errors should occur.

Exposes a use-after-free crash on mesa-9.2 with i965. This is the
underlying reason that `./$gles1_test -fbo` crashes on Intel for each
GLES1 test.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=69622
CC: Ian Romanick <idr at freedesktop.org>
CC: Paul Berry <stereotype441 at gmail.com>
Signed-off-by: Chad Versace <chad.versace at linux.intel.com>
---
 tests/all.tests                                    |   1 +
 tests/egl/spec/CMakeLists.txt                      |   1 +
 tests/egl/spec/egl-1.4/CMakeLists.gles2.txt        |   8 ++
 tests/egl/spec/egl-1.4/CMakeLists.txt              |   1 +
 .../egl-1.4/egl-terminate-then-unbind-context.c    | 108 +++++++++++++++++++++
 5 files changed, 119 insertions(+)
 create mode 100644 tests/egl/spec/egl-1.4/CMakeLists.gles2.txt
 create mode 100644 tests/egl/spec/egl-1.4/CMakeLists.txt
 create mode 100644 tests/egl/spec/egl-1.4/egl-terminate-then-unbind-context.c

diff --git a/tests/all.tests b/tests/all.tests
index a7bf00c..6a89287 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -3020,6 +3020,7 @@ egl14['eglQuerySurface EGL_BAD_ATTRIBUTE'] = plain_test('egl-query-surface --bad
 egl14['eglQuerySurface EGL_BAD_SURFACE'] = plain_test('egl-query-surface --bad-surface')
 egl14['eglQuerySurface EGL_HEIGHT'] = plain_test('egl-query-surface --attr=EGL_HEIGHT')
 egl14['eglQuerySurface EGL_WIDTH'] = plain_test('egl-query-surface --attr=EGL_WIDTH')
+egl14['eglTerminate then unbind context'] = plain_test('egl-terminate-then-unbind-context')
 
 egl_nok_swap_region = Group()
 spec['EGL_NOK_swap_region'] = egl_nok_swap_region
diff --git a/tests/egl/spec/CMakeLists.txt b/tests/egl/spec/CMakeLists.txt
index de4de3f..12bb419 100644
--- a/tests/egl/spec/CMakeLists.txt
+++ b/tests/egl/spec/CMakeLists.txt
@@ -1 +1,2 @@
+add_subdirectory (egl-1.4)
 add_subdirectory (egl_khr_create_context)
diff --git a/tests/egl/spec/egl-1.4/CMakeLists.gles2.txt b/tests/egl/spec/egl-1.4/CMakeLists.gles2.txt
new file mode 100644
index 0000000..b6bb1e8
--- /dev/null
+++ b/tests/egl/spec/egl-1.4/CMakeLists.gles2.txt
@@ -0,0 +1,8 @@
+link_libraries(
+	piglitutil_${piglit_target_api}
+        ${OPENGL_egl_LIBRARY}
+        )
+
+piglit_add_executable(egl-terminate-then-unbind-context egl-terminate-then-unbind-context.c)
+
+# vim: ft=cmake:
diff --git a/tests/egl/spec/egl-1.4/CMakeLists.txt b/tests/egl/spec/egl-1.4/CMakeLists.txt
new file mode 100644
index 0000000..144a306
--- /dev/null
+++ b/tests/egl/spec/egl-1.4/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/egl/spec/egl-1.4/egl-terminate-then-unbind-context.c b/tests/egl/spec/egl-1.4/egl-terminate-then-unbind-context.c
new file mode 100644
index 0000000..acf3dcb
--- /dev/null
+++ b/tests/egl/spec/egl-1.4/egl-terminate-then-unbind-context.c
@@ -0,0 +1,108 @@
+/* Copyright © 2013 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/**
+ * \file
+ *
+ * This test makes current a context, terminates the context's display, then
+ * unbinds the context. According to the EGL 1.4 spec (2011.04.06), Section
+ * 3.2 Initialization, no error should occur.
+ *
+ *     EGLBoolean eglTerminate(EGLDisplay dpy);
+ *
+ *     Termination marks all EGL-specific resources, such as contexts and
+ *     surfaces, associated with the specified display for deletion. Handles
+ *     to all such resources are invalid as soon as eglTerminate returns, but
+ *     the dpy handle itself remains valid. [...] Applications should not try
+ *     to perform useful work with such resources following eglTerminate; only
+ *     eglMakeCurrent or eglReleaseThread should be called, to complete
+ *     deletion of these resources.
+ *
+ *     If contexts or surfaces created with respect to dpy are current (see
+ *     section 3.7.3) to any thread, then they are not actually destroyed
+ *     while they remain current. Such contexts and surfaces will be destroyed
+ *     as soon as eglReleaseThread is called from the thread they are bound
+ *     to, or eglMakeCurrent is called from that thread with the current
+ *     rendering API (see section 3.7) set such that the current context is
+ *     affected. [...]
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+
+#include "piglit-util-egl.h"
+
+#define fail(msg) \
+	do { \
+		fprintf(stderr, "error: %s:%d: %s failed\n", __func__, __LINE__, msg); \
+		piglit_report_result(PIGLIT_FAIL); \
+	} while (0)
+
+int
+main(int argc, char **argv)
+{
+	EGLDisplay dpy;
+	EGLint major_version;
+	EGLint minor_version;
+	EGLConfig config;
+	EGLint num_configs = 0;
+	EGLContext ctx;
+	bool ok;
+
+	dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY );
+	if (!dpy)
+		fail("eglGetDisplay(EGL_DEFAULT_DISPLAY) failed");
+
+	ok = eglInitialize(dpy, &major_version, &minor_version);
+	if (!ok)
+		fail("eglInitialize() failed");
+
+	if (!piglit_is_egl_extension_supported(dpy, "EGL_KHR_surfaceless_context"))
+		piglit_report_result(PIGLIT_SKIP);
+
+	ok = eglChooseConfig(dpy, NULL, &config, 1, &num_configs);
+	if (!ok)
+		fail("eglChooseConfig() failed");
+	if (num_configs == 0)
+		fail("eglChooseConfig() returned no configs\n");
+
+	ctx = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL );
+	if (!ctx)
+		fail("eglCreateContext() failed");
+
+	ok = eglMakeCurrent(dpy, NULL, NULL, ctx);
+	if (!ok)
+		fail("eglMakeCurrent()");
+
+	ok = eglTerminate(dpy);
+	if (!ok)
+	   fail("eglTerminate()");
+
+	/* Unbind the context. */
+	ok = eglMakeCurrent(dpy, NULL, NULL, NULL);
+	if (!ok)
+		fail("eglMakeCurrent(ctx=NULL)");
+
+	piglit_report_result(PIGLIT_PASS);
+	return 0;
+
+}
-- 
1.8.3.1



More information about the Piglit mailing list