trace: add "-trace events" argument to control initial state
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>
This commit is contained in:
parent
31965ae27b
commit
23d15e860b
@ -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))
|
||||
|
||||
######################################################################
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
},
|
||||
|
@ -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!
|
||||
|
42
trace/control.c
Normal file
42
trace/control.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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 */
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
4
vl.c
4
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user