} fr_log_buffer_t;
fr_thread_local_setup(fr_log_buffer_t *, fr_strerror_buffer) /* macro */
+static _Thread_local bool logging_stop; //!< Due to ordering issues we may get errors being
+ ///< logged from within other thread local destructors
+ ///< which cause a crash on exit if the logging buffer
+ ///< has already been freed.
/*
* Explicitly cleanup the memory allocated to the error buffer,
* just in case valgrind complains about it.
*/
-static void _fr_logging_free(void *arg)
+static void _fr_logging_free(UNUSED void *arg)
{
- talloc_free(arg);
+ TALLOC_FREE(fr_strerror_buffer);
+ logging_stop = true;
}
/** Reset cursor state
{
fr_log_buffer_t *buffer;
+ if (logging_stop) return NULL; /* No more logging */
+
buffer = fr_strerror_buffer;
if (!buffer) {
buffer = talloc(NULL, fr_log_buffer_t); /* One byte extra for status */
#define FR_SYSERROR_BUFSIZE (2048)
fr_thread_local_setup(char *, fr_syserror_buffer) /* macro */
+static _Thread_local bool logging_stop; //!< Due to ordering issues we may get errors being
+ ///< logged from within other thread local destructors
+ ///< which cause a crash on exit if the logging buffer
+ ///< has already been freed.
+
+#define HAVE_DEFINITION(_errno) ((_errno) < (int)(sizeof(fr_syserror_macro_names) / sizeof(*fr_syserror_macro_names)))
/*
* Explicitly cleanup the memory allocated to the error buffer,
*/
static void _fr_logging_free(UNUSED void *arg)
{
- TALLOC_FREE(fr_syserror_buffer); /* Set to NULL in case the buffer needs to be recreated */
+ TALLOC_FREE(fr_syserror_buffer);
+ logging_stop = true;
}
/** POSIX-2008 errno macros
buffer = fr_syserror_buffer;
if (!buffer) {
+ /*
+ * Try and produce something useful,
+ * even if the thread is exiting.
+ */
+ if (logging_stop) {
+ if (HAVE_DEFINITION(num)) {
+ return fr_syserror_macro_names[num];
+ }
+ return "";
+ }
+
buffer = talloc_array(NULL, char, FR_SYSERROR_BUFSIZE);
if (!buffer) {
fr_perror("Failed allocating memory for system error buffer");
* Prefix system errors with the macro name and number
* if we're debugging.
*/
- if (num < (int)(sizeof(fr_syserror_macro_names) / sizeof(*fr_syserror_macro_names))) {
+ if (HAVE_DEFINITION(num)) {
p += snprintf(p, end - p, "%s: ", fr_syserror_macro_names[num]);
} else {
p += snprintf(p, end - p, "errno %i: ", num);