115002f60SMarc-André Lureau /* 215002f60SMarc-André Lureau * Error reporting 315002f60SMarc-André Lureau * 415002f60SMarc-André Lureau * Copyright (C) 2010 Red Hat Inc. 515002f60SMarc-André Lureau * 615002f60SMarc-André Lureau * Authors: 715002f60SMarc-André Lureau * Markus Armbruster <armbru@redhat.com>, 815002f60SMarc-André Lureau * 915002f60SMarc-André Lureau * This work is licensed under the terms of the GNU GPL, version 2 or later. 1015002f60SMarc-André Lureau * See the COPYING file in the top-level directory. 1115002f60SMarc-André Lureau */ 1215002f60SMarc-André Lureau 1315002f60SMarc-André Lureau #include "qemu/osdep.h" 1415002f60SMarc-André Lureau #include "monitor/monitor.h" 1515002f60SMarc-André Lureau #include "qemu/error-report.h" 1615002f60SMarc-André Lureau 1715002f60SMarc-André Lureau /* 1815002f60SMarc-André Lureau * @report_type is the type of message: error, warning or 1915002f60SMarc-André Lureau * informational. 2015002f60SMarc-André Lureau */ 2115002f60SMarc-André Lureau typedef enum { 2215002f60SMarc-André Lureau REPORT_TYPE_ERROR, 2315002f60SMarc-André Lureau REPORT_TYPE_WARNING, 2415002f60SMarc-André Lureau REPORT_TYPE_INFO, 2515002f60SMarc-André Lureau } report_type; 2615002f60SMarc-André Lureau 2715002f60SMarc-André Lureau /* Prepend timestamp to messages */ 2815002f60SMarc-André Lureau bool message_with_timestamp; 2915002f60SMarc-André Lureau bool error_with_guestname; 3015002f60SMarc-André Lureau const char *error_guest_name; 3115002f60SMarc-André Lureau 3215002f60SMarc-André Lureau int error_printf(const char *fmt, ...) 3315002f60SMarc-André Lureau { 3415002f60SMarc-André Lureau va_list ap; 3515002f60SMarc-André Lureau int ret; 3615002f60SMarc-André Lureau 3715002f60SMarc-André Lureau va_start(ap, fmt); 3815002f60SMarc-André Lureau ret = error_vprintf(fmt, ap); 3915002f60SMarc-André Lureau va_end(ap); 4015002f60SMarc-André Lureau return ret; 4115002f60SMarc-André Lureau } 4215002f60SMarc-André Lureau 4315002f60SMarc-André Lureau int error_printf_unless_qmp(const char *fmt, ...) 4415002f60SMarc-André Lureau { 4515002f60SMarc-André Lureau va_list ap; 4615002f60SMarc-André Lureau int ret; 4715002f60SMarc-André Lureau 4815002f60SMarc-André Lureau va_start(ap, fmt); 4915002f60SMarc-André Lureau ret = error_vprintf_unless_qmp(fmt, ap); 5015002f60SMarc-André Lureau va_end(ap); 5115002f60SMarc-André Lureau return ret; 5215002f60SMarc-André Lureau } 5315002f60SMarc-André Lureau 5415002f60SMarc-André Lureau static Location std_loc = { 5515002f60SMarc-André Lureau .kind = LOC_NONE 5615002f60SMarc-André Lureau }; 5715002f60SMarc-André Lureau static Location *cur_loc = &std_loc; 5815002f60SMarc-André Lureau 5915002f60SMarc-André Lureau /* 6015002f60SMarc-André Lureau * Push location saved in LOC onto the location stack, return it. 6115002f60SMarc-André Lureau * The top of that stack is the current location. 6215002f60SMarc-André Lureau * Needs a matching loc_pop(). 6315002f60SMarc-André Lureau */ 6415002f60SMarc-André Lureau Location *loc_push_restore(Location *loc) 6515002f60SMarc-André Lureau { 6615002f60SMarc-André Lureau assert(!loc->prev); 6715002f60SMarc-André Lureau loc->prev = cur_loc; 6815002f60SMarc-André Lureau cur_loc = loc; 6915002f60SMarc-André Lureau return loc; 7015002f60SMarc-André Lureau } 7115002f60SMarc-André Lureau 7215002f60SMarc-André Lureau /* 7315002f60SMarc-André Lureau * Initialize *LOC to "nowhere", push it onto the location stack. 7415002f60SMarc-André Lureau * The top of that stack is the current location. 7515002f60SMarc-André Lureau * Needs a matching loc_pop(). 7615002f60SMarc-André Lureau * Return LOC. 7715002f60SMarc-André Lureau */ 7815002f60SMarc-André Lureau Location *loc_push_none(Location *loc) 7915002f60SMarc-André Lureau { 8015002f60SMarc-André Lureau loc->kind = LOC_NONE; 8115002f60SMarc-André Lureau loc->prev = NULL; 8215002f60SMarc-André Lureau return loc_push_restore(loc); 8315002f60SMarc-André Lureau } 8415002f60SMarc-André Lureau 8515002f60SMarc-André Lureau /* 8615002f60SMarc-André Lureau * Pop the location stack. 8715002f60SMarc-André Lureau * LOC must be the current location, i.e. the top of the stack. 8815002f60SMarc-André Lureau */ 8915002f60SMarc-André Lureau Location *loc_pop(Location *loc) 9015002f60SMarc-André Lureau { 9115002f60SMarc-André Lureau assert(cur_loc == loc && loc->prev); 9215002f60SMarc-André Lureau cur_loc = loc->prev; 9315002f60SMarc-André Lureau loc->prev = NULL; 9415002f60SMarc-André Lureau return loc; 9515002f60SMarc-André Lureau } 9615002f60SMarc-André Lureau 9715002f60SMarc-André Lureau /* 9815002f60SMarc-André Lureau * Save the current location in LOC, return LOC. 9915002f60SMarc-André Lureau */ 10015002f60SMarc-André Lureau Location *loc_save(Location *loc) 10115002f60SMarc-André Lureau { 10215002f60SMarc-André Lureau *loc = *cur_loc; 10315002f60SMarc-André Lureau loc->prev = NULL; 10415002f60SMarc-André Lureau return loc; 10515002f60SMarc-André Lureau } 10615002f60SMarc-André Lureau 10715002f60SMarc-André Lureau /* 10815002f60SMarc-André Lureau * Change the current location to the one saved in LOC. 10915002f60SMarc-André Lureau */ 11015002f60SMarc-André Lureau void loc_restore(Location *loc) 11115002f60SMarc-André Lureau { 11215002f60SMarc-André Lureau Location *prev = cur_loc->prev; 11315002f60SMarc-André Lureau assert(!loc->prev); 11415002f60SMarc-André Lureau *cur_loc = *loc; 11515002f60SMarc-André Lureau cur_loc->prev = prev; 11615002f60SMarc-André Lureau } 11715002f60SMarc-André Lureau 11815002f60SMarc-André Lureau /* 11915002f60SMarc-André Lureau * Change the current location to "nowhere in particular". 12015002f60SMarc-André Lureau */ 12115002f60SMarc-André Lureau void loc_set_none(void) 12215002f60SMarc-André Lureau { 12315002f60SMarc-André Lureau cur_loc->kind = LOC_NONE; 12415002f60SMarc-André Lureau } 12515002f60SMarc-André Lureau 12615002f60SMarc-André Lureau /* 12715002f60SMarc-André Lureau * Change the current location to argument ARGV[IDX..IDX+CNT-1]. 12815002f60SMarc-André Lureau */ 12915002f60SMarc-André Lureau void loc_set_cmdline(char **argv, int idx, int cnt) 13015002f60SMarc-André Lureau { 13115002f60SMarc-André Lureau cur_loc->kind = LOC_CMDLINE; 13215002f60SMarc-André Lureau cur_loc->num = cnt; 13315002f60SMarc-André Lureau cur_loc->ptr = argv + idx; 13415002f60SMarc-André Lureau } 13515002f60SMarc-André Lureau 13615002f60SMarc-André Lureau /* 13715002f60SMarc-André Lureau * Change the current location to file FNAME, line LNO. 13815002f60SMarc-André Lureau */ 13915002f60SMarc-André Lureau void loc_set_file(const char *fname, int lno) 14015002f60SMarc-André Lureau { 14115002f60SMarc-André Lureau assert (fname || cur_loc->kind == LOC_FILE); 14215002f60SMarc-André Lureau cur_loc->kind = LOC_FILE; 14315002f60SMarc-André Lureau cur_loc->num = lno; 14415002f60SMarc-André Lureau if (fname) { 14515002f60SMarc-André Lureau cur_loc->ptr = fname; 14615002f60SMarc-André Lureau } 14715002f60SMarc-André Lureau } 14815002f60SMarc-André Lureau 14915002f60SMarc-André Lureau /* 15015002f60SMarc-André Lureau * Print current location to current monitor if we have one, else to stderr. 15115002f60SMarc-André Lureau */ 15215002f60SMarc-André Lureau static void print_loc(void) 15315002f60SMarc-André Lureau { 15415002f60SMarc-André Lureau const char *sep = ""; 15515002f60SMarc-André Lureau int i; 15615002f60SMarc-André Lureau const char *const *argp; 15715002f60SMarc-André Lureau 15815002f60SMarc-André Lureau if (!monitor_cur() && g_get_prgname()) { 159*11fd78dcSMarc-André Lureau error_printf("%s:", g_get_prgname()); 16015002f60SMarc-André Lureau sep = " "; 16115002f60SMarc-André Lureau } 16215002f60SMarc-André Lureau switch (cur_loc->kind) { 16315002f60SMarc-André Lureau case LOC_CMDLINE: 16415002f60SMarc-André Lureau argp = cur_loc->ptr; 16515002f60SMarc-André Lureau for (i = 0; i < cur_loc->num; i++) { 16615002f60SMarc-André Lureau error_printf("%s%s", sep, argp[i]); 16715002f60SMarc-André Lureau sep = " "; 16815002f60SMarc-André Lureau } 16915002f60SMarc-André Lureau error_printf(": "); 17015002f60SMarc-André Lureau break; 17115002f60SMarc-André Lureau case LOC_FILE: 17215002f60SMarc-André Lureau error_printf("%s:", (const char *)cur_loc->ptr); 17315002f60SMarc-André Lureau if (cur_loc->num) { 17415002f60SMarc-André Lureau error_printf("%d:", cur_loc->num); 17515002f60SMarc-André Lureau } 17615002f60SMarc-André Lureau error_printf(" "); 17715002f60SMarc-André Lureau break; 17815002f60SMarc-André Lureau default: 17915002f60SMarc-André Lureau error_printf("%s", sep); 18015002f60SMarc-André Lureau } 18115002f60SMarc-André Lureau } 18215002f60SMarc-André Lureau 18315002f60SMarc-André Lureau static char * 18415002f60SMarc-André Lureau real_time_iso8601(void) 18515002f60SMarc-André Lureau { 18615002f60SMarc-André Lureau #if GLIB_CHECK_VERSION(2, 62, 0) 18715002f60SMarc-André Lureau g_autoptr(GDateTime) dt = g_date_time_new_from_unix_utc(g_get_real_time()); 18815002f60SMarc-André Lureau return g_date_time_format_iso8601(dt); 18915002f60SMarc-André Lureau #else 19015002f60SMarc-André Lureau GTimeVal tv; 19115002f60SMarc-André Lureau g_get_current_time(&tv); 19215002f60SMarc-André Lureau return g_time_val_to_iso8601(&tv); 19315002f60SMarc-André Lureau #endif 19415002f60SMarc-André Lureau } 19515002f60SMarc-André Lureau 19615002f60SMarc-André Lureau /* 19715002f60SMarc-André Lureau * Print a message to current monitor if we have one, else to stderr. 19815002f60SMarc-André Lureau * @report_type is the type of message: error, warning or informational. 19915002f60SMarc-André Lureau * Format arguments like vsprintf(). The resulting message should be 20015002f60SMarc-André Lureau * a single phrase, with no newline or trailing punctuation. 20115002f60SMarc-André Lureau * Prepend the current location and append a newline. 20215002f60SMarc-André Lureau */ 20315002f60SMarc-André Lureau static void vreport(report_type type, const char *fmt, va_list ap) 20415002f60SMarc-André Lureau { 20515002f60SMarc-André Lureau gchar *timestr; 20615002f60SMarc-André Lureau 20715002f60SMarc-André Lureau if (message_with_timestamp && !monitor_cur()) { 20815002f60SMarc-André Lureau timestr = real_time_iso8601(); 20915002f60SMarc-André Lureau error_printf("%s ", timestr); 21015002f60SMarc-André Lureau g_free(timestr); 21115002f60SMarc-André Lureau } 21215002f60SMarc-André Lureau 21315002f60SMarc-André Lureau /* Only prepend guest name if -msg guest-name and -name guest=... are set */ 21415002f60SMarc-André Lureau if (error_with_guestname && error_guest_name && !monitor_cur()) { 21515002f60SMarc-André Lureau error_printf("%s ", error_guest_name); 21615002f60SMarc-André Lureau } 21715002f60SMarc-André Lureau 21815002f60SMarc-André Lureau print_loc(); 21915002f60SMarc-André Lureau 22015002f60SMarc-André Lureau switch (type) { 22115002f60SMarc-André Lureau case REPORT_TYPE_ERROR: 22215002f60SMarc-André Lureau break; 22315002f60SMarc-André Lureau case REPORT_TYPE_WARNING: 22415002f60SMarc-André Lureau error_printf("warning: "); 22515002f60SMarc-André Lureau break; 22615002f60SMarc-André Lureau case REPORT_TYPE_INFO: 22715002f60SMarc-André Lureau error_printf("info: "); 22815002f60SMarc-André Lureau break; 22915002f60SMarc-André Lureau } 23015002f60SMarc-André Lureau 23115002f60SMarc-André Lureau error_vprintf(fmt, ap); 23215002f60SMarc-André Lureau error_printf("\n"); 23315002f60SMarc-André Lureau } 23415002f60SMarc-André Lureau 23515002f60SMarc-André Lureau /* 23615002f60SMarc-André Lureau * Print an error message to current monitor if we have one, else to stderr. 23715002f60SMarc-André Lureau * Format arguments like vsprintf(). The resulting message should be 23815002f60SMarc-André Lureau * a single phrase, with no newline or trailing punctuation. 23915002f60SMarc-André Lureau * Prepend the current location and append a newline. 24015002f60SMarc-André Lureau * It's wrong to call this in a QMP monitor. Use error_setg() there. 24115002f60SMarc-André Lureau */ 24215002f60SMarc-André Lureau void error_vreport(const char *fmt, va_list ap) 24315002f60SMarc-André Lureau { 24415002f60SMarc-André Lureau vreport(REPORT_TYPE_ERROR, fmt, ap); 24515002f60SMarc-André Lureau } 24615002f60SMarc-André Lureau 24715002f60SMarc-André Lureau /* 24815002f60SMarc-André Lureau * Print a warning message to current monitor if we have one, else to stderr. 24915002f60SMarc-André Lureau * Format arguments like vsprintf(). The resulting message should be 25015002f60SMarc-André Lureau * a single phrase, with no newline or trailing punctuation. 25115002f60SMarc-André Lureau * Prepend the current location and append a newline. 25215002f60SMarc-André Lureau */ 25315002f60SMarc-André Lureau void warn_vreport(const char *fmt, va_list ap) 25415002f60SMarc-André Lureau { 25515002f60SMarc-André Lureau vreport(REPORT_TYPE_WARNING, fmt, ap); 25615002f60SMarc-André Lureau } 25715002f60SMarc-André Lureau 25815002f60SMarc-André Lureau /* 25915002f60SMarc-André Lureau * Print an information message to current monitor if we have one, else to 26015002f60SMarc-André Lureau * stderr. 26115002f60SMarc-André Lureau * Format arguments like vsprintf(). The resulting message should be 26215002f60SMarc-André Lureau * a single phrase, with no newline or trailing punctuation. 26315002f60SMarc-André Lureau * Prepend the current location and append a newline. 26415002f60SMarc-André Lureau */ 26515002f60SMarc-André Lureau void info_vreport(const char *fmt, va_list ap) 26615002f60SMarc-André Lureau { 26715002f60SMarc-André Lureau vreport(REPORT_TYPE_INFO, fmt, ap); 26815002f60SMarc-André Lureau } 26915002f60SMarc-André Lureau 27015002f60SMarc-André Lureau /* 27115002f60SMarc-André Lureau * Print an error message to current monitor if we have one, else to stderr. 27215002f60SMarc-André Lureau * Format arguments like sprintf(). The resulting message should be 27315002f60SMarc-André Lureau * a single phrase, with no newline or trailing punctuation. 27415002f60SMarc-André Lureau * Prepend the current location and append a newline. 27515002f60SMarc-André Lureau * It's wrong to call this in a QMP monitor. Use error_setg() there. 27615002f60SMarc-André Lureau */ 27715002f60SMarc-André Lureau void error_report(const char *fmt, ...) 27815002f60SMarc-André Lureau { 27915002f60SMarc-André Lureau va_list ap; 28015002f60SMarc-André Lureau 28115002f60SMarc-André Lureau va_start(ap, fmt); 28215002f60SMarc-André Lureau vreport(REPORT_TYPE_ERROR, fmt, ap); 28315002f60SMarc-André Lureau va_end(ap); 28415002f60SMarc-André Lureau } 28515002f60SMarc-André Lureau 28615002f60SMarc-André Lureau /* 28715002f60SMarc-André Lureau * Print a warning message to current monitor if we have one, else to stderr. 28815002f60SMarc-André Lureau * Format arguments like sprintf(). The resulting message should be a 28915002f60SMarc-André Lureau * single phrase, with no newline or trailing punctuation. 29015002f60SMarc-André Lureau * Prepend the current location and append a newline. 29115002f60SMarc-André Lureau */ 29215002f60SMarc-André Lureau void warn_report(const char *fmt, ...) 29315002f60SMarc-André Lureau { 29415002f60SMarc-André Lureau va_list ap; 29515002f60SMarc-André Lureau 29615002f60SMarc-André Lureau va_start(ap, fmt); 29715002f60SMarc-André Lureau vreport(REPORT_TYPE_WARNING, fmt, ap); 29815002f60SMarc-André Lureau va_end(ap); 29915002f60SMarc-André Lureau } 30015002f60SMarc-André Lureau 30115002f60SMarc-André Lureau /* 30215002f60SMarc-André Lureau * Print an information message to current monitor if we have one, else to 30315002f60SMarc-André Lureau * stderr. 30415002f60SMarc-André Lureau * Format arguments like sprintf(). The resulting message should be a 30515002f60SMarc-André Lureau * single phrase, with no newline or trailing punctuation. 30615002f60SMarc-André Lureau * Prepend the current location and append a newline. 30715002f60SMarc-André Lureau */ 30815002f60SMarc-André Lureau void info_report(const char *fmt, ...) 30915002f60SMarc-André Lureau { 31015002f60SMarc-André Lureau va_list ap; 31115002f60SMarc-André Lureau 31215002f60SMarc-André Lureau va_start(ap, fmt); 31315002f60SMarc-André Lureau vreport(REPORT_TYPE_INFO, fmt, ap); 31415002f60SMarc-André Lureau va_end(ap); 31515002f60SMarc-André Lureau } 31615002f60SMarc-André Lureau 31715002f60SMarc-André Lureau /* 31815002f60SMarc-André Lureau * Like error_report(), except print just once. 31915002f60SMarc-André Lureau * If *printed is false, print the message, and flip *printed to true. 32015002f60SMarc-André Lureau * Return whether the message was printed. 32115002f60SMarc-André Lureau */ 32215002f60SMarc-André Lureau bool error_report_once_cond(bool *printed, const char *fmt, ...) 32315002f60SMarc-André Lureau { 32415002f60SMarc-André Lureau va_list ap; 32515002f60SMarc-André Lureau 32615002f60SMarc-André Lureau assert(printed); 32715002f60SMarc-André Lureau if (*printed) { 32815002f60SMarc-André Lureau return false; 32915002f60SMarc-André Lureau } 33015002f60SMarc-André Lureau *printed = true; 33115002f60SMarc-André Lureau va_start(ap, fmt); 33215002f60SMarc-André Lureau vreport(REPORT_TYPE_ERROR, fmt, ap); 33315002f60SMarc-André Lureau va_end(ap); 33415002f60SMarc-André Lureau return true; 33515002f60SMarc-André Lureau } 33615002f60SMarc-André Lureau 33715002f60SMarc-André Lureau /* 33815002f60SMarc-André Lureau * Like warn_report(), except print just once. 33915002f60SMarc-André Lureau * If *printed is false, print the message, and flip *printed to true. 34015002f60SMarc-André Lureau * Return whether the message was printed. 34115002f60SMarc-André Lureau */ 34215002f60SMarc-André Lureau bool warn_report_once_cond(bool *printed, const char *fmt, ...) 34315002f60SMarc-André Lureau { 34415002f60SMarc-André Lureau va_list ap; 34515002f60SMarc-André Lureau 34615002f60SMarc-André Lureau assert(printed); 34715002f60SMarc-André Lureau if (*printed) { 34815002f60SMarc-André Lureau return false; 34915002f60SMarc-André Lureau } 35015002f60SMarc-André Lureau *printed = true; 35115002f60SMarc-André Lureau va_start(ap, fmt); 35215002f60SMarc-André Lureau vreport(REPORT_TYPE_WARNING, fmt, ap); 35315002f60SMarc-André Lureau va_end(ap); 35415002f60SMarc-André Lureau return true; 35515002f60SMarc-André Lureau } 35615002f60SMarc-André Lureau 35715002f60SMarc-André Lureau static char *qemu_glog_domains; 35815002f60SMarc-André Lureau 35915002f60SMarc-André Lureau static void qemu_log_func(const gchar *log_domain, 36015002f60SMarc-André Lureau GLogLevelFlags log_level, 36115002f60SMarc-André Lureau const gchar *message, 36215002f60SMarc-André Lureau gpointer user_data) 36315002f60SMarc-André Lureau { 36415002f60SMarc-André Lureau switch (log_level & G_LOG_LEVEL_MASK) { 36515002f60SMarc-André Lureau case G_LOG_LEVEL_DEBUG: 36615002f60SMarc-André Lureau case G_LOG_LEVEL_INFO: 36715002f60SMarc-André Lureau /* 36815002f60SMarc-André Lureau * Use same G_MESSAGES_DEBUG logic as glib to enable/disable debug 36915002f60SMarc-André Lureau * messages 37015002f60SMarc-André Lureau */ 37115002f60SMarc-André Lureau if (qemu_glog_domains == NULL) { 37215002f60SMarc-André Lureau break; 37315002f60SMarc-André Lureau } 37415002f60SMarc-André Lureau if (strcmp(qemu_glog_domains, "all") != 0 && 37515002f60SMarc-André Lureau (log_domain == NULL || !strstr(qemu_glog_domains, log_domain))) { 37615002f60SMarc-André Lureau break; 37715002f60SMarc-André Lureau } 37815002f60SMarc-André Lureau /* Fall through */ 37915002f60SMarc-André Lureau case G_LOG_LEVEL_MESSAGE: 38015002f60SMarc-André Lureau info_report("%s%s%s", 38115002f60SMarc-André Lureau log_domain ?: "", log_domain ? ": " : "", message); 38215002f60SMarc-André Lureau 38315002f60SMarc-André Lureau break; 38415002f60SMarc-André Lureau case G_LOG_LEVEL_WARNING: 38515002f60SMarc-André Lureau warn_report("%s%s%s", 38615002f60SMarc-André Lureau log_domain ?: "", log_domain ? ": " : "", message); 38715002f60SMarc-André Lureau break; 38815002f60SMarc-André Lureau case G_LOG_LEVEL_CRITICAL: 38915002f60SMarc-André Lureau case G_LOG_LEVEL_ERROR: 39015002f60SMarc-André Lureau error_report("%s%s%s", 39115002f60SMarc-André Lureau log_domain ?: "", log_domain ? ": " : "", message); 39215002f60SMarc-André Lureau break; 39315002f60SMarc-André Lureau } 39415002f60SMarc-André Lureau } 39515002f60SMarc-André Lureau 39615002f60SMarc-André Lureau void error_init(const char *argv0) 39715002f60SMarc-André Lureau { 39815002f60SMarc-André Lureau const char *p = strrchr(argv0, '/'); 39915002f60SMarc-André Lureau 40015002f60SMarc-André Lureau /* Set the program name for error_print_loc(). */ 40115002f60SMarc-André Lureau g_set_prgname(p ? p + 1 : argv0); 40215002f60SMarc-André Lureau 40315002f60SMarc-André Lureau /* 40415002f60SMarc-André Lureau * This sets up glib logging so libraries using it also print their logs 40515002f60SMarc-André Lureau * through error_report(), warn_report(), info_report(). 40615002f60SMarc-André Lureau */ 40715002f60SMarc-André Lureau g_log_set_default_handler(qemu_log_func, NULL); 40815002f60SMarc-André Lureau g_warn_if_fail(qemu_glog_domains == NULL); 40915002f60SMarc-André Lureau qemu_glog_domains = g_strdup(g_getenv("G_MESSAGES_DEBUG")); 41015002f60SMarc-André Lureau } 411