diff options
author | Kenneth Graunke <kenneth@whitecape.org> | 2015-01-20 20:53:40 -0800 |
---|---|---|
committer | Kenneth Graunke <kenneth@whitecape.org> | 2015-01-20 21:47:18 -0800 |
commit | d8bff3de4af663bb617b938422693333bc98916d (patch) | |
tree | 2755d96f5ac3113521e574a4e60613d2a2aff012 | |
parent | 9f39a0dc78a0a4f8cae49d98eeb95f5f83b0309d (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.c | 31 |
1 files changed, 31 insertions, 0 deletions
@@ -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); |