summaryrefslogtreecommitdiffstats
path: root/libdimension
diff options
context:
space:
mode:
Diffstat (limited to 'libdimension')
-rw-r--r--libdimension/error.c81
1 files changed, 33 insertions, 48 deletions
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 <stdio.h> /* For fprintf() */
#include <stdlib.h> /* 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);
}
}