From 43b48cfc3e8ff745a10a6b78a55519d5cf7ec5e8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 28 Oct 2015 07:06:26 +0100 Subject: trace: count number of enabled events This lets trace_event_get_state_dynamic quickly return false. Right now there is hardly any benefit because there are also many assertions and indirections, but the next patch will streamline all of this. Signed-off-by: Paolo Bonzini Signed-off-by: Stefan Hajnoczi --- trace/control-internal.h | 4 +++- trace/control.c | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/trace/control-internal.h b/trace/control-internal.h index 5a8df28..271bddb 100644 --- a/trace/control-internal.h +++ b/trace/control-internal.h @@ -14,6 +14,7 @@ extern TraceEvent trace_events[]; +extern int trace_events_enabled_count; static inline TraceEventID trace_event_count(void) @@ -54,13 +55,14 @@ static inline bool trace_event_get_state_static(TraceEvent *ev) static inline bool trace_event_get_state_dynamic(TraceEvent *ev) { assert(ev != NULL); - return ev->dstate; + return unlikely(trace_events_enabled_count) && ev->dstate; } static inline void trace_event_set_state_dynamic(TraceEvent *ev, bool state) { assert(ev != NULL); assert(trace_event_get_state_static(ev)); + trace_events_enabled_count += state - ev->dstate; ev->dstate = state; } diff --git a/trace/control.c b/trace/control.c index 995beb3..95fbc07 100644 --- a/trace/control.c +++ b/trace/control.c @@ -16,6 +16,8 @@ #endif #include "qemu/error-report.h" +int trace_events_enabled_count; + TraceEvent *trace_event_name(const char *name) { assert(name != NULL); -- cgit v1.1 From 585ec7273e6fdab902b2128bc6c2a8136aafef04 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 28 Oct 2015 07:06:27 +0100 Subject: trace: track enabled events in a separate array This is more cache friendly on the fast path, where we already have the event id available. Signed-off-by: Paolo Bonzini Signed-off-by: Stefan Hajnoczi --- scripts/tracetool/format/events_c.py | 2 +- trace/control-internal.h | 15 +++++++++++---- trace/control.c | 1 + trace/control.h | 2 +- trace/event-internal.h | 2 -- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/scripts/tracetool/format/events_c.py b/scripts/tracetool/format/events_c.py index 2d97fa3..2717ea3 100644 --- a/scripts/tracetool/format/events_c.py +++ b/scripts/tracetool/format/events_c.py @@ -27,7 +27,7 @@ def generate(events, backend): out('TraceEvent trace_events[TRACE_EVENT_COUNT] = {') for e in events: - out(' { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s, .dstate = 0 },', + out(' { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s },', id = "TRACE_" + e.name.upper(), name = e.name, sstate = "TRACE_%s_ENABLED" % e.name.upper()) diff --git a/trace/control-internal.h b/trace/control-internal.h index 271bddb..07cb1c1 100644 --- a/trace/control-internal.h +++ b/trace/control-internal.h @@ -14,6 +14,7 @@ extern TraceEvent trace_events[]; +extern bool trace_events_dstate[]; extern int trace_events_enabled_count; @@ -52,18 +53,24 @@ static inline bool trace_event_get_state_static(TraceEvent *ev) return ev->sstate; } +static inline bool trace_event_get_state_dynamic_by_id(int id) +{ + return unlikely(trace_events_enabled_count) && trace_events_dstate[id]; +} + static inline bool trace_event_get_state_dynamic(TraceEvent *ev) { - assert(ev != NULL); - return unlikely(trace_events_enabled_count) && ev->dstate; + int id = trace_event_get_id(ev); + return trace_event_get_state_dynamic_by_id(id); } static inline void trace_event_set_state_dynamic(TraceEvent *ev, bool state) { + int id = trace_event_get_id(ev); assert(ev != NULL); assert(trace_event_get_state_static(ev)); - trace_events_enabled_count += state - ev->dstate; - ev->dstate = state; + trace_events_enabled_count += state - trace_events_dstate[id]; + trace_events_dstate[id] = state; } #endif /* TRACE__CONTROL_INTERNAL_H */ diff --git a/trace/control.c b/trace/control.c index 95fbc07..700440c 100644 --- a/trace/control.c +++ b/trace/control.c @@ -17,6 +17,7 @@ #include "qemu/error-report.h" int trace_events_enabled_count; +bool trace_events_dstate[TRACE_EVENT_COUNT]; TraceEvent *trace_event_name(const char *name) { diff --git a/trace/control.h b/trace/control.h index da9bb6b..6af7ddc 100644 --- a/trace/control.h +++ b/trace/control.h @@ -104,7 +104,7 @@ static const char * trace_event_get_name(TraceEvent *ev); * As a down side, you must always use an immediate #TraceEventID value. */ #define trace_event_get_state(id) \ - ((id ##_ENABLED) && trace_event_get_state_dynamic(trace_event_id(id))) + ((id ##_ENABLED) && trace_event_get_state_dynamic_by_id(id)) /** * trace_event_get_state_static: diff --git a/trace/event-internal.h b/trace/event-internal.h index b2310d9..86f6a51 100644 --- a/trace/event-internal.h +++ b/trace/event-internal.h @@ -18,7 +18,6 @@ * @id: Unique event identifier. * @name: Event name. * @sstate: Static tracing state. - * @dstate: Dynamic tracing state. * * Opaque generic description of a tracing event. */ @@ -26,7 +25,6 @@ typedef struct TraceEvent { TraceEventID id; const char * name; const bool sstate; - bool dstate; } TraceEvent; -- cgit v1.1 From 52449a314e100e2db990ab9a156bb0173017f28d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 7 Jan 2016 16:55:22 +0300 Subject: trace: fix documentation Mention the ftrace backend too. Signed-off-by: Paolo Bonzini Signed-off-by: Denis V. Lunev Acked-by: Christian Borntraeger Message-id: 1452174932-28657-2-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- qemu-options.hx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index f31a240..cbb4590 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3558,13 +3558,13 @@ Specify tracing options. @table @option @item events=@var{file} Immediately enable events listed in @var{file}. -The file must contain one event name (as listed in the @var{trace-events} file) -per line. -This option is only available if QEMU has been compiled with -either @var{simple} or @var{stderr} tracing backend. +The file must contain one event name (as listed in the @file{trace-events} file) +per line; globbing patterns are accepted too. This option is only +available if QEMU has been compiled with the @var{simple}, @var{stderr} or +@var{ftrace} tracing backend. + @item file=@var{file} Log output traces to @var{file}. - This option is only available if QEMU has been compiled with the @var{simple} tracing backend. @end table -- cgit v1.1 From 45bd0b41bdbf554e49fb510673309164c513a8c8 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 7 Jan 2016 16:55:23 +0300 Subject: trace: split trace_init_events out of trace_init_backends This is cleaner and has two advantages. First, it improves error reporting with -daemonize. Second, multiple "-trace events" options now cumulate. Signed-off-by: Paolo Bonzini Signed-off-by: Denis V. Lunev Acked-by: Christian Borntraeger Message-id: 1452174932-28657-3-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- qemu-io.c | 2 +- trace/control.c | 5 ++--- trace/control.h | 15 ++++++++++++--- vl.c | 8 ++++---- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/qemu-io.c b/qemu-io.c index d593f19..1c11d57 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -435,7 +435,7 @@ int main(int argc, char **argv) } break; case 'T': - if (!trace_init_backends(optarg, NULL)) { + if (!trace_init_backends(optarg)) { exit(1); /* error message will have been printed */ } break; diff --git a/trace/control.c b/trace/control.c index 700440c..931d64c 100644 --- a/trace/control.c +++ b/trace/control.c @@ -88,7 +88,7 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev) return NULL; } -static void trace_init_events(const char *fname) +void trace_init_events(const char *fname) { Location loc; FILE *fp; @@ -145,7 +145,7 @@ static void trace_init_events(const char *fname) loc_pop(&loc); } -bool trace_init_backends(const char *events, const char *file) +bool trace_init_backends(const char *file) { #ifdef CONFIG_TRACE_SIMPLE if (!st_init(file)) { @@ -167,6 +167,5 @@ bool trace_init_backends(const char *events, const char *file) } #endif - trace_init_events(events); return true; } diff --git a/trace/control.h b/trace/control.h index 6af7ddc..7905917 100644 --- a/trace/control.h +++ b/trace/control.h @@ -150,8 +150,6 @@ static void trace_event_set_state_dynamic(TraceEvent *ev, bool state); /** * trace_init_backends: - * @events: Name of file with events to be enabled at startup; may be NULL. - * Corresponds to commandline option "-trace events=...". * @file: Name of trace output file; may be NULL. * Corresponds to commandline option "-trace file=...". * @@ -159,7 +157,18 @@ static void trace_event_set_state_dynamic(TraceEvent *ev, bool state); * * Returns: Whether the backends could be successfully initialized. */ -bool trace_init_backends(const char *events, const char *file); +bool trace_init_backends(const char *file); + +/** + * trace_init_events: + * @events: Name of file with events to be enabled at startup; may be NULL. + * Corresponds to commandline option "-trace events=...". + * + * Read the list of enabled tracing events. + * + * Returns: Whether the backends could be successfully initialized. + */ +void trace_init_events(const char *file); #include "trace/control-internal.h" diff --git a/vl.c b/vl.c index f043009..ff2a7d5 100644 --- a/vl.c +++ b/vl.c @@ -2988,7 +2988,6 @@ int main(int argc, char **argv, char **envp) bool userconfig = true; const char *log_mask = NULL; const char *log_file = NULL; - const char *trace_events = NULL; const char *trace_file = NULL; ram_addr_t maxram_size; uint64_t ram_slots = 0; @@ -3905,8 +3904,9 @@ int main(int argc, char **argv, char **envp) if (!opts) { exit(1); } - trace_events = qemu_opt_get(opts, "events"); + trace_init_events(qemu_opt_get(opts, "events")); trace_file = qemu_opt_get(opts, "file"); + qemu_opts_del(opts); break; } case QEMU_OPTION_readconfig: @@ -4106,7 +4106,7 @@ int main(int argc, char **argv, char **envp) } if (!is_daemonized()) { - if (!trace_init_backends(trace_events, trace_file)) { + if (!trace_init_backends(trace_file)) { exit(1); } } @@ -4653,7 +4653,7 @@ int main(int argc, char **argv, char **envp) os_setup_post(); if (is_daemonized()) { - if (!trace_init_backends(trace_events, trace_file)) { + if (!trace_init_backends(trace_file)) { exit(1); } } -- cgit v1.1 From 41fc57e44ed64cd4ab5393d83624afd897dabd4f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 7 Jan 2016 16:55:24 +0300 Subject: trace: split trace_init_file out of trace_init_backends This is cleaner, and improves error reporting with -daemonize. Signed-off-by: Paolo Bonzini Signed-off-by: Denis V. Lunev Acked-by: Christian Borntraeger Message-id: 1452174932-28657-4-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- qemu-io.c | 2 +- trace/control.c | 17 ++++++++++++----- trace/control.h | 13 ++++++++++++- trace/simple.c | 6 ++---- trace/simple.h | 4 ++-- vl.c | 13 +++++++++---- 6 files changed, 38 insertions(+), 17 deletions(-) diff --git a/qemu-io.c b/qemu-io.c index 1c11d57..83c48f4 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -435,7 +435,7 @@ int main(int argc, char **argv) } break; case 'T': - if (!trace_init_backends(optarg)) { + if (!trace_init_backends()) { exit(1); /* error message will have been printed */ } break; diff --git a/trace/control.c b/trace/control.c index 931d64c..f5a497a 100644 --- a/trace/control.c +++ b/trace/control.c @@ -145,17 +145,24 @@ void trace_init_events(const char *fname) loc_pop(&loc); } -bool trace_init_backends(const char *file) +void trace_init_file(const char *file) { #ifdef CONFIG_TRACE_SIMPLE - if (!st_init(file)) { - fprintf(stderr, "failed to initialize simple tracing backend.\n"); - return false; - } + st_set_trace_file(file); #else if (file) { fprintf(stderr, "error: -trace file=...: " "option not supported by the selected tracing backends\n"); + exit(1); + } +#endif +} + +bool trace_init_backends(void) +{ +#ifdef CONFIG_TRACE_SIMPLE + if (!st_init()) { + fprintf(stderr, "failed to initialize simple tracing backend.\n"); return false; } #endif diff --git a/trace/control.h b/trace/control.h index 7905917..d50f399 100644 --- a/trace/control.h +++ b/trace/control.h @@ -157,7 +157,7 @@ static void trace_event_set_state_dynamic(TraceEvent *ev, bool state); * * Returns: Whether the backends could be successfully initialized. */ -bool trace_init_backends(const char *file); +bool trace_init_backends(void); /** * trace_init_events: @@ -170,6 +170,17 @@ bool trace_init_backends(const char *file); */ void trace_init_events(const char *file); +/** + * trace_init_file: + * @file: Name of trace output file; may be NULL. + * Corresponds to commandline option "-trace file=...". + * + * Record the name of the output file for the tracing backend. + * Exits if no selected backend does not support specifying the + * output file, and a non-NULL file was passed. + */ +void trace_init_file(const char *file); + #include "trace/control-internal.h" diff --git a/trace/simple.c b/trace/simple.c index 56a624c..e8594cd 100644 --- a/trace/simple.c +++ b/trace/simple.c @@ -322,7 +322,7 @@ void st_set_trace_file_enabled(bool enable) * @file The trace file name or NULL for the default name- set at * config time */ -bool st_set_trace_file(const char *file) +void st_set_trace_file(const char *file) { st_set_trace_file_enabled(false); @@ -336,7 +336,6 @@ bool st_set_trace_file(const char *file) } st_set_trace_file_enabled(true); - return true; } void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)) @@ -374,7 +373,7 @@ static GThread *trace_thread_create(GThreadFunc fn) return thread; } -bool st_init(const char *file) +bool st_init(void) { GThread *thread; @@ -387,6 +386,5 @@ bool st_init(const char *file) } atexit(st_flush_trace_buffer); - st_set_trace_file(file); return true; } diff --git a/trace/simple.h b/trace/simple.h index 6997996..8d1a32e 100644 --- a/trace/simple.h +++ b/trace/simple.h @@ -20,8 +20,8 @@ void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf); void st_set_trace_file_enabled(bool enable); -bool st_set_trace_file(const char *file); -bool st_init(const char *file); +void st_set_trace_file(const char *file); +bool st_init(void); void st_flush_trace_buffer(void); typedef struct { diff --git a/vl.c b/vl.c index ff2a7d5..955f364 100644 --- a/vl.c +++ b/vl.c @@ -2988,7 +2988,7 @@ int main(int argc, char **argv, char **envp) bool userconfig = true; const char *log_mask = NULL; const char *log_file = NULL; - const char *trace_file = NULL; + char *trace_file = NULL; ram_addr_t maxram_size; uint64_t ram_slots = 0; FILE *vmstate_dump_file = NULL; @@ -3905,7 +3905,10 @@ int main(int argc, char **argv, char **envp) exit(1); } trace_init_events(qemu_opt_get(opts, "events")); - trace_file = qemu_opt_get(opts, "file"); + if (trace_file) { + g_free(trace_file); + } + trace_file = g_strdup(qemu_opt_get(opts, "file")); qemu_opts_del(opts); break; } @@ -4089,6 +4092,8 @@ int main(int argc, char **argv, char **envp) exit(0); } + trace_init_file(trace_file); + /* Open the logfile at this point and set the log mask if necessary. */ if (log_file) { @@ -4106,7 +4111,7 @@ int main(int argc, char **argv, char **envp) } if (!is_daemonized()) { - if (!trace_init_backends(trace_file)) { + if (!trace_init_backends()) { exit(1); } } @@ -4653,7 +4658,7 @@ int main(int argc, char **argv, char **envp) os_setup_post(); if (is_daemonized()) { - if (!trace_init_backends(trace_file)) { + if (!trace_init_backends()) { exit(1); } } -- cgit v1.1 From f246b86672118e4f0d0782f4c240d3666aa36710 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Thu, 7 Jan 2016 16:55:25 +0300 Subject: trace: no need to call trace_backend_init in different branches now original idea to split calling locations was to spawn tracing thread in the final child process according to commit 8a745f2a9296ad2cf6bda33534ed298f2625a4ad Author: Michael Mueller Date: Mon Sep 23 16:36:54 2013 +0200 os_daemonize is now on top of both locations. Drop unneeded ifs. Signed-off-by: Denis V. Lunev Reviewed-by: Paolo Bonzini Signed-off-by: Paolo Bonzini Message-id: 1452174932-28657-5-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- vl.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/vl.c b/vl.c index 955f364..6370efe 100644 --- a/vl.c +++ b/vl.c @@ -4110,10 +4110,8 @@ int main(int argc, char **argv, char **envp) qemu_set_log(mask); } - if (!is_daemonized()) { - if (!trace_init_backends()) { - exit(1); - } + if (!trace_init_backends()) { + exit(1); } /* If no data_dir is specified then try to find it relative to the @@ -4657,12 +4655,6 @@ int main(int argc, char **argv, char **envp) os_setup_post(); - if (is_daemonized()) { - if (!trace_init_backends()) { - exit(1); - } - } - main_loop(); replay_disable_events(); -- cgit v1.1 From 10578a257d94fb59449d0b0e441990c45a036ccc Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 7 Jan 2016 16:55:26 +0300 Subject: trace: add "-trace enable=..." Allow enabling events without going through a file, for example: qemu-system-x86_64 -trace bdrv_aio_writev -trace bdrv_aio_readv or with globbing too: qemu-system-x86_64 -trace 'bdrv_aio_*' if an appropriate backend is enabled (simple, stderr, ftrace). Signed-off-by: Paolo Bonzini Signed-off-by: Denis V. Lunev Acked-by: Christian Borntraeger Message-id: 1452174932-28657-6-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- qemu-options.hx | 10 +++++++++- trace/control.c | 48 +++++++++++++++++++++++++++--------------------- trace/control.h | 9 +++++++++ vl.c | 11 +++++++++-- 4 files changed, 54 insertions(+), 24 deletions(-) diff --git a/qemu-options.hx b/qemu-options.hx index cbb4590..35dc725 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3544,7 +3544,7 @@ config files on @var{sysconfdir}, but won't make it skip the QEMU-provided confi files from @var{datadir}. ETEXI DEF("trace", HAS_ARG, QEMU_OPTION_trace, - "-trace [events=][,file=]\n" + "-trace [[enable=]][,events=][,file=]\n" " specify tracing options\n", QEMU_ARCH_ALL) STEXI @@ -3556,6 +3556,14 @@ HXCOMM HX does not support conditional compilation of text. Specify tracing options. @table @option +@item [enable=]@var{pattern} +Immediately enable events matching @var{pattern}. +The file must contain one event name (as listed in the @file{trace-events} file) +per line; globbing patterns are accepted too. This option is only +available if QEMU has been compiled with the @var{simple}, @var{stderr} +or @var{ftrace} tracing backend. To specify multiple events or patterns, +specify the @option{-trace} option multiple times. + @item events=@var{file} Immediately enable events listed in @var{file}. The file must contain one event name (as listed in the @file{trace-events} file) diff --git a/trace/control.c b/trace/control.c index f5a497a..af92705 100644 --- a/trace/control.c +++ b/trace/control.c @@ -88,6 +88,32 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev) return NULL; } +void trace_enable_events(const char *line_buf) +{ + const bool enable = ('-' != line_buf[0]); + const char *line_ptr = enable ? line_buf : line_buf + 1; + + if (trace_event_is_pattern(line_ptr)) { + TraceEvent *ev = NULL; + while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) { + if (trace_event_get_state_static(ev)) { + trace_event_set_state_dynamic(ev, enable); + } + } + } else { + TraceEvent *ev = trace_event_name(line_ptr); + if (ev == NULL) { + error_report("WARNING: trace event '%s' does not exist", + line_ptr); + } else if (!trace_event_get_state_static(ev)) { + error_report("WARNING: trace event '%s' is not traceable", + line_ptr); + } else { + trace_event_set_state_dynamic(ev, enable); + } + } +} + void trace_init_events(const char *fname) { Location loc; @@ -114,27 +140,7 @@ void trace_init_events(const char *fname) if ('#' == line_buf[0]) { /* skip commented lines */ continue; } - const bool enable = ('-' != line_buf[0]); - char *line_ptr = enable ? line_buf : line_buf + 1; - if (trace_event_is_pattern(line_ptr)) { - TraceEvent *ev = NULL; - while ((ev = trace_event_pattern(line_ptr, ev)) != NULL) { - if (trace_event_get_state_static(ev)) { - trace_event_set_state_dynamic(ev, enable); - } - } - } else { - TraceEvent *ev = trace_event_name(line_ptr); - if (ev == NULL) { - error_report("WARNING: trace event '%s' does not exist", - line_ptr); - } else if (!trace_event_get_state_static(ev)) { - error_report("WARNING: trace event '%s' is not traceable", - line_ptr); - } else { - trace_event_set_state_dynamic(ev, enable); - } - } + trace_enable_events(line_buf); } } if (fclose(fp) != 0) { diff --git a/trace/control.h b/trace/control.h index d50f399..d5081ce 100644 --- a/trace/control.h +++ b/trace/control.h @@ -181,6 +181,15 @@ void trace_init_events(const char *file); */ void trace_init_file(const char *file); +/** + * trace_enable_events: + * @line_buf: A string with a glob pattern of events to be enabled or, + * if the string starts with '-', disabled. + * + * Enable or disable matching events. + */ +void trace_enable_events(const char *line_buf); + #include "trace/control-internal.h" diff --git a/vl.c b/vl.c index 6370efe..58cc050 100644 --- a/vl.c +++ b/vl.c @@ -270,10 +270,14 @@ static QemuOptsList qemu_sandbox_opts = { static QemuOptsList qemu_trace_opts = { .name = "trace", - .implied_opt_name = "trace", + .implied_opt_name = "enable", .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head), .desc = { { + .name = "enable", + .type = QEMU_OPT_STRING, + }, + { .name = "events", .type = QEMU_OPT_STRING, },{ @@ -3900,10 +3904,13 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_trace: { opts = qemu_opts_parse_noisily(qemu_find_opts("trace"), - optarg, false); + optarg, true); if (!opts) { exit(1); } + if (qemu_opt_get(opts, "enable")) { + trace_enable_events(qemu_opt_get(opts, "enable")); + } trace_init_events(qemu_opt_get(opts, "events")); if (trace_file) { g_free(trace_file); -- cgit v1.1 From e9527dd399ed213ec6eb2c0ea54be663a73032b0 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 7 Jan 2016 16:55:27 +0300 Subject: trace: add "-trace help" Print a list of trace points Signed-off-by: Paolo Bonzini Signed-off-by: Denis V. Lunev Acked-by: Christian Borntraeger Message-id: 1452174932-28657-7-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- qemu-options.hx | 2 ++ trace/control.c | 21 ++++++++++++++++++++- trace/control.h | 7 +++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/qemu-options.hx b/qemu-options.hx index 35dc725..733a194 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3564,6 +3564,8 @@ available if QEMU has been compiled with the @var{simple}, @var{stderr} or @var{ftrace} tracing backend. To specify multiple events or patterns, specify the @option{-trace} option multiple times. +Use @code{-trace help} to print a list of names of trace points. + @item events=@var{file} Immediately enable events listed in @var{file}. The file must contain one event name (as listed in the @file{trace-events} file) diff --git a/trace/control.c b/trace/control.c index af92705..bef7884 100644 --- a/trace/control.c +++ b/trace/control.c @@ -88,7 +88,16 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev) return NULL; } -void trace_enable_events(const char *line_buf) +void trace_list_events(void) +{ + int i; + for (i = 0; i < trace_event_count(); i++) { + TraceEvent *res = trace_event_id(i); + fprintf(stderr, "%s\n", trace_event_get_name(res)); + } +} + +static void do_trace_enable_events(const char *line_buf) { const bool enable = ('-' != line_buf[0]); const char *line_ptr = enable ? line_buf : line_buf + 1; @@ -114,6 +123,16 @@ void trace_enable_events(const char *line_buf) } } +void trace_enable_events(const char *line_buf) +{ + if (is_help_option(line_buf)) { + trace_list_events(); + exit(0); + } else { + do_trace_enable_events(line_buf); + } +} + void trace_init_events(const char *fname) { Location loc; diff --git a/trace/control.h b/trace/control.h index d5081ce..d5bc86e 100644 --- a/trace/control.h +++ b/trace/control.h @@ -182,6 +182,13 @@ void trace_init_events(const char *file); void trace_init_file(const char *file); /** + * trace_list_events: + * + * List all available events. + */ +void trace_list_events(void); + +/** * trace_enable_events: * @line_buf: A string with a glob pattern of events to be enabled or, * if the string starts with '-', disabled. -- cgit v1.1 From 508127e243122cf3ed67d2aaa472a1b4f1be055e Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 7 Jan 2016 16:55:28 +0300 Subject: log: do not unnecessarily include qom/cpu.h Split the bits that require it to exec/log.h. Signed-off-by: Paolo Bonzini Signed-off-by: Denis V. Lunev Acked-by: Christian Borntraeger Message-id: 1452174932-28657-8-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- bsd-user/main.c | 1 + cpu-exec.c | 1 + exec.c | 1 + hw/acpi/cpu_hotplug.c | 1 + hw/timer/a9gtimer.c | 1 + include/exec/log.h | 60 +++++++++++++++++++++++++++++++++++++++++++ include/qemu/log.h | 59 ------------------------------------------ linux-user/main.c | 1 + qom/cpu.c | 1 + target-alpha/translate.c | 1 + target-arm/translate-a64.c | 1 + target-arm/translate.c | 1 + target-cris/translate.c | 1 + target-i386/seg_helper.c | 1 + target-i386/smm_helper.c | 1 + target-i386/translate.c | 1 + target-lm32/helper.c | 1 + target-lm32/translate.c | 1 + target-m68k/translate.c | 1 + target-microblaze/helper.c | 1 + target-microblaze/translate.c | 1 + target-mips/helper.c | 1 + target-mips/translate.c | 1 + target-moxie/translate.c | 1 + target-openrisc/translate.c | 1 + target-ppc/mmu-hash32.c | 1 + target-ppc/mmu-hash64.c | 1 + target-ppc/mmu_helper.c | 1 + target-ppc/translate.c | 1 + target-s390x/translate.c | 1 + target-sh4/helper.c | 1 + target-sh4/translate.c | 1 + target-sparc/int32_helper.c | 1 + target-sparc/int64_helper.c | 1 + target-sparc/translate.c | 1 + target-tilegx/translate.c | 1 + target-tricore/translate.c | 1 + target-unicore32/translate.c | 1 + target-xtensa/translate.c | 1 + tcg/tcg.c | 1 + translate-all.c | 1 + 41 files changed, 99 insertions(+), 59 deletions(-) create mode 100644 include/exec/log.h diff --git a/bsd-user/main.c b/bsd-user/main.c index 1ecaeb5..fefcfc1 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -33,6 +33,7 @@ #include "tcg.h" #include "qemu/timer.h" #include "qemu/envlist.h" +#include "exec/log.h" int singlestep; unsigned long mmap_min_addr; diff --git a/cpu-exec.c b/cpu-exec.c index c459364..fd92452 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -27,6 +27,7 @@ #include "exec/address-spaces.h" #include "qemu/rcu.h" #include "exec/tb-hash.h" +#include "exec/log.h" #if defined(TARGET_I386) && !defined(CONFIG_USER_ONLY) #include "hw/i386/apic.h" #endif diff --git a/exec.c b/exec.c index 9e076bc..ab37360 100644 --- a/exec.c +++ b/exec.c @@ -52,6 +52,7 @@ #include "exec/memory-internal.h" #include "exec/ram_addr.h" +#include "exec/log.h" #include "qemu/range.h" #ifndef _WIN32 diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c index 2f99ec5..5a410a5 100644 --- a/hw/acpi/cpu_hotplug.c +++ b/hw/acpi/cpu_hotplug.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "hw/acpi/cpu_hotplug.h" +#include "qom/cpu.h" static uint64_t cpu_status_read(void *opaque, hwaddr addr, unsigned int size) { diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c index c11a7bc..fa4602c 100644 --- a/hw/timer/a9gtimer.c +++ b/hw/timer/a9gtimer.c @@ -25,6 +25,7 @@ #include "qemu/timer.h" #include "qemu/bitops.h" #include "qemu/log.h" +#include "qom/cpu.h" #ifndef A9_GTIMER_ERR_DEBUG #define A9_GTIMER_ERR_DEBUG 0 diff --git a/include/exec/log.h b/include/exec/log.h new file mode 100644 index 0000000..ba1c9b5 --- /dev/null +++ b/include/exec/log.h @@ -0,0 +1,60 @@ +#ifndef QEMU_EXEC_LOG_H +#define QEMU_EXEC_LOG_H + +#include "qemu/log.h" +#include "qom/cpu.h" +#include "disas/disas.h" + +/* cpu_dump_state() logging functions: */ +/** + * log_cpu_state: + * @cpu: The CPU whose state is to be logged. + * @flags: Flags what to log. + * + * Logs the output of cpu_dump_state(). + */ +static inline void log_cpu_state(CPUState *cpu, int flags) +{ + if (qemu_log_enabled()) { + cpu_dump_state(cpu, qemu_logfile, fprintf, flags); + } +} + +/** + * log_cpu_state_mask: + * @mask: Mask when to log. + * @cpu: The CPU whose state is to be logged. + * @flags: Flags what to log. + * + * Logs the output of cpu_dump_state() if loglevel includes @mask. + */ +static inline void log_cpu_state_mask(int mask, CPUState *cpu, int flags) +{ + if (qemu_loglevel & mask) { + log_cpu_state(cpu, flags); + } +} + +#ifdef NEED_CPU_H +/* disas() and target_disas() to qemu_logfile: */ +static inline void log_target_disas(CPUState *cpu, target_ulong start, + target_ulong len, int flags) +{ + target_disas(qemu_logfile, cpu, start, len, flags); +} + +static inline void log_disas(void *code, unsigned long size) +{ + disas(qemu_logfile, code, size); +} + +#if defined(CONFIG_USER_ONLY) +/* page_dump() output to the log file: */ +static inline void log_page_dump(void) +{ + page_dump(qemu_logfile); +} +#endif +#endif + +#endif diff --git a/include/qemu/log.h b/include/qemu/log.h index d837d90..09722e3 100644 --- a/include/qemu/log.h +++ b/include/qemu/log.h @@ -5,10 +5,6 @@ #include #include #include "qemu/compiler.h" -#include "qom/cpu.h" -#ifdef NEED_CPU_H -#include "disas/disas.h" -#endif /* Private global variables, don't use */ extern FILE *qemu_logfile; @@ -78,61 +74,6 @@ qemu_log_vprintf(const char *fmt, va_list va) void GCC_FMT_ATTR(2, 3) qemu_log_mask(int mask, const char *fmt, ...); -/* Special cases: */ - -/* cpu_dump_state() logging functions: */ -/** - * log_cpu_state: - * @cpu: The CPU whose state is to be logged. - * @flags: Flags what to log. - * - * Logs the output of cpu_dump_state(). - */ -static inline void log_cpu_state(CPUState *cpu, int flags) -{ - if (qemu_log_enabled()) { - cpu_dump_state(cpu, qemu_logfile, fprintf, flags); - } -} - -/** - * log_cpu_state_mask: - * @mask: Mask when to log. - * @cpu: The CPU whose state is to be logged. - * @flags: Flags what to log. - * - * Logs the output of cpu_dump_state() if loglevel includes @mask. - */ -static inline void log_cpu_state_mask(int mask, CPUState *cpu, int flags) -{ - if (qemu_loglevel & mask) { - log_cpu_state(cpu, flags); - } -} - -#ifdef NEED_CPU_H -/* disas() and target_disas() to qemu_logfile: */ -static inline void log_target_disas(CPUState *cpu, target_ulong start, - target_ulong len, int flags) -{ - target_disas(qemu_logfile, cpu, start, len, flags); -} - -static inline void log_disas(void *code, unsigned long size) -{ - disas(qemu_logfile, code, size); -} - -#if defined(CONFIG_USER_ONLY) -/* page_dump() output to the log file: */ -static inline void log_page_dump(void) -{ - page_dump(qemu_logfile); -} -#endif -#endif - - /* Maintenance: */ /* fflush() the log file */ diff --git a/linux-user/main.c b/linux-user/main.c index f8d4577..e719a2d 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -28,6 +28,7 @@ #include "qemu/timer.h" #include "qemu/envlist.h" #include "elf.h" +#include "exec/log.h" char *exec_path; diff --git a/qom/cpu.c b/qom/cpu.c index 8f537a4..38dc713 100644 --- a/qom/cpu.c +++ b/qom/cpu.c @@ -23,6 +23,7 @@ #include "sysemu/kvm.h" #include "qemu/notify.h" #include "qemu/log.h" +#include "exec/log.h" #include "qemu/error-report.h" #include "sysemu/sysemu.h" diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 7d419d9..c96adbb 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -28,6 +28,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" #undef ALPHA_DEBUG_DISAS diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c index 80f6c20..2af7d86 100644 --- a/target-arm/translate-a64.c +++ b/target-arm/translate-a64.c @@ -31,6 +31,7 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" +#include "exec/log.h" #include "trace-tcg.h" diff --git a/target-arm/translate.c b/target-arm/translate.c index cff511b..3ec758a 100644 --- a/target-arm/translate.c +++ b/target-arm/translate.c @@ -32,6 +32,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T) diff --git a/target-cris/translate.c b/target-cris/translate.c index 295005f..0350cb5 100644 --- a/target-cris/translate.c +++ b/target-cris/translate.c @@ -35,6 +35,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" #define DISAS_CRIS 0 diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c index 4c7cab7..4f26941 100644 --- a/target-i386/seg_helper.c +++ b/target-i386/seg_helper.c @@ -23,6 +23,7 @@ #include "qemu/log.h" #include "exec/helper-proto.h" #include "exec/cpu_ldst.h" +#include "exec/log.h" //#define DEBUG_PCALL diff --git a/target-i386/smm_helper.c b/target-i386/smm_helper.c index b930421..e7bb5be 100644 --- a/target-i386/smm_helper.c +++ b/target-i386/smm_helper.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" +#include "exec/log.h" /* SMM support */ diff --git a/target-i386/translate.c b/target-i386/translate.c index 957a92d..73a45c8 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -28,6 +28,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" #define PREFIX_REPZ 0x01 diff --git a/target-lm32/helper.c b/target-lm32/helper.c index 3ebec68..655248f 100644 --- a/target-lm32/helper.c +++ b/target-lm32/helper.c @@ -22,6 +22,7 @@ #include "qemu/host-utils.h" #include "sysemu/sysemu.h" #include "exec/semihost.h" +#include "exec/log.h" int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw, int mmu_idx) diff --git a/target-lm32/translate.c b/target-lm32/translate.c index 477d428..52fe562 100644 --- a/target-lm32/translate.c +++ b/target-lm32/translate.c @@ -29,6 +29,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" #define DISAS_LM32 1 diff --git a/target-m68k/translate.c b/target-m68k/translate.c index 342c040..a402bd8 100644 --- a/target-m68k/translate.c +++ b/target-m68k/translate.c @@ -29,6 +29,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" //#define DEBUG_DISPATCH 1 diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c index 3b0fae8..4de6bdb 100644 --- a/target-microblaze/helper.c +++ b/target-microblaze/helper.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "qemu/host-utils.h" +#include "exec/log.h" #define D(x) diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c index 2e1293d..40be4ec 100644 --- a/target-microblaze/translate.c +++ b/target-microblaze/translate.c @@ -28,6 +28,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" #define SIM_COMPAT 0 diff --git a/target-mips/helper.c b/target-mips/helper.c index f9c4c11..1004ede 100644 --- a/target-mips/helper.c +++ b/target-mips/helper.c @@ -21,6 +21,7 @@ #include "cpu.h" #include "sysemu/kvm.h" #include "exec/cpu_ldst.h" +#include "exec/log.h" enum { TLBRET_XI = -6, diff --git a/target-mips/translate.c b/target-mips/translate.c index 383d4b5..791866b 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -33,6 +33,7 @@ #include "exec/semihost.h" #include "trace-tcg.h" +#include "exec/log.h" #define MIPS_DEBUG_DISAS 0 diff --git a/target-moxie/translate.c b/target-moxie/translate.c index 229ce3b..04ab278 100644 --- a/target-moxie/translate.c +++ b/target-moxie/translate.c @@ -31,6 +31,7 @@ #include "exec/helper-proto.h" #include "exec/helper-gen.h" +#include "exec/log.h" /* This is the state at translation time. */ typedef struct DisasContext { diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c index 62890c2..b766b27 100644 --- a/target-openrisc/translate.c +++ b/target-openrisc/translate.c @@ -32,6 +32,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" #define OPENRISC_DISAS diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c index b076d80..39abb2f 100644 --- a/target-ppc/mmu-hash32.c +++ b/target-ppc/mmu-hash32.c @@ -24,6 +24,7 @@ #include "sysemu/kvm.h" #include "kvm_ppc.h" #include "mmu-hash32.h" +#include "exec/log.h" //#define DEBUG_BAT diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c index 6d110ee..9c58fbf 100644 --- a/target-ppc/mmu-hash64.c +++ b/target-ppc/mmu-hash64.c @@ -25,6 +25,7 @@ #include "qemu/error-report.h" #include "kvm_ppc.h" #include "mmu-hash64.h" +#include "exec/log.h" //#define DEBUG_SLB diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c index de4e286..e5ec8d6 100644 --- a/target-ppc/mmu_helper.c +++ b/target-ppc/mmu_helper.c @@ -24,6 +24,7 @@ #include "mmu-hash64.h" #include "mmu-hash32.h" #include "exec/cpu_ldst.h" +#include "exec/log.h" //#define DEBUG_MMU //#define DEBUG_BATS diff --git a/target-ppc/translate.c b/target-ppc/translate.c index 7db3145..0057bda 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -29,6 +29,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" #define CPU_SINGLE_STEP 0x1 diff --git a/target-s390x/translate.c b/target-s390x/translate.c index 811928b..3087692 100644 --- a/target-s390x/translate.c +++ b/target-s390x/translate.c @@ -44,6 +44,7 @@ static TCGv_ptr cpu_env; #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" /* Information that (most) every instruction needs to manipulate. */ diff --git a/target-sh4/helper.c b/target-sh4/helper.c index 9d8b61c..6438338 100644 --- a/target-sh4/helper.c +++ b/target-sh4/helper.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "cpu.h" +#include "exec/log.h" #if !defined(CONFIG_USER_ONLY) #include "hw/sh4/sh_intc.h" diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 9de5659..3e4164b 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -29,6 +29,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" typedef struct DisasContext { diff --git a/target-sparc/int32_helper.c b/target-sparc/int32_helper.c index d4d6a4b..09afe13 100644 --- a/target-sparc/int32_helper.c +++ b/target-sparc/int32_helper.c @@ -21,6 +21,7 @@ #include "cpu.h" #include "trace.h" #include "sysemu/sysemu.h" +#include "exec/log.h" #define DEBUG_PCALL diff --git a/target-sparc/int64_helper.c b/target-sparc/int64_helper.c index ddef66b..aa876cd 100644 --- a/target-sparc/int64_helper.c +++ b/target-sparc/int64_helper.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/helper-proto.h" +#include "exec/log.h" #include "trace.h" #define DEBUG_PCALL diff --git a/target-sparc/translate.c b/target-sparc/translate.c index 747f94d..6726860 100644 --- a/target-sparc/translate.c +++ b/target-sparc/translate.c @@ -29,6 +29,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" #define DEBUG_DISAS diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c index 2088f87..a5bb8d4 100644 --- a/target-tilegx/translate.c +++ b/target-tilegx/translate.c @@ -21,6 +21,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "qemu/log.h" +#include "exec/log.h" #include "disas/disas.h" #include "tcg-op.h" #include "exec/cpu_ldst.h" diff --git a/target-tricore/translate.c b/target-tricore/translate.c index 2b07b86..e385fc7 100644 --- a/target-tricore/translate.c +++ b/target-tricore/translate.c @@ -28,6 +28,7 @@ #include "exec/helper-gen.h" #include "tricore-opcodes.h" +#include "exec/log.h" /* * TCG registers diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c index 5db8f94..7dbfe3b 100644 --- a/target-unicore32/translate.c +++ b/target-unicore32/translate.c @@ -20,6 +20,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" /* internal defines */ diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c index a8c1113..435ee03 100644 --- a/target-xtensa/translate.c +++ b/target-xtensa/translate.c @@ -43,6 +43,7 @@ #include "exec/helper-gen.h" #include "trace-tcg.h" +#include "exec/log.h" typedef struct DisasContext { diff --git a/tcg/tcg.c b/tcg/tcg.c index 3ce02dc..be765ad 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -60,6 +60,7 @@ #endif #include "elf.h" +#include "exec/log.h" /* Forward declarations for functions declared in tcg-target.c and used here. */ static void tcg_target_init(TCGContext *s); diff --git a/translate-all.c b/translate-all.c index ab61fac..e9f409b 100644 --- a/translate-all.c +++ b/translate-all.c @@ -55,6 +55,7 @@ #include "translate-all.h" #include "qemu/bitmap.h" #include "qemu/timer.h" +#include "exec/log.h" //#define DEBUG_TB_INVALIDATE //#define DEBUG_FLUSH -- cgit v1.1 From d890d50d1821a18366a0b9f72e6c93689a47bcd4 Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Thu, 7 Jan 2016 16:55:29 +0300 Subject: log: move qemu-log.c into util/ directory log will become common facility with tracepoints support in next step. Signed-off-by: Denis V. Lunev Reviewed-by: Paolo Bonzini Signed-off-by: Paolo Bonzini Message-id: 1452174932-28657-9-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- Makefile.objs | 1 - qemu-log.c | 179 ----------------------------------------------------- util/Makefile.objs | 1 + util/log.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 180 insertions(+), 180 deletions(-) delete mode 100644 qemu-log.c create mode 100644 util/log.c diff --git a/Makefile.objs b/Makefile.objs index 06b95c7..fbcaa74 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -89,7 +89,6 @@ endif ####################################################################### # Target-independent parts used in system and user emulation -common-obj-y += qemu-log.o common-obj-y += tcg-runtime.o common-obj-y += hw/ common-obj-y += qom/ diff --git a/qemu-log.c b/qemu-log.c deleted file mode 100644 index 901b930..0000000 --- a/qemu-log.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Logging support - * - * Copyright (c) 2003 Fabrice Bellard - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, see . - */ - -#include "qemu-common.h" -#include "qemu/log.h" - -static char *logfilename; -FILE *qemu_logfile; -int qemu_loglevel; -static int log_append = 0; - -void qemu_log(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - if (qemu_logfile) { - vfprintf(qemu_logfile, fmt, ap); - } - va_end(ap); -} - -void qemu_log_mask(int mask, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - if ((qemu_loglevel & mask) && qemu_logfile) { - vfprintf(qemu_logfile, fmt, ap); - } - va_end(ap); -} - -/* enable or disable low levels log */ -void do_qemu_set_log(int log_flags, bool use_own_buffers) -{ - qemu_loglevel = log_flags; - if (qemu_loglevel && !qemu_logfile) { - if (logfilename) { - qemu_logfile = fopen(logfilename, log_append ? "a" : "w"); - if (!qemu_logfile) { - perror(logfilename); - _exit(1); - } - } else { - /* Default to stderr if no log file specified */ - qemu_logfile = stderr; - } - /* must avoid mmap() usage of glibc by setting a buffer "by hand" */ - if (use_own_buffers) { - static char logfile_buf[4096]; - - setvbuf(qemu_logfile, logfile_buf, _IOLBF, sizeof(logfile_buf)); - } else { -#if defined(_WIN32) - /* Win32 doesn't support line-buffering, so use unbuffered output. */ - setvbuf(qemu_logfile, NULL, _IONBF, 0); -#else - setvbuf(qemu_logfile, NULL, _IOLBF, 0); -#endif - log_append = 1; - } - } - if (!qemu_loglevel && qemu_logfile) { - qemu_log_close(); - } -} - -void qemu_set_log_filename(const char *filename) -{ - g_free(logfilename); - logfilename = g_strdup(filename); - qemu_log_close(); - qemu_set_log(qemu_loglevel); -} - -const QEMULogItem qemu_log_items[] = { - { CPU_LOG_TB_OUT_ASM, "out_asm", - "show generated host assembly code for each compiled TB" }, - { CPU_LOG_TB_IN_ASM, "in_asm", - "show target assembly code for each compiled TB" }, - { CPU_LOG_TB_OP, "op", - "show micro ops for each compiled TB" }, - { CPU_LOG_TB_OP_OPT, "op_opt", - "show micro ops (x86 only: before eflags optimization) and\n" - "after liveness analysis" }, - { CPU_LOG_INT, "int", - "show interrupts/exceptions in short format" }, - { CPU_LOG_EXEC, "exec", - "show trace before each executed TB (lots of logs)" }, - { CPU_LOG_TB_CPU, "cpu", - "show CPU state before block translation" }, - { CPU_LOG_MMU, "mmu", - "log MMU-related activities" }, - { CPU_LOG_PCALL, "pcall", - "x86 only: show protected mode far calls/returns/exceptions" }, - { CPU_LOG_RESET, "cpu_reset", - "show CPU state before CPU resets" }, - { LOG_UNIMP, "unimp", - "log unimplemented functionality" }, - { LOG_GUEST_ERROR, "guest_errors", - "log when the guest OS does something invalid (eg accessing a\n" - "non-existent register)" }, - { CPU_LOG_PAGE, "page", - "dump pages at beginning of user mode emulation" }, - { CPU_LOG_TB_NOCHAIN, "nochain", - "do not chain compiled TBs so that \"exec\" and \"cpu\" show\n" - "complete traces" }, - { 0, NULL, NULL }, -}; - -static int cmp1(const char *s1, int n, const char *s2) -{ - if (strlen(s2) != n) { - return 0; - } - return memcmp(s1, s2, n) == 0; -} - -/* takes a comma separated list of log masks. Return 0 if error. */ -int qemu_str_to_log_mask(const char *str) -{ - const QEMULogItem *item; - int mask; - const char *p, *p1; - - p = str; - mask = 0; - for (;;) { - p1 = strchr(p, ','); - if (!p1) { - p1 = p + strlen(p); - } - if (cmp1(p,p1-p,"all")) { - for (item = qemu_log_items; item->mask != 0; item++) { - mask |= item->mask; - } - } else { - for (item = qemu_log_items; item->mask != 0; item++) { - if (cmp1(p, p1 - p, item->name)) { - goto found; - } - } - return 0; - } - found: - mask |= item->mask; - if (*p1 != ',') { - break; - } - p = p1 + 1; - } - return mask; -} - -void qemu_print_log_usage(FILE *f) -{ - const QEMULogItem *item; - fprintf(f, "Log items (comma separated):\n"); - for (item = qemu_log_items; item->mask != 0; item++) { - fprintf(f, "%-10s %s\n", item->name, item->help); - } -} diff --git a/util/Makefile.objs b/util/Makefile.objs index 8620a80..a8a777e 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -31,3 +31,4 @@ util-obj-y += coroutine-$(CONFIG_COROUTINE_BACKEND).o util-obj-y += buffer.o util-obj-y += timed-average.o util-obj-y += base64.o +util-obj-y += log.o diff --git a/util/log.c b/util/log.c new file mode 100644 index 0000000..901b930 --- /dev/null +++ b/util/log.c @@ -0,0 +1,179 @@ +/* + * Logging support + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu-common.h" +#include "qemu/log.h" + +static char *logfilename; +FILE *qemu_logfile; +int qemu_loglevel; +static int log_append = 0; + +void qemu_log(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if (qemu_logfile) { + vfprintf(qemu_logfile, fmt, ap); + } + va_end(ap); +} + +void qemu_log_mask(int mask, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + if ((qemu_loglevel & mask) && qemu_logfile) { + vfprintf(qemu_logfile, fmt, ap); + } + va_end(ap); +} + +/* enable or disable low levels log */ +void do_qemu_set_log(int log_flags, bool use_own_buffers) +{ + qemu_loglevel = log_flags; + if (qemu_loglevel && !qemu_logfile) { + if (logfilename) { + qemu_logfile = fopen(logfilename, log_append ? "a" : "w"); + if (!qemu_logfile) { + perror(logfilename); + _exit(1); + } + } else { + /* Default to stderr if no log file specified */ + qemu_logfile = stderr; + } + /* must avoid mmap() usage of glibc by setting a buffer "by hand" */ + if (use_own_buffers) { + static char logfile_buf[4096]; + + setvbuf(qemu_logfile, logfile_buf, _IOLBF, sizeof(logfile_buf)); + } else { +#if defined(_WIN32) + /* Win32 doesn't support line-buffering, so use unbuffered output. */ + setvbuf(qemu_logfile, NULL, _IONBF, 0); +#else + setvbuf(qemu_logfile, NULL, _IOLBF, 0); +#endif + log_append = 1; + } + } + if (!qemu_loglevel && qemu_logfile) { + qemu_log_close(); + } +} + +void qemu_set_log_filename(const char *filename) +{ + g_free(logfilename); + logfilename = g_strdup(filename); + qemu_log_close(); + qemu_set_log(qemu_loglevel); +} + +const QEMULogItem qemu_log_items[] = { + { CPU_LOG_TB_OUT_ASM, "out_asm", + "show generated host assembly code for each compiled TB" }, + { CPU_LOG_TB_IN_ASM, "in_asm", + "show target assembly code for each compiled TB" }, + { CPU_LOG_TB_OP, "op", + "show micro ops for each compiled TB" }, + { CPU_LOG_TB_OP_OPT, "op_opt", + "show micro ops (x86 only: before eflags optimization) and\n" + "after liveness analysis" }, + { CPU_LOG_INT, "int", + "show interrupts/exceptions in short format" }, + { CPU_LOG_EXEC, "exec", + "show trace before each executed TB (lots of logs)" }, + { CPU_LOG_TB_CPU, "cpu", + "show CPU state before block translation" }, + { CPU_LOG_MMU, "mmu", + "log MMU-related activities" }, + { CPU_LOG_PCALL, "pcall", + "x86 only: show protected mode far calls/returns/exceptions" }, + { CPU_LOG_RESET, "cpu_reset", + "show CPU state before CPU resets" }, + { LOG_UNIMP, "unimp", + "log unimplemented functionality" }, + { LOG_GUEST_ERROR, "guest_errors", + "log when the guest OS does something invalid (eg accessing a\n" + "non-existent register)" }, + { CPU_LOG_PAGE, "page", + "dump pages at beginning of user mode emulation" }, + { CPU_LOG_TB_NOCHAIN, "nochain", + "do not chain compiled TBs so that \"exec\" and \"cpu\" show\n" + "complete traces" }, + { 0, NULL, NULL }, +}; + +static int cmp1(const char *s1, int n, const char *s2) +{ + if (strlen(s2) != n) { + return 0; + } + return memcmp(s1, s2, n) == 0; +} + +/* takes a comma separated list of log masks. Return 0 if error. */ +int qemu_str_to_log_mask(const char *str) +{ + const QEMULogItem *item; + int mask; + const char *p, *p1; + + p = str; + mask = 0; + for (;;) { + p1 = strchr(p, ','); + if (!p1) { + p1 = p + strlen(p); + } + if (cmp1(p,p1-p,"all")) { + for (item = qemu_log_items; item->mask != 0; item++) { + mask |= item->mask; + } + } else { + for (item = qemu_log_items; item->mask != 0; item++) { + if (cmp1(p, p1 - p, item->name)) { + goto found; + } + } + return 0; + } + found: + mask |= item->mask; + if (*p1 != ',') { + break; + } + p = p1 + 1; + } + return mask; +} + +void qemu_print_log_usage(FILE *f) +{ + const QEMULogItem *item; + fprintf(f, "Log items (comma separated):\n"); + for (item = qemu_log_items; item->mask != 0; item++) { + fprintf(f, "%-10s %s\n", item->name, item->help); + } +} -- cgit v1.1 From ed7f5f1d8db06fc31352a5ef4f54985e630c575a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 7 Jan 2016 16:55:30 +0300 Subject: trace: convert stderr backend to log [Also update .travis.yml --enable-trace-backends=stderr --Stefan] Signed-off-by: Paolo Bonzini Signed-off-by: Denis V. Lunev Acked-by: Christian Borntraeger Message-id: 1452174932-28657-10-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- .travis.yml | 2 +- configure | 4 ++-- include/qemu/log.h | 1 + scripts/tracetool/backend/log.py | 48 +++++++++++++++++++++++++++++++++++++ scripts/tracetool/backend/stderr.py | 47 ------------------------------------ trace/control.c | 10 ++++++++ util/log.c | 3 +++ vl.c | 2 ++ 8 files changed, 67 insertions(+), 50 deletions(-) create mode 100644 scripts/tracetool/backend/log.py delete mode 100644 scripts/tracetool/backend/stderr.py diff --git a/.travis.yml b/.travis.yml index 6ca0260..0428aed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -78,7 +78,7 @@ matrix: compiler: gcc # All the trace backends (apart from dtrace) - env: TARGETS=i386-softmmu,x86_64-softmmu - EXTRA_CONFIG="--enable-trace-backends=stderr" + EXTRA_CONFIG="--enable-trace-backends=log" compiler: gcc - env: TARGETS=i386-softmmu,x86_64-softmmu EXTRA_CONFIG="--enable-trace-backends=simple" diff --git a/configure b/configure index 297bfc7..92c2616 100755 --- a/configure +++ b/configure @@ -5445,8 +5445,8 @@ if have_backend "simple"; then # Set the appropriate trace file. trace_file="\"$trace_file-\" FMT_pid" fi -if have_backend "stderr"; then - echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak +if have_backend "log"; then + echo "CONFIG_TRACE_LOG=y" >> $config_host_mak fi if have_backend "ust"; then echo "CONFIG_TRACE_UST=y" >> $config_host_mak diff --git a/include/qemu/log.h b/include/qemu/log.h index 09722e3..30817f7 100644 --- a/include/qemu/log.h +++ b/include/qemu/log.h @@ -45,6 +45,7 @@ static inline bool qemu_log_separate(void) #define CPU_LOG_MMU (1 << 12) #define CPU_LOG_TB_NOCHAIN (1 << 13) #define CPU_LOG_PAGE (1 << 14) +#define LOG_TRACE (1 << 15) /* Returns true if a bit is set in the current loglevel mask */ diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py new file mode 100644 index 0000000..a62c310 --- /dev/null +++ b/scripts/tracetool/backend/log.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Stderr built-in backend. +""" + +__author__ = "Lluís Vilanova " +__copyright__ = "Copyright 2012-2014, Lluís Vilanova " +__license__ = "GPL version 2 or (at your option) any later version" + +__maintainer__ = "Stefan Hajnoczi" +__email__ = "stefanha@linux.vnet.ibm.com" + + +from tracetool import out + + +PUBLIC = True + + +def generate_h_begin(events): + out('#include ', + '#include ', + '#include ', + '#include ', + '#include "trace/control.h"', + '#include "qemu/log.h"', + '') + + +def generate_h(event): + argnames = ", ".join(event.args.names()) + if len(event.args) > 0: + argnames = ", " + argnames + + out(' if (trace_event_get_state(%(event_id)s)) {', + ' struct timeval _now;', + ' gettimeofday(&_now, NULL);', + ' qemu_log_mask(LOG_TRACE, "%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",', + ' getpid(),', + ' (size_t)_now.tv_sec, (size_t)_now.tv_usec', + ' %(argnames)s);', + ' }', + event_id="TRACE_" + event.name.upper(), + name=event.name, + fmt=event.fmt.rstrip("\n"), + argnames=argnames) diff --git a/scripts/tracetool/backend/stderr.py b/scripts/tracetool/backend/stderr.py deleted file mode 100644 index ca58054..0000000 --- a/scripts/tracetool/backend/stderr.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -""" -Stderr built-in backend. -""" - -__author__ = "Lluís Vilanova " -__copyright__ = "Copyright 2012-2014, Lluís Vilanova " -__license__ = "GPL version 2 or (at your option) any later version" - -__maintainer__ = "Stefan Hajnoczi" -__email__ = "stefanha@linux.vnet.ibm.com" - - -from tracetool import out - - -PUBLIC = True - - -def generate_h_begin(events): - out('#include ', - '#include ', - '#include ', - '#include ', - '#include "trace/control.h"', - '') - - -def generate_h(event): - argnames = ", ".join(event.args.names()) - if len(event.args) > 0: - argnames = ", " + argnames - - out(' if (trace_event_get_state(%(event_id)s)) {', - ' struct timeval _now;', - ' gettimeofday(&_now, NULL);', - ' fprintf(stderr, "%%d@%%zd.%%06zd:%(name)s " %(fmt)s "\\n",', - ' getpid(),', - ' (size_t)_now.tv_sec, (size_t)_now.tv_usec', - ' %(argnames)s);', - ' }', - event_id="TRACE_" + event.name.upper(), - name=event.name, - fmt=event.fmt.rstrip("\n"), - argnames=argnames) diff --git a/trace/control.c b/trace/control.c index bef7884..84ea840 100644 --- a/trace/control.c +++ b/trace/control.c @@ -14,6 +14,9 @@ #ifdef CONFIG_TRACE_FTRACE #include "trace/ftrace.h" #endif +#ifdef CONFIG_TRACE_LOG +#include "qemu/log.h" +#endif #include "qemu/error-report.h" int trace_events_enabled_count; @@ -174,6 +177,13 @@ void trace_init_file(const char *file) { #ifdef CONFIG_TRACE_SIMPLE st_set_trace_file(file); +#elif defined CONFIG_TRACE_LOG + /* If both the simple and the log backends are enabled, "-trace file" + * only applies to the simple backend; use "-D" for the log backend. + */ + if (file) { + qemu_set_log_filename(file); + } #else if (file) { fprintf(stderr, "error: -trace file=...: " diff --git a/util/log.c b/util/log.c index 901b930..37185a5 100644 --- a/util/log.c +++ b/util/log.c @@ -51,6 +51,9 @@ void qemu_log_mask(int mask, const char *fmt, ...) void do_qemu_set_log(int log_flags, bool use_own_buffers) { qemu_loglevel = log_flags; +#ifdef CONFIG_TRACE_LOG + qemu_loglevel |= LOG_TRACE; +#endif if (qemu_loglevel && !qemu_logfile) { if (logfilename) { qemu_logfile = fopen(logfilename, log_append ? "a" : "w"); diff --git a/vl.c b/vl.c index 58cc050..a7d7c39 100644 --- a/vl.c +++ b/vl.c @@ -4115,6 +4115,8 @@ int main(int argc, char **argv, char **envp) exit(1); } qemu_set_log(mask); + } else { + qemu_set_log(0); } if (!trace_init_backends()) { -- cgit v1.1 From baf86d6b3ca0191372f8b60299ef500b5484fd8f Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 7 Jan 2016 16:55:31 +0300 Subject: trace: switch default backend to "log" This enables integration with other QEMU logging facilities. Signed-off-by: Paolo Bonzini Signed-off-by: Denis V. Lunev Acked-by: Christian Borntraeger Message-id: 1452174932-28657-11-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 92c2616..d4411a1 100755 --- a/configure +++ b/configure @@ -303,7 +303,7 @@ pkgversion="" pie="" zero_malloc="" qom_cast_debug="yes" -trace_backends="nop" +trace_backends="log" trace_file="trace" spice="" rbd="" -- cgit v1.1 From c84ea00dc29b2084a62bd31f498ed0f245d3848e Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Thu, 7 Jan 2016 16:55:32 +0300 Subject: log: add "-d trace:PATTERN" This is a bit easier to use than "-trace" if you are also enabling other kinds of logging. It is also more discoverable for experienced QEMU users, and accessible from user-mode emulators. Signed-off-by: Paolo Bonzini Signed-off-by: Denis V. Lunev Acked-by: Christian Borntraeger Message-id: 1452174932-28657-12-git-send-email-den@openvz.org Signed-off-by: Stefan Hajnoczi --- util/log.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/util/log.c b/util/log.c index 37185a5..46c88c9 100644 --- a/util/log.c +++ b/util/log.c @@ -19,6 +19,7 @@ #include "qemu-common.h" #include "qemu/log.h" +#include "trace/control.h" static char *logfilename; FILE *qemu_logfile; @@ -154,6 +155,11 @@ int qemu_str_to_log_mask(const char *str) for (item = qemu_log_items; item->mask != 0; item++) { mask |= item->mask; } +#ifdef CONFIG_TRACE_LOG + } else if (strncmp(p, "trace:", 6) == 0 && p + 6 != p1) { + trace_enable_events(p + 6); + mask |= LOG_TRACE; +#endif } else { for (item = qemu_log_items; item->mask != 0; item++) { if (cmp1(p, p1 - p, item->name)) { @@ -161,9 +167,9 @@ int qemu_str_to_log_mask(const char *str) } } return 0; + found: + mask |= item->mask; } - found: - mask |= item->mask; if (*p1 != ',') { break; } @@ -177,6 +183,10 @@ void qemu_print_log_usage(FILE *f) const QEMULogItem *item; fprintf(f, "Log items (comma separated):\n"); for (item = qemu_log_items; item->mask != 0; item++) { - fprintf(f, "%-10s %s\n", item->name, item->help); + fprintf(f, "%-15s %s\n", item->name, item->help); } +#ifdef CONFIG_TRACE_LOG + fprintf(f, "trace:PATTERN enable trace events\n"); + fprintf(f, "\nUse \"-d trace:help\" to get a list of trace events.\n\n"); +#endif } -- cgit v1.1