diff options
Diffstat (limited to 'trace')
-rw-r--r-- | trace/Makefile.objs | 32 | ||||
-rw-r--r-- | trace/control-internal.h | 4 | ||||
-rw-r--r-- | trace/control.c | 86 | ||||
-rw-r--r-- | trace/control.h | 27 | ||||
-rw-r--r-- | trace/default.c | 40 | ||||
-rw-r--r-- | trace/ftrace.c | 25 | ||||
-rw-r--r-- | trace/ftrace.h | 5 | ||||
-rw-r--r-- | trace/simple.c | 27 | ||||
-rw-r--r-- | trace/simple.h | 1 | ||||
-rw-r--r-- | trace/stderr.c | 30 |
10 files changed, 103 insertions, 174 deletions
diff --git a/trace/Makefile.objs b/trace/Makefile.objs index 6a30467096..d7a86969a4 100644 --- a/trace/Makefile.objs +++ b/trace/Makefile.objs @@ -3,12 +3,12 @@ ###################################################################### # Auto-generated event descriptions for LTTng ust code -ifeq ($(TRACE_BACKEND),ust) +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 $(call quiet-command,$(TRACETOOL) \ --format=ust-events-h \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -16,7 +16,7 @@ $(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-hos $(obj)/generated-ust.c-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=ust-events-c \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -31,7 +31,7 @@ $(obj)/generated-events.h: $(obj)/generated-events.h-timestamp $(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=events-h \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -39,7 +39,7 @@ $(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/conf $(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events $(call quiet-command,$(TRACETOOL) \ --format=events-c \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) @@ -54,23 +54,21 @@ $(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp $(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak $(call quiet-command,$(TRACETOOL) \ --format=h \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") ###################################################################### # Auto-generated tracing routines (non-DTrace) -ifneq ($(TRACE_BACKEND),dtrace) $(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 $(call quiet-command,$(TRACETOOL) \ --format=c \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") $(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers.h -endif ###################################################################### @@ -79,27 +77,27 @@ endif # Normal practice is to name DTrace probe file with a '.d' extension # but that gets picked up by QEMU's Makefile as an external dependency # rule file. So we use '.dtrace' instead -ifeq ($(TRACE_BACKEND),dtrace) -$(obj)/generated-tracers.dtrace: $(obj)/generated-tracers.dtrace-timestamp -$(obj)/generated-tracers.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak +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 $(call quiet-command,$(TRACETOOL) \ --format=d \ - --backend=$(TRACE_BACKEND) \ + --backends=$(TRACE_BACKENDS) \ < $< > $@," GEN $(patsubst %-timestamp,%,$@)") @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@) -$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers.dtrace +$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers-dtrace.dtrace $(call quiet-command,dtrace -o $@ -h -s $<, " GEN $@") -$(obj)/generated-tracers.o: $(obj)/generated-tracers.dtrace +$(obj)/generated-tracers-dtrace.o: $(obj)/generated-tracers-dtrace.dtrace + +util-obj-y += generated-tracers-dtrace.o endif ###################################################################### # Backend code -util-obj-$(CONFIG_TRACE_DEFAULT) += default.o util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o -util-obj-$(CONFIG_TRACE_STDERR) += stderr.o util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o util-obj-$(CONFIG_TRACE_UST) += generated-ust.o util-obj-y += control.o diff --git a/trace/control-internal.h b/trace/control-internal.h index b3f587ed93..5a8df28c58 100644 --- a/trace/control-internal.h +++ b/trace/control-internal.h @@ -1,7 +1,7 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> + * Copyright (C) 2011-2014 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. @@ -61,7 +61,7 @@ static inline void trace_event_set_state_dynamic(TraceEvent *ev, bool state) { assert(ev != NULL); assert(trace_event_get_state_static(ev)); - return trace_event_set_state_dynamic_backend(ev, state); + ev->dstate = state; } #endif /* TRACE__CONTROL_INTERNAL_H */ diff --git a/trace/control.c b/trace/control.c index 49f61e137b..9631a40eff 100644 --- a/trace/control.c +++ b/trace/control.c @@ -1,14 +1,20 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> + * Copyright (C) 2011-2014 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. */ #include "trace/control.h" - +#ifdef CONFIG_TRACE_SIMPLE +#include "trace/simple.h" +#endif +#ifdef CONFIG_TRACE_FTRACE +#include "trace/ftrace.h" +#endif +#include "qemu/error-report.h" TraceEvent *trace_event_name(const char *name) { @@ -79,20 +85,39 @@ TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev) return NULL; } -void trace_backend_init_events(const char *fname) +void trace_print_events(FILE *stream, fprintf_function stream_printf) +{ + TraceEventID i; + + for (i = 0; i < trace_event_count(); i++) { + TraceEvent *ev = trace_event_id(i); + stream_printf(stream, "%s [Event ID %u] : state %u\n", + trace_event_get_name(ev), i, + trace_event_get_state_static(ev) && + trace_event_get_state_dynamic(ev)); + } +} + +static void trace_init_events(const char *fname) { + Location loc; + FILE *fp; + char line_buf[1024]; + size_t line_idx = 0; + if (fname == NULL) { return; } - FILE *fp = fopen(fname, "r"); + loc_push_none(&loc); + loc_set_file(fname, 0); + fp = fopen(fname, "r"); if (!fp) { - fprintf(stderr, "error: could not open trace events file '%s': %s\n", - fname, strerror(errno)); + error_report("%s", strerror(errno)); exit(1); } - char line_buf[1024]; while (fgets(line_buf, sizeof(line_buf), fp)) { + loc_set_file(fname, ++line_idx); size_t len = strlen(line_buf); if (len > 1) { /* skip empty lines */ line_buf[len - 1] = '\0'; @@ -111,22 +136,47 @@ void trace_backend_init_events(const char *fname) } else { TraceEvent *ev = trace_event_name(line_ptr); if (ev == NULL) { - fprintf(stderr, - "error: trace event '%s' does not exist\n", line_ptr); - exit(1); + 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\n", + line_ptr); + } else { + trace_event_set_state_dynamic(ev, enable); } - if (!trace_event_get_state_static(ev)) { - fprintf(stderr, - "error: trace event '%s' is not traceable\n", line_ptr); - exit(1); - } - trace_event_set_state_dynamic(ev, enable); } } } if (fclose(fp) != 0) { - fprintf(stderr, "error: closing file '%s': %s\n", - fname, strerror(errno)); + loc_set_file(fname, 0); + error_report("%s", strerror(errno)); exit(1); } + loc_pop(&loc); +} + +bool trace_init_backends(const char *events, const char *file) +{ +#ifdef CONFIG_TRACE_SIMPLE + if (!st_init(file)) { + fprintf(stderr, "failed to initialize simple tracing backend.\n"); + return false; + } +#else + if (file) { + fprintf(stderr, "error: -trace file=...: " + "option not supported by the selected tracing backends\n"); + return false; + } +#endif + +#ifdef CONFIG_TRACE_FTRACE + if (!ftrace_init()) { + fprintf(stderr, "failed to initialize ftrace backend.\n"); + return false; + } +#endif + + trace_init_events(events); + return true; } diff --git a/trace/control.h b/trace/control.h index cde8260a8a..e1ec033705 100644 --- a/trace/control.h +++ b/trace/control.h @@ -1,7 +1,7 @@ /* * Interface for configuring and controlling the state of tracing events. * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> + * Copyright (C) 2011-2014 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. @@ -146,26 +146,17 @@ static bool trace_event_get_state_dynamic(TraceEvent *ev); */ static void trace_event_set_state_dynamic(TraceEvent *ev, bool state); -/** - * trace_event_set_state_dynamic_backend: - * - * Warning: This function must be implemented by each tracing backend. - */ -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state); - /** * trace_print_events: * * Print the state of all events. - * - * Warning: This function must be implemented by each tracing backend. */ void trace_print_events(FILE *stream, fprintf_function stream_printf); /** - * trace_backend_init: + * 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. @@ -173,19 +164,9 @@ void trace_print_events(FILE *stream, fprintf_function stream_printf); * * Initialize the tracing backend. * - * Warning: This function must be implemented by each tracing backend. - * - * Returns: Whether the backend could be successfully initialized. - */ -bool trace_backend_init(const char *events, const char *file); - -/** - * trace_backend_init_events: - * @fname: Name of file with events to enable; may be NULL. - * - * Generic function to initialize the state of events. + * Returns: Whether the backends could be successfully initialized. */ -void trace_backend_init_events(const char *fname); +bool trace_init_backends(const char *events, const char *file); #include "trace/control-internal.h" diff --git a/trace/default.c b/trace/default.c deleted file mode 100644 index 6e07a479d6..0000000000 --- a/trace/default.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Default implementation for backend initialization from commandline. - * - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu> - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - */ - -#include "trace/control.h" - - -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - fprintf(stderr, "warning: " - "cannot print the trace events with the current backend\n"); - stream_printf(stream, "error: " - "operation not supported with the current backend\n"); -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - fprintf(stderr, "warning: " - "cannot set the state of a trace event with the current backend\n"); -} - -bool trace_backend_init(const char *events, const char *file) -{ - if (events) { - fprintf(stderr, "error: -trace events=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - if (file) { - fprintf(stderr, "error: -trace file=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - return true; -} diff --git a/trace/ftrace.c b/trace/ftrace.c index 46b7fdb1f2..a7ae371e6f 100644 --- a/trace/ftrace.c +++ b/trace/ftrace.c @@ -42,35 +42,13 @@ static int find_debugfs(char *debugfs) return 1; } -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - TraceEventID i; - - for (i = 0; i < trace_event_count(); i++) { - TraceEvent *ev = trace_event_id(i); - stream_printf(stream, "%s [Event ID %u] : state %u\n", - trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev)); - } -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - ev->dstate = state; -} - -bool trace_backend_init(const char *events, const char *file) +bool ftrace_init(void) { char debugfs[PATH_MAX]; char path[PATH_MAX]; int debugfs_found; int trace_fd = -1; - if (file) { - fprintf(stderr, "error: -trace file=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - debugfs_found = find_debugfs(debugfs); if (debugfs_found) { snprintf(path, PATH_MAX, "%s/tracing/tracing_on", debugfs); @@ -97,6 +75,5 @@ bool trace_backend_init(const char *events, const char *file) return false; } - trace_backend_init_events(events); return true; } diff --git a/trace/ftrace.h b/trace/ftrace.h index 94cb8d5365..863e052e90 100644 --- a/trace/ftrace.h +++ b/trace/ftrace.h @@ -1,10 +1,15 @@ #ifndef TRACE_FTRACE_H #define TRACE_FTRACE_H +#include <stdbool.h> + + #define MAX_TRACE_STRLEN 512 #define _STR(x) #x #define STR(x) _STR(x) extern int trace_marker_fd; +bool ftrace_init(void); + #endif /* ! TRACE_FTRACE_H */ diff --git a/trace/simple.c b/trace/simple.c index bb0b52ce02..a8f923c82e 100644 --- a/trace/simple.c +++ b/trace/simple.c @@ -75,6 +75,7 @@ uint8_t trace_buf[TRACE_BUF_LEN]; static volatile gint trace_idx; static unsigned int writeout_idx; static volatile gint dropped_events; +static uint32_t trace_pid; static FILE *trace_fp; static char *trace_file_name; @@ -83,7 +84,7 @@ typedef struct { uint64_t event; /* TraceEventID */ uint64_t timestamp_ns; uint32_t length; /* in bytes */ - uint32_t reserved; /* unused */ + uint32_t pid; uint64_t arguments[]; } TraceRecord; @@ -190,7 +191,7 @@ static gpointer writeout_thread(gpointer opaque) dropped.rec.event = DROPPED_EVENT_ID, dropped.rec.timestamp_ns = get_clock(); dropped.rec.length = sizeof(TraceRecord) + sizeof(uint64_t), - dropped.rec.reserved = 0; + dropped.rec.pid = trace_pid; do { dropped_count = g_atomic_int_get(&dropped_events); } while (!g_atomic_int_compare_and_exchange(&dropped_events, @@ -249,6 +250,7 @@ int trace_record_start(TraceBufferRecord *rec, TraceEventID event, size_t datasi rec_off = write_to_buffer(rec_off, &event_u64, sizeof(event_u64)); rec_off = write_to_buffer(rec_off, ×tamp_ns, sizeof(timestamp_ns)); rec_off = write_to_buffer(rec_off, &rec_len, sizeof(rec_len)); + rec_off = write_to_buffer(rec_off, &trace_pid, sizeof(trace_pid)); rec->tbuf_idx = idx; rec->rec_off = (idx + sizeof(TraceRecord)) % TRACE_BUF_LEN; @@ -366,22 +368,6 @@ void st_flush_trace_buffer(void) flush_trace_file(true); } -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - unsigned int i; - - for (i = 0; i < trace_event_count(); i++) { - TraceEvent *ev = trace_event_id(i); - stream_printf(stream, "%s [Event ID %u] : state %u\n", - trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev)); - } -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - ev->dstate = state; -} - /* Helper function to create a thread with signals blocked. Use glib's * portable threads since QEMU abstractions cannot be used due to reentrancy in * the tracer. Also note the signal masking on POSIX hosts so that the thread @@ -410,10 +396,12 @@ static GThread *trace_thread_create(GThreadFunc fn) return thread; } -bool trace_backend_init(const char *events, const char *file) +bool st_init(const char *file) { GThread *thread; + trace_pid = getpid(); + #if !GLIB_CHECK_VERSION(2, 31, 0) trace_available_cond = g_cond_new(); trace_empty_cond = g_cond_new(); @@ -426,7 +414,6 @@ bool trace_backend_init(const char *events, const char *file) } atexit(st_flush_trace_buffer); - trace_backend_init_events(events); st_set_trace_file(file); return true; } diff --git a/trace/simple.h b/trace/simple.h index 5260d9aa81..6997996855 100644 --- a/trace/simple.h +++ b/trace/simple.h @@ -21,6 +21,7 @@ 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_flush_trace_buffer(void); typedef struct { diff --git a/trace/stderr.c b/trace/stderr.c deleted file mode 100644 index e212efd64d..0000000000 --- a/trace/stderr.c +++ /dev/null @@ -1,30 +0,0 @@ -#include "trace.h" -#include "trace/control.h" - - -void trace_print_events(FILE *stream, fprintf_function stream_printf) -{ - TraceEventID i; - - for (i = 0; i < trace_event_count(); i++) { - TraceEvent *ev = trace_event_id(i); - stream_printf(stream, "%s [Event ID %u] : state %u\n", - trace_event_get_name(ev), i, trace_event_get_state_dynamic(ev)); - } -} - -void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state) -{ - ev->dstate = state; -} - -bool trace_backend_init(const char *events, const char *file) -{ - if (file) { - fprintf(stderr, "error: -trace file=...: " - "option not supported by the selected tracing backend\n"); - return false; - } - trace_backend_init_events(events); - return true; -} |