NO_INLINE void G_GNUC_COLD assertion_warning_log(const assertion_data * const data, const char * const fmt, ...) { static str_t *str; va_list args; assertion_message(data, FALSE); if G_UNLIKELY(NULL == str) str = str_new_not_leaking(512); /* * Log additional message. */ va_start(args, fmt); str_vprintf(str, fmt, args); va_end(args); { char time_buf[18]; char prefix[UINT_DEC_BUFLEN + CONST_STRLEN(" (WARNING-): ")]; unsigned stid = thread_small_id(); DECLARE_STR(4); crash_time(time_buf, sizeof time_buf); print_str(time_buf); if (0 == stid) { print_str(" (WARNING): "); } else { str_bprintf(prefix, sizeof prefix, " (WARNING-%u): ", stid); print_str(prefix); } print_str(str_2c(str)); print_str("\n"); flush_err_str(); if (log_stdout_is_distinct()) flush_str(STDOUT_FILENO); } assertion_stacktrace(); }
/** * Log message. */ void gl_logv(const char *domain, GLogLevelFlags flags, const char *fmt, va_list args) { static str_t *msg[THREAD_MAX]; static bool logging[THREAD_MAX]; unsigned stid = thread_small_id(); G_IGNORE_PUSH(-Wformat-nonliteral); /* s_minilogv() call below */ if (logging[stid]) { s_minilogv(flags | G_LOG_FLAG_RECURSION, FALSE, fmt, args); return; } G_IGNORE_POP; /* * This call is thread-unsafe by construction, and supposed to be called * only from the main thread. This is why it's OK to have a global * ``logging'' variable. */ logging[stid] = TRUE; if G_UNLIKELY(NULL == msg[stid]) msg[stid] = str_new_not_leaking(0); str_vprintf(msg[stid], fmt, args); if (handler_cb != NULL) (*handler_cb)(domain, flags, str_2c(msg[stid]), handler_data); else s_minilog(flags, "%s", str_2c(msg[stid])); logging[stid] = FALSE; }