diff options
Diffstat (limited to 'qemu/trace')
-rw-r--r-- | qemu/trace/Makefile.objs | 155 | ||||
-rw-r--r-- | qemu/trace/control-internal.h | 75 | ||||
-rw-r--r-- | qemu/trace/control.c | 218 | ||||
-rw-r--r-- | qemu/trace/control.h | 203 | ||||
-rw-r--r-- | qemu/trace/event-internal.h | 31 | ||||
-rw-r--r-- | qemu/trace/ftrace.c | 76 | ||||
-rw-r--r-- | qemu/trace/ftrace.h | 14 | ||||
-rw-r--r-- | qemu/trace/qmp.c | 75 | ||||
-rw-r--r-- | qemu/trace/simple.c | 386 | ||||
-rw-r--r-- | qemu/trace/simple.h | 55 |
10 files changed, 0 insertions, 1288 deletions
diff --git a/qemu/trace/Makefile.objs b/qemu/trace/Makefile.objs deleted file mode 100644 index 5145b34d1..000000000 --- a/qemu/trace/Makefile.objs +++ /dev/null @@ -1,155 +0,0 @@ -# -*- 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 - @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,%,$@)") - -$(obj)/generated-ust.c: $(obj)/generated-ust.c-timestamp $(BUILD_DIR)/config-host.mak - @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,%,$@)") - -$(obj)/generated-events.h: $(obj)/generated-ust-provider.h -$(obj)/generated-events.c: $(obj)/generated-ust.c -endif - -###################################################################### -# Auto-generated event descriptions - -$(obj)/generated-events.h: $(obj)/generated-events.h-timestamp - @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,%,$@)") - -$(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/config-host.mak - @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,%,$@)") - -util-obj-y += generated-events.o - - -###################################################################### -# Auto-generated tracing routines - -################################################## -# Execution level - -$(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 $(tracetool-y) - $(call quiet-command,$(TRACETOOL) \ - --format=h \ - --backends=$(TRACE_BACKENDS) \ - < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - -############################## -# non-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 $(tracetool-y) - $(call quiet-command,$(TRACETOOL) \ - --format=c \ - --backends=$(TRACE_BACKENDS) \ - < $< > $@," GEN $(patsubst %-timestamp,%,$@)") - -$(obj)/generated-tracers.o: $(obj)/generated-tracers.c $(obj)/generated-tracers.h - -############################## -# DTrace - -# 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 ($(findstring dtrace,$(TRACE_BACKENDS)),dtrace) -$(obj)/generated-tracers-dtrace.dtrace: $(obj)/generated-tracers-dtrace.dtrace-timestamp - @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,%,$@)") - -$(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers-dtrace.dtrace - $(call quiet-command,dtrace -o $@ -h -s $<, " GEN $@") - -$(obj)/generated-tracers-dtrace.o: $(obj)/generated-tracers-dtrace.dtrace - -util-obj-y += generated-tracers-dtrace.o -endif - -################################################## -# Translation level - -$(obj)/generated-helpers-wrappers.h: $(obj)/generated-helpers-wrappers.h-timestamp - @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,%,$@)") - -$(obj)/generated-helpers.h: $(obj)/generated-helpers.h-timestamp - @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,%,$@)") - -$(obj)/generated-helpers.c: $(obj)/generated-helpers.c-timestamp - @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,%,$@)") - -$(obj)/generated-helpers.o: $(obj)/generated-helpers.c - -target-obj-y += generated-helpers.o - - -$(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp - @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,%,$@)") - - -###################################################################### -# Backend code - -util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o generated-tracers.o -util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o -util-obj-$(CONFIG_TRACE_UST) += generated-ust.o -util-obj-y += control.o -util-obj-y += qmp.o diff --git a/qemu/trace/control-internal.h b/qemu/trace/control-internal.h deleted file mode 100644 index dcf67f505..000000000 --- a/qemu/trace/control-internal.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Interface for configuring and controlling the state of tracing events. - * - * 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. - */ - -#ifndef TRACE__CONTROL_INTERNAL_H -#define TRACE__CONTROL_INTERNAL_H - - - -extern TraceEvent trace_events[]; -extern bool trace_events_dstate[]; -extern int trace_events_enabled_count; - - -static inline TraceEventID trace_event_count(void) -{ - return TRACE_EVENT_COUNT; -} - -static inline TraceEvent *trace_event_id(TraceEventID id) -{ - assert(id < trace_event_count()); - return &trace_events[id]; -} - -static inline bool trace_event_is_pattern(const char *str) -{ - assert(str != NULL); - return strchr(str, '*') != NULL; -} - -static inline TraceEventID trace_event_get_id(TraceEvent *ev) -{ - assert(ev != NULL); - return ev->id; -} - -static inline const char * trace_event_get_name(TraceEvent *ev) -{ - assert(ev != NULL); - return ev->name; -} - -static inline bool trace_event_get_state_static(TraceEvent *ev) -{ - assert(ev != NULL); - 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) -{ - 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 - 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 deleted file mode 100644 index d099f735d..000000000 --- a/qemu/trace/control.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Interface for configuring and controlling the state of tracing events. - * - * 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 "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) -{ - assert(name != NULL); - - TraceEventID i; - for (i = 0; i < trace_event_count(); i++) { - TraceEvent *ev = trace_event_id(i); - if (strcmp(trace_event_get_name(ev), name) == 0) { - return ev; - } - } - return NULL; -} - -static bool pattern_glob(const char *pat, const char *ev) -{ - while (*pat != '\0' && *ev != '\0') { - if (*pat == *ev) { - pat++; - ev++; - } - else if (*pat == '*') { - if (pattern_glob(pat, ev+1)) { - return true; - } else if (pattern_glob(pat+1, ev)) { - return true; - } else { - return false; - } - } else { - return false; - } - } - - while (*pat == '*') { - pat++; - } - - if (*pat == '\0' && *ev == '\0') { - return true; - } else { - return false; - } -} - -TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev) -{ - assert(pat != NULL); - - TraceEventID i; - - if (ev == NULL) { - i = -1; - } else { - i = trace_event_get_id(ev); - } - i++; - - while (i < trace_event_count()) { - TraceEvent *res = trace_event_id(i); - if (pattern_glob(pat, trace_event_get_name(res))) { - return res; - } - i++; - } - - return NULL; -} - -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; - char line_buf[1024]; - size_t line_idx = 0; - - if (fname == NULL) { - return; - } - - loc_push_none(&loc); - loc_set_file(fname, 0); - fp = fopen(fname, "r"); - if (!fp) { - error_report("%s", strerror(errno)); - exit(1); - } - 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'; - if ('#' == line_buf[0]) { /* skip commented lines */ - continue; - } - trace_enable_events(line_buf); - } - } - if (fclose(fp) != 0) { - loc_set_file(fname, 0); - error_report("%s", strerror(errno)); - exit(1); - } - loc_pop(&loc); -} - -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=...: " - "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 - -#ifdef CONFIG_TRACE_FTRACE - if (!ftrace_init()) { - fprintf(stderr, "failed to initialize ftrace backend.\n"); - return false; - } -#endif - - return true; -} diff --git a/qemu/trace/control.h b/qemu/trace/control.h deleted file mode 100644 index e2ba6d4de..000000000 --- a/qemu/trace/control.h +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Interface for configuring and controlling the state of tracing events. - * - * 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. - */ - -#ifndef TRACE__CONTROL_H -#define TRACE__CONTROL_H - -#include "qemu-common.h" -#include "trace/generated-events.h" - - -/** - * TraceEventID: - * - * Unique tracing event identifier. - * - * These are named as 'TRACE_${EVENT_NAME}'. - * - * See also: "trace/generated-events.h" - */ -enum TraceEventID; - -/** - * trace_event_id: - * @id: Event identifier. - * - * Get an event by its identifier. - * - * This routine has a constant cost, as opposed to trace_event_name and - * trace_event_pattern. - * - * Pre-conditions: The identifier is valid. - * - * Returns: pointer to #TraceEvent. - * - */ -static TraceEvent *trace_event_id(TraceEventID id); - -/** - * trace_event_name: - * @id: Event name. - * - * Search an event by its name. - * - * Returns: pointer to #TraceEvent or NULL if not found. - */ -TraceEvent *trace_event_name(const char *name); - -/** - * trace_event_pattern: - * @pat: Event name pattern. - * @ev: Event to start searching from (not included). - * - * Get all events with a given name pattern. - * - * Returns: pointer to #TraceEvent or NULL if not found. - */ -TraceEvent *trace_event_pattern(const char *pat, TraceEvent *ev); - -/** - * trace_event_is_pattern: - * - * Whether the given string is an event name pattern. - */ -static bool trace_event_is_pattern(const char *str); - -/** - * trace_event_count: - * - * Return the number of events. - */ -static TraceEventID trace_event_count(void); - - - -/** - * trace_event_get_id: - * - * Get the identifier of an event. - */ -static TraceEventID trace_event_get_id(TraceEvent *ev); - -/** - * trace_event_get_name: - * - * Get the name of an event. - */ -static const char * trace_event_get_name(TraceEvent *ev); - -/** - * trace_event_get_state: - * @id: Event identifier. - * - * Get the tracing state of an event (both static and dynamic). - * - * If the event has the disabled property, the check will have no performance - * impact. - * - * 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_by_id(id)) - -/** - * trace_event_get_state_static: - * @id: Event identifier. - * - * Get the static tracing state of an event. - * - * Use the define 'TRACE_${EVENT_NAME}_ENABLED' for compile-time checks (it will - * be set to 1 or 0 according to the presence of the disabled property). - */ -static bool trace_event_get_state_static(TraceEvent *ev); - -/** - * trace_event_get_state_dynamic: - * - * Get the dynamic tracing state of an event. - */ -static bool trace_event_get_state_dynamic(TraceEvent *ev); - -/** - * trace_event_set_state: - * - * Set the tracing state of an event (only if possible). - */ -#define trace_event_set_state(id, state) \ - do { \ - if ((id ##_ENABLED)) { \ - TraceEvent *_e = trace_event_id(id); \ - trace_event_set_state_dynamic(_e, state); \ - } \ - } while (0) - -/** - * trace_event_set_state_dynamic: - * - * Set the dynamic tracing state of an event. - * - * Pre-condition: trace_event_get_state_static(ev) == true - */ -static void trace_event_set_state_dynamic(TraceEvent *ev, bool state); - - - -/** - * trace_init_backends: - * @file: Name of trace output file; may be NULL. - * Corresponds to commandline option "-trace file=...". - * - * Initialize the tracing backend. - * - * Returns: Whether the backends could be successfully initialized. - */ -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" - -#endif /* TRACE__CONTROL_H */ diff --git a/qemu/trace/event-internal.h b/qemu/trace/event-internal.h deleted file mode 100644 index 86f6a511b..000000000 --- a/qemu/trace/event-internal.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Interface for configuring and controlling the state of tracing events. - * - * Copyright (C) 2012 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. - */ - -#ifndef TRACE__EVENT_INTERNAL_H -#define TRACE__EVENT_INTERNAL_H - -#include "trace/generated-events.h" - - -/** - * TraceEvent: - * @id: Unique event identifier. - * @name: Event name. - * @sstate: Static tracing state. - * - * Opaque generic description of a tracing event. - */ -typedef struct TraceEvent { - TraceEventID id; - const char * name; - const bool sstate; -} TraceEvent; - - -#endif /* TRACE__EVENT_INTERNAL_H */ diff --git a/qemu/trace/ftrace.c b/qemu/trace/ftrace.c deleted file mode 100644 index e953922f5..000000000 --- a/qemu/trace/ftrace.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Ftrace trace backend - * - * Copyright (C) 2013 Hitachi, Ltd. - * Created by Eiichi Tsukata <eiichi.tsukata.xh@hitachi.com> - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#include "qemu/osdep.h" -#include "trace.h" -#include "trace/control.h" - -int trace_marker_fd; - -static int find_debugfs(char *debugfs) -{ - char type[100]; - FILE *fp; - - fp = fopen("/proc/mounts", "r"); - if (fp == NULL) { - return 0; - } - - while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n", - debugfs, type) == 2) { - if (strcmp(type, "debugfs") == 0) { - break; - } - } - fclose(fp); - - if (strcmp(type, "debugfs") != 0) { - return 0; - } - return 1; -} - -bool ftrace_init(void) -{ - char debugfs[PATH_MAX]; - char path[PATH_MAX]; - int debugfs_found; - int trace_fd = -1; - - debugfs_found = find_debugfs(debugfs); - if (debugfs_found) { - snprintf(path, PATH_MAX, "%s/tracing/tracing_on", debugfs); - trace_fd = open(path, O_WRONLY); - if (trace_fd < 0) { - perror("Could not open ftrace 'tracing_on' file"); - return false; - } else { - if (write(trace_fd, "1", 1) < 0) { - perror("Could not write to 'tracing_on' file"); - close(trace_fd); - return false; - } - close(trace_fd); - } - snprintf(path, PATH_MAX, "%s/tracing/trace_marker", debugfs); - trace_marker_fd = open(path, O_WRONLY); - if (trace_marker_fd < 0) { - perror("Could not open ftrace 'trace_marker' file"); - return false; - } - } else { - fprintf(stderr, "debugfs is not mounted\n"); - return false; - } - - return true; -} diff --git a/qemu/trace/ftrace.h b/qemu/trace/ftrace.h deleted file mode 100644 index 92372e3ca..000000000 --- a/qemu/trace/ftrace.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef TRACE_FTRACE_H -#define TRACE_FTRACE_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/qemu/trace/qmp.c b/qemu/trace/qmp.c deleted file mode 100644 index 8aa2660aa..000000000 --- a/qemu/trace/qmp.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * QMP commands for tracing events. - * - * Copyright (C) 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 "qemu/osdep.h" -#include "qmp-commands.h" -#include "trace/control.h" - - -TraceEventInfoList *qmp_trace_event_get_state(const char *name, Error **errp) -{ - TraceEventInfoList *events = NULL; - bool found = false; - TraceEvent *ev; - - ev = NULL; - while ((ev = trace_event_pattern(name, ev)) != NULL) { - TraceEventInfoList *elem = g_new(TraceEventInfoList, 1); - elem->value = g_new(TraceEventInfo, 1); - elem->value->name = g_strdup(trace_event_get_name(ev)); - if (!trace_event_get_state_static(ev)) { - elem->value->state = TRACE_EVENT_STATE_UNAVAILABLE; - } else if (!trace_event_get_state_dynamic(ev)) { - elem->value->state = TRACE_EVENT_STATE_DISABLED; - } else { - elem->value->state = TRACE_EVENT_STATE_ENABLED; - } - elem->next = events; - events = elem; - found = true; - } - - if (!found && !trace_event_is_pattern(name)) { - error_setg(errp, "unknown event \"%s\"", name); - } - - return events; -} - -void qmp_trace_event_set_state(const char *name, bool enable, - bool has_ignore_unavailable, - bool ignore_unavailable, Error **errp) -{ - bool found = false; - TraceEvent *ev; - - /* Check all selected events are dynamic */ - ev = NULL; - while ((ev = trace_event_pattern(name, ev)) != NULL) { - found = true; - if (!(has_ignore_unavailable && ignore_unavailable) && - !trace_event_get_state_static(ev)) { - error_setg(errp, "cannot set dynamic tracing state for \"%s\"", - trace_event_get_name(ev)); - return; - } - } - if (!found && !trace_event_is_pattern(name)) { - error_setg(errp, "unknown event \"%s\"", name); - return; - } - - /* Apply changes */ - ev = NULL; - while ((ev = trace_event_pattern(name, ev)) != NULL) { - if (trace_event_get_state_static(ev)) { - trace_event_set_state_dynamic(ev, enable); - } - } -} diff --git a/qemu/trace/simple.c b/qemu/trace/simple.c deleted file mode 100644 index 3fdcc8226..000000000 --- a/qemu/trace/simple.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - * Simple trace backend - * - * Copyright IBM, Corp. 2010 - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#include "qemu/osdep.h" -#ifndef _WIN32 -#include <pthread.h> -#endif -#include "qemu/timer.h" -#include "trace.h" -#include "trace/control.h" -#include "trace/simple.h" - -/** Trace file header event ID */ -#define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */ - -/** Trace file magic number */ -#define HEADER_MAGIC 0xf2b177cb0aa429b4ULL - -/** Trace file version number, bump if format changes */ -#define HEADER_VERSION 3 - -/** Records were dropped event ID */ -#define DROPPED_EVENT_ID (~(uint64_t)0 - 1) - -/** Trace record is valid */ -#define TRACE_RECORD_VALID ((uint64_t)1 << 63) - -/* - * Trace records are written out by a dedicated thread. The thread waits for - * records to become available, writes them out, and then waits again. - */ -static CompatGMutex trace_lock; -static CompatGCond trace_available_cond; -static CompatGCond trace_empty_cond; - -static bool trace_available; -static bool trace_writeout_enabled; - -enum { - TRACE_BUF_LEN = 4096 * 64, - TRACE_BUF_FLUSH_THRESHOLD = TRACE_BUF_LEN / 4, -}; - -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; - -/* * Trace buffer entry */ -typedef struct { - uint64_t event; /* TraceEventID */ - uint64_t timestamp_ns; - uint32_t length; /* in bytes */ - uint32_t pid; - uint64_t arguments[]; -} TraceRecord; - -typedef struct { - uint64_t header_event_id; /* HEADER_EVENT_ID */ - uint64_t header_magic; /* HEADER_MAGIC */ - uint64_t header_version; /* HEADER_VERSION */ -} TraceLogHeader; - - -static void read_from_buffer(unsigned int idx, void *dataptr, size_t size); -static unsigned int write_to_buffer(unsigned int idx, void *dataptr, size_t size); - -static void clear_buffer_range(unsigned int idx, size_t len) -{ - uint32_t num = 0; - while (num < len) { - if (idx >= TRACE_BUF_LEN) { - idx = idx % TRACE_BUF_LEN; - } - trace_buf[idx++] = 0; - num++; - } -} -/** - * Read a trace record from the trace buffer - * - * @idx Trace buffer index - * @record Trace record to fill - * - * Returns false if the record is not valid. - */ -static bool get_trace_record(unsigned int idx, TraceRecord **recordptr) -{ - uint64_t event_flag = 0; - TraceRecord record; - /* read the event flag to see if its a valid record */ - read_from_buffer(idx, &record, sizeof(event_flag)); - - if (!(record.event & TRACE_RECORD_VALID)) { - return false; - } - - smp_rmb(); /* read memory barrier before accessing record */ - /* read the record header to know record length */ - read_from_buffer(idx, &record, sizeof(TraceRecord)); - *recordptr = malloc(record.length); /* dont use g_malloc, can deadlock when traced */ - /* make a copy of record to avoid being overwritten */ - read_from_buffer(idx, *recordptr, record.length); - smp_rmb(); /* memory barrier before clearing valid flag */ - (*recordptr)->event &= ~TRACE_RECORD_VALID; - /* clear the trace buffer range for consumed record otherwise any byte - * with its MSB set may be considered as a valid event id when the writer - * thread crosses this range of buffer again. - */ - clear_buffer_range(idx, record.length); - return true; -} - -/** - * Kick writeout thread - * - * @wait Whether to wait for writeout thread to complete - */ -static void flush_trace_file(bool wait) -{ - g_mutex_lock(&trace_lock); - trace_available = true; - g_cond_signal(&trace_available_cond); - - if (wait) { - g_cond_wait(&trace_empty_cond, &trace_lock); - } - - g_mutex_unlock(&trace_lock); -} - -static void wait_for_trace_records_available(void) -{ - g_mutex_lock(&trace_lock); - while (!(trace_available && trace_writeout_enabled)) { - g_cond_signal(&trace_empty_cond); - g_cond_wait(&trace_available_cond, &trace_lock); - } - trace_available = false; - g_mutex_unlock(&trace_lock); -} - -static gpointer writeout_thread(gpointer opaque) -{ - TraceRecord *recordptr; - union { - TraceRecord rec; - uint8_t bytes[sizeof(TraceRecord) + sizeof(uint64_t)]; - } dropped; - unsigned int idx = 0; - int dropped_count; - size_t unused __attribute__ ((unused)); - - for (;;) { - wait_for_trace_records_available(); - - if (g_atomic_int_get(&dropped_events)) { - dropped.rec.event = DROPPED_EVENT_ID, - dropped.rec.timestamp_ns = get_clock(); - dropped.rec.length = sizeof(TraceRecord) + sizeof(uint64_t), - dropped.rec.pid = trace_pid; - do { - dropped_count = g_atomic_int_get(&dropped_events); - } while (!g_atomic_int_compare_and_exchange(&dropped_events, - dropped_count, 0)); - dropped.rec.arguments[0] = dropped_count; - unused = fwrite(&dropped.rec, dropped.rec.length, 1, trace_fp); - } - - while (get_trace_record(idx, &recordptr)) { - unused = fwrite(recordptr, recordptr->length, 1, trace_fp); - writeout_idx += recordptr->length; - free(recordptr); /* dont use g_free, can deadlock when traced */ - idx = writeout_idx % TRACE_BUF_LEN; - } - - fflush(trace_fp); - } - return NULL; -} - -void trace_record_write_u64(TraceBufferRecord *rec, uint64_t val) -{ - rec->rec_off = write_to_buffer(rec->rec_off, &val, sizeof(uint64_t)); -} - -void trace_record_write_str(TraceBufferRecord *rec, const char *s, uint32_t slen) -{ - /* Write string length first */ - rec->rec_off = write_to_buffer(rec->rec_off, &slen, sizeof(slen)); - /* Write actual string now */ - rec->rec_off = write_to_buffer(rec->rec_off, (void*)s, slen); -} - -int trace_record_start(TraceBufferRecord *rec, TraceEventID event, size_t datasize) -{ - unsigned int idx, rec_off, old_idx, new_idx; - uint32_t rec_len = sizeof(TraceRecord) + datasize; - uint64_t event_u64 = event; - uint64_t timestamp_ns = get_clock(); - - do { - old_idx = g_atomic_int_get(&trace_idx); - smp_rmb(); - new_idx = old_idx + rec_len; - - if (new_idx - writeout_idx > TRACE_BUF_LEN) { - /* Trace Buffer Full, Event dropped ! */ - g_atomic_int_inc(&dropped_events); - return -ENOSPC; - } - } while (!g_atomic_int_compare_and_exchange(&trace_idx, old_idx, new_idx)); - - idx = old_idx % TRACE_BUF_LEN; - - rec_off = idx; - 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; - return 0; -} - -static void read_from_buffer(unsigned int idx, void *dataptr, size_t size) -{ - uint8_t *data_ptr = dataptr; - uint32_t x = 0; - while (x < size) { - if (idx >= TRACE_BUF_LEN) { - idx = idx % TRACE_BUF_LEN; - } - data_ptr[x++] = trace_buf[idx++]; - } -} - -static unsigned int write_to_buffer(unsigned int idx, void *dataptr, size_t size) -{ - uint8_t *data_ptr = dataptr; - uint32_t x = 0; - while (x < size) { - if (idx >= TRACE_BUF_LEN) { - idx = idx % TRACE_BUF_LEN; - } - trace_buf[idx++] = data_ptr[x++]; - } - return idx; /* most callers wants to know where to write next */ -} - -void trace_record_finish(TraceBufferRecord *rec) -{ - TraceRecord record; - read_from_buffer(rec->tbuf_idx, &record, sizeof(TraceRecord)); - smp_wmb(); /* write barrier before marking as valid */ - record.event |= TRACE_RECORD_VALID; - write_to_buffer(rec->tbuf_idx, &record, sizeof(TraceRecord)); - - if (((unsigned int)g_atomic_int_get(&trace_idx) - writeout_idx) - > TRACE_BUF_FLUSH_THRESHOLD) { - flush_trace_file(false); - } -} - -void st_set_trace_file_enabled(bool enable) -{ - if (enable == !!trace_fp) { - return; /* no change */ - } - - /* Halt trace writeout */ - flush_trace_file(true); - trace_writeout_enabled = false; - flush_trace_file(true); - - if (enable) { - static const TraceLogHeader header = { - .header_event_id = HEADER_EVENT_ID, - .header_magic = HEADER_MAGIC, - /* Older log readers will check for version at next location */ - .header_version = HEADER_VERSION, - }; - - trace_fp = fopen(trace_file_name, "wb"); - if (!trace_fp) { - return; - } - - if (fwrite(&header, sizeof header, 1, trace_fp) != 1) { - fclose(trace_fp); - trace_fp = NULL; - return; - } - - /* Resume trace writeout */ - trace_writeout_enabled = true; - flush_trace_file(false); - } else { - fclose(trace_fp); - trace_fp = NULL; - } -} - -/** - * Set the name of a trace file - * - * @file The trace file name or NULL for the default name-<pid> set at - * config time - */ -void st_set_trace_file(const char *file) -{ - st_set_trace_file_enabled(false); - - g_free(trace_file_name); - - if (!file) { - /* 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); -} - -void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)) -{ - stream_printf(stream, "Trace file \"%s\" %s.\n", - trace_file_name, trace_fp ? "on" : "off"); -} - -void st_flush_trace_buffer(void) -{ - flush_trace_file(true); -} - -/* 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 - * does not steal signals when the rest of the program wants them blocked. - */ -static GThread *trace_thread_create(GThreadFunc fn) -{ - GThread *thread; -#ifndef _WIN32 - sigset_t set, oldset; - - sigfillset(&set); - pthread_sigmask(SIG_SETMASK, &set, &oldset); -#endif - - thread = g_thread_new("trace-thread", fn, NULL); - -#ifndef _WIN32 - pthread_sigmask(SIG_SETMASK, &oldset, NULL); -#endif - - return thread; -} - -bool st_init(void) -{ - GThread *thread; - - trace_pid = getpid(); - - thread = trace_thread_create(writeout_thread); - if (!thread) { - fprintf(stderr, "warning: unable to initialize simple trace backend\n"); - return false; - } - - atexit(st_flush_trace_buffer); - return true; -} diff --git a/qemu/trace/simple.h b/qemu/trace/simple.h deleted file mode 100644 index 1e7de4557..000000000 --- a/qemu/trace/simple.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Simple trace backend - * - * Copyright IBM, Corp. 2010 - * - * This work is licensed under the terms of the GNU GPL, version 2. See - * the COPYING file in the top-level directory. - * - */ - -#ifndef TRACE_SIMPLE_H -#define TRACE_SIMPLE_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); -void st_set_trace_file(const char *file); -bool st_init(void); -void st_flush_trace_buffer(void); - -typedef struct { - unsigned int tbuf_idx; - unsigned int rec_off; -} TraceBufferRecord; - -/* Note for hackers: Make sure MAX_TRACE_LEN < sizeof(uint32_t) */ -#define MAX_TRACE_STRLEN 512 -/** - * Initialize a trace record and claim space for it in the buffer - * - * @arglen number of bytes required for arguments - */ -int trace_record_start(TraceBufferRecord *rec, TraceEventID id, size_t arglen); - -/** - * Append a 64-bit argument to a trace record - */ -void trace_record_write_u64(TraceBufferRecord *rec, uint64_t val); - -/** - * Append a string argument to a trace record - */ -void trace_record_write_str(TraceBufferRecord *rec, const char *s, uint32_t slen); - -/** - * Mark a trace record completed - * - * Don't append any more arguments to the trace record after calling this. - */ -void trace_record_finish(TraceBufferRecord *rec); - -#endif /* TRACE_SIMPLE_H */ |