예제 #1
0
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();
}
예제 #2
0
/**
 * 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;
}