]> git.proxmox.com Git - qemu.git/commitdiff
trace: add "-trace events" argument to control initial state
authorLluís <xscript@gmx.net>
Wed, 31 Aug 2011 18:31:31 +0000 (20:31 +0200)
committerStefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Thu, 1 Sep 2011 09:34:54 +0000 (10:34 +0100)
The "-trace events" argument can be used to provide a file with a list of trace
event names that will be enabled prior to starting execution, thus providing
early tracing.

This saves the user from manually toggling event states through the monitor
interface or whichever backend-specific interface.

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Makefile.objs
docs/tracing.txt
qemu-config.c
qemu-options.hx
trace/control.c [new file with mode: 0644]
trace/control.h
trace/default.c
trace/simple.c
vl.c

index 57a80e613054e6e5d2dd96fa49bd75bd9063d5ac..036a4eb6abe5820b9747ac53265e1244cde5677f 100644 (file)
@@ -384,6 +384,8 @@ trace-nested-$(CONFIG_TRACE_DEFAULT) += default.o
 trace-nested-$(CONFIG_TRACE_SIMPLE) += simple.o
 trace-obj-$(CONFIG_TRACE_SIMPLE) += qemu-timer-common.o
 
+trace-nested-y += control.o
+
 trace-obj-y += $(addprefix trace/, $(trace-nested-y))
 
 ######################################################################
index 41eb8e6fec1e670624a33fe223e558d7857d7bcf..455da37969ee42d058687f333540b335f30d3ace 100644 (file)
@@ -138,6 +138,10 @@ This functionality is also provided through monitor commands:
 * trace-event NAME on|off
   Enable/disable a given trace event.
 
+The "-trace events=<file>" command line argument can be used to enable the
+events listed in <file> from the very beginning of the program. This file must
+contain one event name per line.
+
 == Trace backends ==
 
 The "tracetool" script automates tedious trace event code generation and also
