summaryrefslogtreecommitdiffstats
path: root/qemu/trace
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/trace')
-rw-r--r--qemu/trace/Makefile.objs48
-rw-r--r--qemu/trace/control-internal.h16
-rw-r--r--qemu/trace/control.c103
-rw-r--r--qemu/trace/control.h46
-rw-r--r--qemu/trace/event-internal.h2
-rw-r--r--qemu/trace/ftrace.c5
-rw-r--r--qemu/trace/ftrace.h1
-rw-r--r--qemu/trace/qmp.c2
-rw-r--r--qemu/trace/simple.c15
-rw-r--r--qemu/trace/simple.h7
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 {