summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Brenneman <kbrenneman@nvidia.com>2016-03-22 10:42:19 -0600
committerKyle Brenneman <kbrenneman@nvidia.com>2016-03-29 10:18:02 -0600
commite2d44985d82380fa27f1910ed59a609bb9a1a160 (patch)
tree56148e9e14aa1d6f1e26779422f8bc7bb4d7bba6
parentd7f4370dde9b67c8b5a8a4fd3a3df4507ba7f879 (diff)
Add support for reporting application errors.
The libglvnd libraries will now check for a new environment variable, __GLVND_APP_ERROR_CHECKING. If it's set to a non-zero value, then libglvnd will check for and report some application errors. Many non-libglvnd implementations of libGL.so have been fairly tolerant of certain application bugs. Libglvnd has to be similarly tolerant to support existing apps that the developers can't or won't fix. The new __GLVND_APP_ERROR_CHECKING provides a way to check for some of those errors, so that hopefully there will be fewer broken apps in the future. In addition to the setting itself, this updates the no-op stubs in libGLdispatch to report an error when the app tries to call an OpenGL function without a current context. Later changes will likely add other error checks.
-rw-r--r--src/GLdispatch/GLdispatch.c7
-rw-r--r--src/GLdispatch/Makefile.am1
-rw-r--r--src/GLdispatch/vnd-glapi/mapi/table.c11
-rw-r--r--src/util/Makefile.am3
-rw-r--r--src/util/app_error_check.c81
-rw-r--r--src/util/app_error_check.h79
6 files changed, 173 insertions, 9 deletions
diff --git a/src/GLdispatch/GLdispatch.c b/src/GLdispatch/GLdispatch.c
index aa0b64d..be2f61a 100644
--- a/src/GLdispatch/GLdispatch.c
+++ b/src/GLdispatch/GLdispatch.c
@@ -37,6 +37,7 @@
#include "GLdispatchPrivate.h"
#include "stub.h"
#include "glvnd_pthread.h"
+#include "app_error_check.h"
/*
* Global current dispatch table list. We need this to fix up all current
@@ -193,6 +194,7 @@ void _init(void)
// Here, we only initialize the pthreads imports. Everything else we'll
// deal with in __glDispatchInit.
glvndSetupPthreads();
+ glvndAppErrorCheckInit();
}
void __glDispatchInit(void)
@@ -414,6 +416,11 @@ static inline int PatchingIsDisabledByEnvVar(void)
char *disallowPatchStr = getenv("__GLVND_DISALLOW_PATCHING");
if (disallowPatchStr) {
disallowPatch = atoi(disallowPatchStr);
+ } else if (glvndAppErrorCheckGetEnabled()) {
+ // Entrypoint rewriting means skipping the dispatch table in
+ // libGLdispatch, which would disable checking for calling OpenGL
+ // functions without a context.
+ disallowPatch = GL_TRUE;
}
inited = GL_TRUE;
}
diff --git a/src/GLdispatch/Makefile.am b/src/GLdispatch/Makefile.am
index 9109d35..b26769d 100644
--- a/src/GLdispatch/Makefile.am
+++ b/src/GLdispatch/Makefile.am
@@ -47,6 +47,7 @@ libGLdispatch_la_LDFLAGS += \
libGLdispatch_la_SOURCES = \
$(top_srcdir)/src/util/glvnd_pthread.c \
+ $(top_srcdir)/src/util/app_error_check.c \
GLdispatch.c
libGLdispatch_la_LIBADD = vnd-glapi/libglapi.la
diff --git a/src/GLdispatch/vnd-glapi/mapi/table.c b/src/GLdispatch/vnd-glapi/mapi/table.c
index 0d28666..3c7d926 100644
--- a/src/GLdispatch/vnd-glapi/mapi/table.c
+++ b/src/GLdispatch/vnd-glapi/mapi/table.c
@@ -29,23 +29,18 @@
#include <stdio.h>
#include "table.h"
+#include "app_error_check.h"
static void
noop_warn(const char *name)
{
- static int debug = -1;
-
- if (debug < 0)
- debug = (getenv("MESA_DEBUG") || getenv("LIBGL_DEBUG"));
-
- if (debug)
- fprintf(stderr, "%s is no-op\n", name);
+ glvndAppErrorCheckReportError("%s called without a current context\n", name);
}
static int
noop_generic(void)
{
- noop_warn("function");
+ noop_warn("OpenGL function");
return 0;
}
diff --git a/src/util/Makefile.am b/src/util/Makefile.am
index bb814f5..d4a5432 100644
--- a/src/util/Makefile.am
+++ b/src/util/Makefile.am
@@ -2,6 +2,7 @@ SUBDIRS = trace
noinst_HEADERS = \
glvnd_genentry.h \
utils_misc.h \
- glvnd_pthread.h
+ glvnd_pthread.h \
+ app_error_check.h
EXTRA_DIST = uthash
diff --git a/src/util/app_error_check.c b/src/util/app_error_check.c
new file mode 100644
index 0000000..53318cd
--- /dev/null
+++ b/src/util/app_error_check.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * unaltered in all copies or substantial portions of the Materials.
+ * Any additions, deletions, or changes to the original source files
+ * must be clearly indicated in accompanying documentation.
+ *
+ * If only executable code is distributed, then the accompanying
+ * documentation must state that "this software is based in part on the
+ * work of the Khronos Group."
+ *
+ * THE MATERIALS ARE 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
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ */
+
+#include "app_error_check.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+static int errorCheckingEnabled = 0;
+static int reportAppErrorsEnabled = 0;
+static int abortOnAppError = 0;
+
+void glvndAppErrorCheckInit(void)
+{
+ const char *env;
+
+ env = getenv("__GLVND_APP_ERROR_CHECKING");
+ if (env != NULL) {
+ errorCheckingEnabled = (atoi(env) != 0 ? 1 : 0);
+ if (errorCheckingEnabled) {
+ reportAppErrorsEnabled = 1;
+ abortOnAppError = 1;
+ }
+ }
+
+ env = getenv("__GLVND_ABORT_ON_APP_ERROR");
+ if (env != NULL) {
+ abortOnAppError = (atoi(env) != 0 ? 1 : 0);
+ if (abortOnAppError) {
+ reportAppErrorsEnabled = 1;
+ }
+ }
+}
+
+void glvndAppErrorCheckReportError(const char *format, ...)
+{
+ if (reportAppErrorsEnabled) {
+ va_list args;
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+ fflush(stderr);
+
+ if (abortOnAppError) {
+ abort();
+ }
+ }
+}
+
+int glvndAppErrorCheckGetEnabled(void)
+{
+ return errorCheckingEnabled;
+}
+
diff --git a/src/util/app_error_check.h b/src/util/app_error_check.h
new file mode 100644
index 0000000..cb75b3e
--- /dev/null
+++ b/src/util/app_error_check.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016, NVIDIA CORPORATION.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and/or associated documentation files (the
+ * "Materials"), to deal in the Materials without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Materials, and to
+ * permit persons to whom the Materials are furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * unaltered in all copies or substantial portions of the Materials.
+ * Any additions, deletions, or changes to the original source files
+ * must be clearly indicated in accompanying documentation.
+ *
+ * If only executable code is distributed, then the accompanying
+ * documentation must state that "this software is based in part on the
+ * work of the Khronos Group."
+ *
+ * THE MATERIALS ARE 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
+ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+ */
+
+#ifndef __APP_ERROR_CHECK_H
+#define __APP_ERROR_CHECK_H
+
+#include "compiler.h"
+
+/**
+ * \file
+ *
+ * Functions for reporting application errors.
+ *
+ * These functions are used for reporting application errors that might
+ * otherwise go unnoticed, not for debugging libglvnd itself. For example,
+ * they're used for reporting when an application tries to call an OpenGL
+ * function without a current context.
+ *
+ * There are two environment variables to control this:
+ *
+ * __GLVND_APP_ERROR_CHECKING: This flag will enable whatever application error
+ * checks are available in each component. In the future, there may be other
+ * flags to enable and disable other error checks. If that happens, then the
+ * __GLVND_APP_ERROR_CHECKING flag will still enable all available checks by
+ * default.
+ *
+ * __GLVND_ABORT_ON_APP_ERROR: If set to 1, then libglvnd will call \c abort(3)
+ * when it detects an application error. This is enabled by default if
+ * __GLVND_APP_ERROR_CHECKING is enabled, but the user can manually disable it.
+ */
+
+/**
+ * Initializes the debug output state. This will handle things like reading the
+ * environment variables.
+ */
+void glvndAppErrorCheckInit(void);
+
+/**
+ * Reports an application error.
+ *
+ * If __GLVND_ABORT_ON_APP_ERROR is enabled, then this will also cause the
+ * process to abort, so it should only be used for clear errors.
+ *
+ * \param format A printf-style format string.
+ */
+void glvndAppErrorCheckReportError(const char *format, ...) PRINTFLIKE(1, 2);
+
+/**
+ * Returns non-zero if error checking is enabled.
+ */
+int glvndAppErrorCheckGetEnabled(void);
+
+#endif // __APP_ERROR_CHECK_H