@@ -342,15 +342,22 @@ trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
$(call quiet-command,dtrace -o $@ -G -s $<, " GEN trace-dtrace.o")
simpletrace.o: simpletrace.c $(GENERATED_HEADERS)
+stderrtrace.o: stderrtrace.c $(GENERATED_HEADERS)
ifeq ($(TRACE_BACKEND),dtrace)
trace-obj-y = trace-dtrace.o
else
trace-obj-y = trace.o
+
ifeq ($(TRACE_BACKEND),simple)
trace-obj-y += simpletrace.o
user-obj-y += qemu-timer-common.o
endif
+
+ifeq ($(TRACE_BACKEND),stderr)
+trace-obj-y += stderrtrace.o
+endif
+
endif
######################################################################
@@ -361,4 +368,3 @@ libcacard-y = cac.o event.o vcard.o vreader.o vcard_emul_nss.o vcard_emul_type.o
vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
-
@@ -2933,6 +2933,9 @@ echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak
if test "$trace_backend" = "simple"; then
echo "CONFIG_SIMPLE_TRACE=y" >> $config_host_mak
fi
+if test "$trace_backend" = "stderr"; then
+ echo "CONFIG_STDERR_TRACE=y" >> $config_host_mak
+fi
# Set the appropriate trace file.
if test "$trace_backend" = "simple"; then
trace_file="\"$trace_file-%u\""
@@ -134,10 +134,8 @@ effectively turns trace events into debug printfs.
This is the simplest backend and can be used together with existing code that
uses DPRINTF().
-Note that with this backend trace events cannot be programmatically
-enabled/disabled. Thus, in order to trim down the amount of output and the
-performance impact of tracing, you might want to add the "disable" property in
-the "trace-events" file for those events you are not interested in.
+See the documentation in the "simple" backend for instruction on how to control
+trace event states from the command line, the monitor and/or programmatically.
=== Simpletrace ===
@@ -180,7 +180,7 @@ STEXI
Output logs to @var{filename}.
ETEXI
-#ifdef CONFIG_SIMPLE_TRACE
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
{
.name = "trace-event",
.args_type = "name:s,option:b",
@@ -194,7 +194,9 @@ STEXI
@findex trace-event
changes status of a trace event
ETEXI
+#endif
+#if defined(CONFIG_SIMPLE_TRACE)
{
.name = "trace-file",
.args_type = "op:s?,arg:F?",
@@ -1355,10 +1357,14 @@ show roms
@end table
ETEXI
-#ifdef CONFIG_SIMPLE_TRACE
+#if defined(CONFIG_SIMPLE_TRACE)
STEXI
@item info trace
show contents of trace buffer
+ETEXI
+#endif
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
+STEXI
@item info trace-events
show available trace events and their state
ETEXI
@@ -590,7 +590,7 @@ static void do_help_cmd(Monitor *mon, const QDict *qdict)
help_cmd(mon, qdict_get_try_str(qdict, "name"));
}
-#if defined(CONFIG_SIMPLE_TRACE)
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
static void do_change_trace_event_state(Monitor *mon, const QDict *qdict)
{
const char *tp_name = qdict_get_str(qdict, "name");
@@ -601,7 +601,9 @@ static void do_change_trace_event_state(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "unknown event name \"%s\"\n", tp_name);
}
}
+#endif
+#if defined(CONFIG_SIMPLE_TRACE)
static void do_trace_file(Monitor *mon, const QDict *qdict)
{
const char *op = qdict_get_try_str(qdict, "op");
@@ -999,7 +1001,9 @@ static void do_info_trace(Monitor *mon)
{
st_print_trace((FILE *)mon, &monitor_fprintf);
}
+#endif
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
static void do_info_trace_events(Monitor *mon)
{
st_print_trace_events((FILE *)mon, &monitor_fprintf);
@@ -3103,6 +3107,8 @@ static const mon_cmd_t info_cmds[] = {
.help = "show current contents of trace buffer",
.mhandler.info = do_info_trace,
},
+#endif
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
{
.name = "trace-events",
.args_type = "",
@@ -297,7 +297,7 @@ static QemuOptsList qemu_mon_opts = {
},
};
-#if defined(CONFIG_SIMPLE_TRACE)
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
static QemuOptsList qemu_trace_opts = {
.name = "trace",
.implied_opt_name = "trace",
@@ -306,7 +306,8 @@ static QemuOptsList qemu_trace_opts = {
{
.name = "file",
.type = QEMU_OPT_STRING,
- },{
+ },
+ {
.name = "events",
.type = QEMU_OPT_STRING,
},
@@ -464,7 +465,7 @@ static QemuOptsList *vm_config_groups[32] = {
&qemu_global_opts,
&qemu_mon_opts,
&qemu_cpudef_opts,
-#if defined(CONFIG_SIMPLE_TRACE)
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
&qemu_trace_opts,
#endif
&qemu_option_rom_opts,
@@ -2356,9 +2356,13 @@ Normally QEMU loads a configuration file from @var{sysconfdir}/qemu.conf and
@var{sysconfdir}/target-@var{ARCH}.conf on startup. The @code{-nodefconfig}
option will prevent QEMU from loading these configuration files at startup.
ETEXI
-#ifdef CONFIG_SIMPLE_TRACE
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
DEF("trace", HAS_ARG, QEMU_OPTION_trace,
+#if defined(CONFIG_SIMPLE_TRACE)
"-trace [file=<file>][,events=<file>]\n"
+#elif defined(CONFIG_STDERR_TRACE)
+ "-trace [events=<file>]\n"
+#endif
" specify tracing options\n",
QEMU_ARCH_ALL)
STEXI
@@ -2368,7 +2372,9 @@ STEXI
Specify tracing options.
@table @option
+#if defined(CONFIG_SIMPLE_TRACE)
@item file=@var{file}
+#endif
Log output traces to @var{file}.
@item events=@var{file}
Immediately enable events listed in @var{file}.
@@ -241,7 +241,12 @@ linetoh_begin_stderr()
{
cat <<EOF
#include <stdio.h>
+#include "stderrtrace.h"
+
+extern TraceEvent trace_list[];
EOF
+
+ stderr_event_num=0
}
linetoh_stderr()
@@ -260,29 +265,47 @@ linetoh_stderr()
cat <<EOF
static inline void trace_$name($args)
{
- fprintf(stderr, "$name $fmt\n" $argnames);
+ if (trace_list[$stderr_event_num].state != 0) {
+ fprintf(stderr, "$name $fmt\n" $argnames);
+ }
}
EOF
+ stderr_event_num=$((stderr_event_num + 1))
+
}
linetoh_end_stderr()
{
-return
+ cat <<EOF
+#define NR_TRACE_EVENTS $stderr_event_num
+EOF
}
linetoc_begin_stderr()
{
-return
+ cat <<EOF
+#include "trace.h"
+
+TraceEvent trace_list[] = {
+EOF
+ stderr_event_num=0
}
linetoc_stderr()
{
-return
+ local name
+ name=$(get_name "$1")
+ cat <<EOF
+{.tp_name = "$name", .state=0},
+EOF
+ stderr_event_num=$(($stderr_event_num + 1))
}
linetoc_end_stderr()
{
-return
+ cat <<EOF
+};
+EOF
}
#END OF STDERR
new file mode 100644
@@ -0,0 +1,24 @@
+#include "trace.h"
+
+void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...))
+{
+ unsigned int i;
+
+ for (i = 0; i < NR_TRACE_EVENTS; i++) {
+ stream_printf(stream, "%s [Event ID %u] : state %u\n",
+ trace_list[i].tp_name, i, trace_list[i].state);
+ }
+}
+
+bool st_change_trace_event_state(const char *name, bool enabled)
+{
+ int i;
+
+ for (i = 0; i < NR_TRACE_EVENTS; i++) {
+ if (!strcmp(trace_list[i].tp_name, name)) {
+ trace_list[i].state = enabled;
+ return true;
+ }
+ }
+ return false;
+}
new file mode 100644
@@ -0,0 +1,14 @@
+#ifndef _STDERRTRACE_H_
+#define _STDERRTRACE_H_
+
+typedef uint64_t TraceEventID;
+
+typedef struct {
+ const char *tp_name;
+ bool state;
+} TraceEvent;
+
+void st_print_trace_events(FILE *stream, fprintf_function stream_printf);
+bool st_change_trace_event_state(const char *name, bool enabled);
+
+#endif /* ! _STDERRTRACE_H_ */
@@ -1966,7 +1966,7 @@ int main(int argc, char **argv, char **envp)
int show_vnc_port = 0;
#endif
int defconfig = 1;
-#if defined(CONFIG_SIMPLE_TRACE)
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
const char *trace_file = NULL;
const char *trace_events_file = NULL;
#endif
@@ -2762,7 +2762,7 @@ int main(int argc, char **argv, char **envp)
}
xen_mode = XEN_ATTACH;
break;
-#if defined(CONFIG_SIMPLE_TRACE)
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
case QEMU_OPTION_trace:
opts = qemu_opts_parse(qemu_find_opts("trace"), optarg, 0);
if (opts) {
@@ -2820,6 +2820,13 @@ int main(int argc, char **argv, char **envp)
if (!st_init(trace_file)) {
fprintf(stderr, "warning: unable to initialize simple trace backend\n");
}
+#else
+ if (trace_file) {
+ fprintf(stderr, "option \"-trace file=\" not supported\n");
+ exit(1);
+ }
+#endif
+#if defined(CONFIG_SIMPLE_TRACE) || defined(CONFIG_STDERR_TRACE)
if (trace_events_file) {
FILE *trace_events_fp = fopen(trace_events_file, "r");
if (!trace_events_fp) {