summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenneth Graunke <kenneth@whitecape.org>2015-01-20 20:53:40 -0800
committerKenneth Graunke <kenneth@whitecape.org>2015-01-20 21:47:18 -0800
commitd8bff3de4af663bb617b938422693333bc98916d (patch)
tree2755d96f5ac3113521e574a4e60613d2a2aff012
parent9f39a0dc78a0a4f8cae49d98eeb95f5f83b0309d (diff)
run: Print which shaders were being processed when crashing.
If the driver hits an assertion failure and aborts, the runner will die, which can be hard to debug. This patch makes the runner catch SIGABRT and SIGSEGV and and print out a list of shaders each thread was processing before it terminates. => CRASHED <= while processing these shaders: shaders/foo/1936.shader_test shaders/foo/9991.shader_test shaders/foo/1832.shader_test v2: Handle SIGSEGV too, since SIGABRT doesn't catch real crashes (such as null pointer dereferences). Call _exit() to avoid continuing. Use write() in the signal handler since fputs() is not signal safe. According to an Austin Group bug tracker entry, strlen() is signal safe, so using it should be fine.
-rw-r--r--run.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/run.c b/run.c
index 5f89c50..8628f71 100644
--- a/run.c
+++ b/run.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
+#include <signal.h>
/* for memmem(). The man page doesn't say __USE_GNU... */
#define __USE_GNU
#include <string.h>
@@ -232,6 +233,26 @@ gather_shader_test(const char *fpath, const struct stat *sb, int typeflag)
return 0;
}
+const char **current_shader_names;
+int max_threads;
+
+#define sigputs(str) write(STDERR_FILENO, str, strlen(str))
+
+static void
+abort_handler(int signo)
+{
+ sigputs("\n => CRASHED <= while processing these shaders:\n\n");
+ for (int i = 0; i < max_threads; i++) {
+ if (current_shader_names[i]) {
+ sigputs(" ");
+ sigputs(current_shader_names[i]);
+ sigputs("\n");
+ }
+ }
+ sigputs("\n");
+ _exit(-1);
+}
+
int
main(int argc, char **argv)
{
@@ -394,6 +415,14 @@ main(int argc, char **argv)
ftw(argv[i], gather_shader_test, 100);
}
+ max_threads = omp_get_max_threads();
+ current_shader_names = calloc(max_threads, sizeof(const char *));
+
+ if (signal(SIGABRT, abort_handler) == SIG_ERR)
+ fprintf(stderr, "WARNING: could not install SIGABRT handler.\n");
+ if (signal(SIGSEGV, abort_handler) == SIG_ERR)
+ fprintf(stderr, "WARNING: could not install SIGSEGV handler.\n");
+
#pragma omp parallel if(shader_test_length > omp_get_max_threads())
{
const char *current_shader_name;
@@ -444,6 +473,7 @@ main(int argc, char **argv)
#pragma omp for schedule(dynamic)
for (int i = 0; i < shader_test_length; i++) {
current_shader_name = shader_test[i].filename;
+ current_shader_names[omp_get_thread_num()] = current_shader_name;
int fd = open(current_shader_name, O_RDONLY);
if (unlikely(fd == -1)) {
@@ -544,6 +574,7 @@ main(int argc, char **argv)
shaders_compiled, ctx_switches);
}
+ free(current_shader_names);
free(shader_test);
free(core.extension_string);