From 531e63071a4d86edf45bf745e7e594de4df3db9d Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Wed, 15 Jun 2011 00:06:43 -0600 Subject: Don't force the error handler to deal with recursion. --- libdimension/error.c | 81 +++++++++++++++++++++------------------------------- 1 file changed, 33 insertions(+), 48 deletions(-) (limited to 'libdimension/error.c') diff --git a/libdimension/error.c b/libdimension/error.c index 8fcf1fd..cfeed94 100644 --- a/libdimension/error.c +++ b/libdimension/error.c @@ -28,6 +28,14 @@ #include /* For fprintf() */ #include /* For exit() */ +/** Report internal errors in this file. */ +#define DMNSN_LOCAL_ERROR(str) \ + do { \ + fprintf(stderr, "Dimension ERROR: %s, %s:%u: %s\n", \ + DMNSN_FUNC, __FILE__, __LINE__, (str)); \ + abort(); \ + } while (0) + /** The default fatal error handler. */ static void dmnsn_default_fatal_error_fn(void); @@ -47,27 +55,32 @@ dmnsn_report_error(bool die, const char *func, const char *file, unsigned int line, const char *str) { if (pthread_mutex_lock(&dmnsn_always_die_mutex) != 0) { - fprintf(stderr, "Dimension ERROR: %s, line %u: %s\n", - DMNSN_FUNC, __LINE__, - "Couldn't lock mutex."); - exit(EXIT_FAILURE); + DMNSN_LOCAL_ERROR("Couldn't lock mutex."); } bool always_die = dmnsn_always_die; if (pthread_mutex_unlock(&dmnsn_always_die_mutex) != 0) { - fprintf(stderr, "Dimension ERROR: %s, line %u: %s\n", - DMNSN_FUNC, __LINE__, - "Couldn't unlock mutex."); - exit(EXIT_FAILURE); + DMNSN_LOCAL_ERROR("Couldn't unlock mutex."); } fprintf(stderr, "Dimension %s: %s, %s:%u: %s\n", die ? "ERROR" : "WARNING", func, file, line, str); if (die || always_die) { - /* An error happened, bail out */ - dmnsn_fatal_error_fn *fatal = dmnsn_get_fatal_error_fn(); - fatal(); - exit(EXIT_FAILURE); /* Failsafe in case *dmnsn_fatal doesn't exit */ + /* Prevent infinite recursion if the fatal error function itself calls + dmnsn_error() */ + static __thread bool thread_exiting = false; + + if (thread_exiting) { + if (die) { + DMNSN_LOCAL_ERROR("Error raised while in error handler, aborting."); + } + } else { + thread_exiting = true; + + dmnsn_fatal_error_fn *fatal = dmnsn_get_fatal_error_fn(); + fatal(); + DMNSN_LOCAL_ERROR("Fatal error handler didn't exit."); + } } } @@ -75,17 +88,11 @@ void dmnsn_die_on_warnings(bool always_die) { if (pthread_mutex_lock(&dmnsn_always_die_mutex) != 0) { - fprintf(stderr, "Dimension ERROR: %s, line %u: %s\n", - DMNSN_FUNC, __LINE__, - "Couldn't lock mutex."); - exit(EXIT_FAILURE); + DMNSN_LOCAL_ERROR("Couldn't lock mutex."); } dmnsn_always_die = always_die; if (pthread_mutex_unlock(&dmnsn_always_die_mutex) != 0) { - fprintf(stderr, "Dimension ERROR: %s, line %u: %s\n", - DMNSN_FUNC, __LINE__, - "Couldn't unlock mutex."); - exit(EXIT_FAILURE); + DMNSN_LOCAL_ERROR("Couldn't unlock mutex."); } } @@ -94,17 +101,11 @@ dmnsn_get_fatal_error_fn(void) { dmnsn_fatal_error_fn *fatal; if (pthread_mutex_lock(&dmnsn_fatal_mutex) != 0) { - fprintf(stderr, "Dimension WARNING: %s, line %u: %s\n", - DMNSN_FUNC, __LINE__, - "Couldn't lock fatal error handler mutex."); - exit(EXIT_FAILURE); + DMNSN_LOCAL_ERROR("Couldn't lock fatal error handler mutex."); } fatal = dmnsn_fatal; if (pthread_mutex_unlock(&dmnsn_fatal_mutex) != 0) { - fprintf(stderr, "Dimension WARNING: %s, line %u: %s\n", - DMNSN_FUNC, __LINE__, - "Couldn't unlock fatal error handler mutex."); - exit(EXIT_FAILURE); + DMNSN_LOCAL_ERROR("Couldn't unlock fatal error handler mutex."); } return fatal; } @@ -113,39 +114,23 @@ void dmnsn_set_fatal_error_fn(dmnsn_fatal_error_fn *fatal) { if (pthread_mutex_lock(&dmnsn_fatal_mutex) != 0) { - fprintf(stderr, "Dimension WARNING: %s, line %u: %s\n", - DMNSN_FUNC, __LINE__, - "Couldn't lock fatal error handler mutex."); - exit(EXIT_FAILURE); + DMNSN_LOCAL_ERROR("Couldn't lock fatal error handler mutex."); } dmnsn_fatal = fatal; if (pthread_mutex_unlock(&dmnsn_fatal_mutex) != 0) { - fprintf(stderr, "Dimension WARNING: %s, line %u: %s\n", - DMNSN_FUNC, __LINE__, - "Couldn't unlock fatal error handler mutex."); - exit(EXIT_FAILURE); + DMNSN_LOCAL_ERROR("Couldn't unlock fatal error handler mutex."); } } static void dmnsn_default_fatal_error_fn(void) { - /* Prevent infinite recursion if the fatal error function itself calls - dmnsn_error() */ - static __thread bool thread_exiting = false; - + /* Print a stack trace to standard error */ dmnsn_backtrace(stderr); - if (thread_exiting) { - fprintf(stderr, "Dimension ERROR: %s, line %u: %s\n", - DMNSN_FUNC, __LINE__, - "Error raised while in error handler, aborting."); - abort(); - } else if (dmnsn_is_main_thread()) { - thread_exiting = true; + if (dmnsn_is_main_thread()) { exit(EXIT_FAILURE); } else { - thread_exiting = true; pthread_exit(NULL); } } -- cgit v1.2.3