index 4f3465d384306b5cc9ae01cfe01a6eb7634b0e29..7a7854fd06ff92cf4a41dc498634f9b95e3d70c5 100644 (file)
@@ -309,6 +309,9 @@ static QemuOptsList qemu_trace_opts = {
     .head = QTAILQ_HEAD_INITIALIZER(qemu_trace_opts.head),
     .desc = {
         {
+            .name = "events",
+            .type = QEMU_OPT_STRING,
+        },{
             .name = "file",
             .type = QEMU_OPT_STRING,
         },
index 2d29933ab1727d1b0df822faa700c8959402fd26..edd181bb8e920345b8439e4920c7d3e068b7b1cb 100644 (file)
@@ -2437,17 +2437,29 @@ Normally QEMU loads a configuration file from @var{sysconfdir}/qemu.conf and
 option will prevent QEMU from loading these configuration files at startup.
 ETEXI
 DEF("trace", HAS_ARG, QEMU_OPTION_trace,
-    "-trace\n"
-    "                Specify a trace file to log traces to\n",
+    "-trace [events=<file>][,file=<file>]\n"
+    "                specify tracing options\n",
     QEMU_ARCH_ALL)
 STEXI
-HXCOMM This line is not accurate, as the option is backend-specific but HX does
-HXCOMM not support conditional compilation of text.
-@item -trace
+HXCOMM This line is not accurate, as some sub-options are backend-specific but
+HXCOMM HX does not support conditional compilation of text.
+@item -trace [events=@var{file}][,file=@var{file}]
 @findex -trace
-Specify a trace file to log output traces to.
 
-This option is available only when using the @var{simple} tracing backend.
+Specify tracing options.
+
+@table @option
+@item events=@var{file}
+Immediately enable events listed in @var{file}.
+The file must contain one event name (as listed in the @var{trace-events} file)
+per line.
+
+This option is only available when using the @var{simple} tracing backend.
+@item file=@var{file}
+Log output traces to @var{file}.
+
+This option is only available when using the @var{simple} tracing backend.
+@end table
 ETEXI
 
 HXCOMM This is the last statement. Insert new options before this line!
diff --git a/trace/control.c b/trace/control.c
new file mode 100644 (file)
index 0000000..4c5527d
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Interface for configuring and controlling the state of tracing events.
+ *
+ * Copyright (C) 2011 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_backend_init_events(const char *fname)
+{
+    if (fname == NULL) {
+        return;
+    }
+
+    FILE *fp = fopen(fname, "r");
+    if (!fp) {
+        fprintf(stderr, "error: could not open trace events file '%s': %s\n",
+                fname, strerror(errno));
+        exit(1);
+    }
+    char line_buf[1024];
+    while (fgets(line_buf, sizeof(line_buf), fp)) {
+        size_t len = strlen(line_buf);
+        if (len > 1) {              /* skip empty lines */
+            line_buf[len - 1] = '\0';
+            if (!trace_event_set_state(line_buf, true)) {
+                fprintf(stderr,
+                        "error: trace event '%s' does not exist\n", line_buf);
+                exit(1);
+            }
+        }
+    }
+    if (fclose(fp) != 0) {
+        fprintf(stderr, "error: closing file '%s': %s\n",
+                fname, strerror(errno));
+        exit(1);
+    }
+}
index c99b4d50a8ba0296680a4df244b5602824798e77..2acaa4290e82cc3d37bae547563d9f321bedb671 100644 (file)
@@ -24,10 +24,18 @@ bool trace_event_set_state(const char *name, bool state);
 
 /** Initialize the tracing backend.
  *
- * @file Name of trace output file; may be NULL.
- *       Corresponds to commandline option "-trace file=...".
+ * @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=...".
  * @return Whether the backend could be successfully initialized.
  */
-bool trace_backend_init(const char *file);
+bool trace_backend_init(const char *events, const char *file);
+
+/** Generic function to initialize the state of events.
+ *
+ * @fname Name of file with events to enable; may be NULL.
+ */
+void trace_backend_init_events(const char *fname);
 
 #endif  /* TRACE_CONTROL_H */
index 3573d5b296d5fc7ce7e90de4c0a369f13d009e8a..c9b27a289ba9ba8063406e58af4a637a9cb64fec 100644 (file)
@@ -25,8 +25,13 @@ bool trace_event_set_state(const char *name, bool state)
     return false;
 }
 
-bool trace_backend_init(const char *file)
+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");
index 70689e9484ae2e47c56432b06abb0ce5cc77a117..a6093682dd338b9e8e3859c0436ef0dae7ca4066 100644 (file)
@@ -331,7 +331,7 @@ bool trace_event_set_state(const char *name, bool state)
     return false;
 }
 
-bool trace_backend_init(const char *file)
+bool trace_backend_init(const char *events, const char *file)
 {
     pthread_t thread;
     pthread_attr_t attr;
@@ -350,6 +350,7 @@ bool trace_backend_init(const char *file)
         fprintf(stderr, "warning: unable to initialize simple trace backend\n");
     } else {
         atexit(st_flush_trace_buffer);
+        trace_backend_init_events(events);
         st_set_trace_file(file);
     }
 
diff --git a/vl.c b/vl.c
index 60322b62a4eeb3b4ef531f9e58c4e1d01f03b40d..c6dc6895b4303d61ac611dffe741e17f5f1a5af7 100644 (file)
--- a/vl.c
+++ b/vl.c
@@ -2137,6 +2137,7 @@ int main(int argc, char **argv, char **envp)
         .realloc = realloc_and_trace,
         .free = free_and_trace,
     };
+    const char *trace_events = NULL;
     const char *trace_file = NULL;
 
     atexit(qemu_run_exit_notifiers);
@@ -2934,6 +2935,7 @@ int main(int argc, char **argv, char **envp)
                 if (!opts) {
                     exit(1);
                 }
+                trace_events = qemu_opt_get(opts, "events");
                 trace_file = qemu_opt_get(opts, "file");
                 break;
             }
@@ -2994,7 +2996,7 @@ int main(int argc, char **argv, char **envp)
         set_cpu_log(log_mask);
     }
 
-    if (!trace_backend_init(trace_file)) {
+    if (!trace_backend_init(trace_events, trace_file)) {
         exit(1);
     }