diff options
Diffstat (limited to 'qemu/trace')
-rw-r--r-- | qemu/trace/Makefile.objs | 48 | ||||
-rw-r--r-- | qemu/trace/control-internal.h | 16 | ||||
-rw-r--r-- | qemu/trace/control.c | 103 | ||||
-rw-r--r-- | qemu/trace/control.h | 46 | ||||
-rw-r--r-- | qemu/trace/event-internal.h | 2 | ||||
-rw-r--r-- | qemu/trace/ftrace.c | 5 | ||||
-rw-r--r-- | qemu/trace/ftrace.h | 1 | ||||
-rw-r--r-- | qemu/trace/qmp.c | 2 | ||||
-rw-r--r-- | qemu/trace/simple.c | 15 | ||||
-rw-r--r-- | qemu/trace/simple.h | 7 |
10 files changed, 166 insertions, 79 deletions
diff --git a/qemu/trace/Makefile.objs b/qemu/trace/Makefile.objs index 32f7a32ce..5145b34d1 100644 --- a/qemu/trace/Makefile.objs +++ b/qemu/trace/Makefile.objs @@ -1,24 +1,32 @@ # -*- mode: makefile -*- ###################################################################### +# tracetool source files +# Every rule that invokes tracetool must depend on this so code is regenerated +# if tracetool itself changes. + +tracetool-y = $(SRC_PATH)/scripts/tracetool.py +tracetool-y += $(shell find $(SRC_PATH)/scripts/tracetool -name "*.py") + +###################################################################### # Auto-generated event descriptions for LTTng ust code ifeq ($(findstring ust,$(TRACE_BACKENDS)),ust) $(obj)/generated-ust-provider.h: $(obj)/generated-ust-provider.h-timestamp -$(obj)/generated-ust-provider.h-timestamp: $(SRC_PATH)/trace-events + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-ust-provider.h-timestamp: $(SRC_PATH)/trace-events $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=ust-events-h \ --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) $(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-host.mak -$(obj)/generated-ust.c-timestamp: $(SRC_PATH)/trace-events + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-ust.c-timestamp: $(SRC_PATH)/trace-events $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=ust-events-c \ --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) $(obj)/generated-events.h: $(obj)/generated-ust-provider.h $(obj)/generated-events.c: $(obj)/generated-ust.c @@ -28,20 +36,20 @@ endif # Auto-generated event descriptions $(obj)/generated-events.h: $(obj)/generated-events.h-timestamp -$(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=events-h \ --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) $(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/config-host.mak -$(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=events-c \ --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) util-obj-y += generated-events.o @@ -54,7 +62,7 @@ util-obj-y += generated-events.o $(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp @cmp -s $< $@ || cp $< $@ -$(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak +$(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=h \ --backends=$(TRACE_BACKENDS) \ @@ -65,7 +73,7 @@ $(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/conf $(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp @cmp -s $< $@ || cp $< $@ -$(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak +$(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=c \ --backends=$(TRACE_BACKENDS) \ @@ -81,12 +89,12 @@ $(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers. # rule file. So we use '.dtrace' instead ifeq ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace) $(obj)/generated-tracers-dtrace.dtrace: $(obj)/generated-tracers-dtrace.dtrace-timestamp -$(obj)/generated-tracers-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-tracers-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=d \ --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) $(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers-dtrace.dtrace $(call quiet-command,dtrace -o $@ -h -s $<, " GEN $@") @@ -100,28 +108,28 @@ endif # Translation level $(obj)/generated-helpers-wrappers.h: $(obj)/generated-helpers-wrappers.h-timestamp -$(obj)/generated-helpers-wrappers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-helpers-wrappers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=tcg-helper-wrapper-h \ --backend=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) $(obj)/generated-helpers.h: $(obj)/generated-helpers.h-timestamp -$(obj)/generated-helpers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-helpers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=tcg-helper-h \ --backend=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) $(obj)/generated-helpers.c: $(obj)/generated-helpers.c-timestamp -$(obj)/generated-helpers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-helpers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=tcg-helper-c \ --backend=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) $(obj)/generated-helpers.o: $(obj)/generated-helpers.c @@ -129,12 +137,12 @@ target-obj-y += generated-helpers.o $(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp -$(obj)/generated-tcg-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-tcg-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y) $(call quiet-command,$(TRACETOOL) \ --format=tcg-h \ --backend=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) ###################################################################### diff --git a/qemu/trace/control-internal.h b/qemu/trace/control-internal.h index 5a8df28c5..dcf67f505 100644 --- a/qemu/trace/control-internal.h +++ b/qemu/trace/control-internal.h @@ -10,10 +10,11 @@ #ifndef TRACE__CONTROL_INTERNAL_H #define TRACE__CONTROL_INTERNAL_H -#include <string.h> extern TraceEvent trace_events[]; +extern bool trace_events_dstate[]; +extern int trace_events_enabled_count; static inline TraceEventID trace_event_count(void) @@ -51,17 +52,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 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)); - 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/qemu/trace/control.c b/qemu/trace/control.c index 995beb384..d099f735d 100644 --- a/qemu/trace/control.c +++ b/qemu/trace/control.c @@ -7,14 +7,23 @@ * See the COPYING file in the top-level directory. */ +#include "qemu/osdep.h" #include "trace/control.h" +#include "qemu/help_option.h" #ifdef CONFIG_TRACE_SIMPLE #include "trace/simple.h" #endif #ifdef CONFIG_TRACE_FTRACE #include "trace/ftrace.h" #endif +#ifdef CONFIG_TRACE_LOG +#include "qemu/log.h" +#endif #include "qemu/error-report.h" +#include "monitor/monitor.h" + +int trace_events_enabled_count; +bool trace_events_dstate[TRACE_EVENT_COUNT]; TraceEvent *trace_event_name(const char *name) { @@ -85,7 +94,54 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev) return NULL; } -static void trace_init_events(const char *fname) +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; + + 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_enable_events(const char *line_buf) +{ + if (is_help_option(line_buf)) { + trace_list_events(); + if (cur_mon == NULL) { + exit(0); + } + } else { + do_trace_enable_events(line_buf); + } +} + +void trace_init_events(const char *fname) { Location loc; FILE *fp; @@ -111,27 +167,7 @@ static 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) { @@ -142,17 +178,31 @@ static void trace_init_events(const char *fname) loc_pop(&loc); } -bool trace_init_backends(const char *events, 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); +#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=...: " "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 @@ -164,6 +214,5 @@ bool trace_init_backends(const char *events, const char *file) } #endif - trace_init_events(events); return true; } diff --git a/qemu/trace/control.h b/qemu/trace/control.h index da9bb6b77..e2ba6d4de 100644 --- a/qemu/trace/control.h +++ b/qemu/trace/control.h @@ -1,7 +1,7 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2014 Lluís Vilanova <vilanova@ac.upc.edu> + * Copyright (C) 2011-2016 Lluís Vilanova <vilanova@ac.upc.edu> * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. @@ -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: @@ -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,45 @@ 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(void); + +/** + * 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); + +/** + * 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); + +/** + * 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. + * + * Enable or disable matching events. + */ +void trace_enable_events(const char *line_buf); #include "trace/control-internal.h" diff --git a/qemu/trace/event-internal.h b/qemu/trace/event-internal.h index b2310d9be..86f6a511b 100644 --- a/qemu/trace/event-internal.h +++ b/qemu/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; diff --git a/qemu/trace/ftrace.c b/qemu/trace/ftrace.c index a7ae371e6..e953922f5 100644 --- a/qemu/trace/ftrace.c +++ b/qemu/trace/ftrace.c @@ -9,10 +9,7 @@ * */ -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <limits.h> +#include "qemu/osdep.h" #include "trace.h" #include "trace/control.h" diff --git a/qemu/trace/ftrace.h b/qemu/trace/ftrace.h index 863e052e9..92372e3ca 100644 --- a/qemu/trace/ftrace.h +++ b/qemu/trace/ftrace.h @@ -1,7 +1,6 @@ #ifndef TRACE_FTRACE_H #define TRACE_FTRACE_H -#include <stdbool.h> #define MAX_TRACE_STRLEN 512 diff --git a/qemu/trace/qmp.c b/qemu/trace/qmp.c index 0b1948952..8aa2660aa 100644 --- a/qemu/trace/qmp.c +++ b/qemu/trace/qmp.c @@ -7,7 +7,7 @@ * See the COPYING file in the top-level directory. */ -#include "qemu/typedefs.h" +#include "qemu/osdep.h" #include "qmp-commands.h" #include "trace/control.h" diff --git a/qemu/trace/simple.c b/qemu/trace/simple.c index 11ad03093..3fdcc8226 100644 --- a/qemu/trace/simple.c +++ b/qemu/trace/simple.c @@ -8,12 +8,8 @@ * */ -#include <stdlib.h> -#include <stdint.h> -#include <stdio.h> -#include <time.h> +#include "qemu/osdep.h" #ifndef _WIN32 -#include <signal.h> #include <pthread.h> #endif #include "qemu/timer.h" @@ -322,20 +318,20 @@ void st_set_trace_file_enabled(bool enable) * @file The trace file name or NULL for the default name-<pid> 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); g_free(trace_file_name); if (!file) { - trace_file_name = g_strdup_printf(CONFIG_TRACE_FILE, getpid()); + /* Type cast needed for Windows where getpid() returns an int. */ + trace_file_name = g_strdup_printf(CONFIG_TRACE_FILE, (pid_t)getpid()); } else { trace_file_name = g_strdup_printf("%s", 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, ...)) @@ -373,7 +369,7 @@ static GThread *trace_thread_create(GThreadFunc fn) return thread; } -bool st_init(const char *file) +bool st_init(void) { GThread *thread; @@ -386,6 +382,5 @@ bool st_init(const char *file) } atexit(st_flush_trace_buffer); - st_set_trace_file(file); return true; } diff --git a/qemu/trace/simple.h b/qemu/trace/simple.h index 699799685..1e7de4557 100644 --- a/qemu/trace/simple.h +++ b/qemu/trace/simple.h @@ -11,17 +11,14 @@ #ifndef TRACE_SIMPLE_H #define TRACE_SIMPLE_H -#include <stdint.h> -#include <stdbool.h> -#include <stdio.h> #include "trace/generated-events.h" 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 { |