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