1. Build with the 'simple' trace backend:
- ./configure --trace-backend=simple
+ ./configure --enable-trace-backends=simple
make
2. Create a file with the events you want to trace:
4. Pretty-print the binary trace file:
- ./simpletrace.py trace-events trace-*
+ ./scripts/simpletrace.py trace-events trace-*
== Trace events ==
4. Name trace events after their function. If there are multiple trace events
in one function, append a unique distinguisher at the end of the name.
-5. If specific trace events are going to be called a huge number of times, this
- might have a noticeable performance impact even when the trace events are
- programmatically disabled. In this case you should declare the trace event
- with the "disable" property, which will effectively disable it at compile
- time (using the "nop" backend).
-
== Generic interface and monitor commands ==
-You can programmatically query and control the dynamic state of trace events
-through a backend-agnostic interface:
-
-* trace_print_events
+You can programmatically query and control the state of trace events through a
+backend-agnostic interface provided by the header "trace/control.h".
-* trace_event_set_state
- Enables or disables trace events at runtime inside QEMU.
- The function returns "true" if the state of the event has been successfully
- changed, or "false" otherwise:
-
- #include "trace/control.h"
-
- trace_event_set_state("virtio_irq", true); /* enable */
- [...]
- trace_event_set_state("virtio_irq", false); /* disable */
+Note that some of the backends do not provide an implementation for some parts
+of this interface, in which case QEMU will just print a warning (please refer to
+header "trace/control.h" to see which routines are backend-dependent).
-Note that some of the backends do not provide an implementation for this
-interface, in which case QEMU will just print a warning.
-
-This functionality is also provided through monitor commands:
+The state of events can also be queried and modified through monitor commands:
* info trace-events
View available trace events and their state. State 1 means enabled, state 0
means disabled.
* trace-event NAME on|off
- Enable/disable a given trace event.
+ Enable/disable a given trace event or a group of events (using wildcards).
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.
+If a line in the "-trace events=<file>" file begins with a '-', the trace event
+will be disabled instead of enabled. This is useful when a wildcard was used
+to enable an entire family of events but one noisy event needs to be disabled.
+
+Wildcard matching is supported in both the monitor command "trace-event" and the
+events list file. That means you can enable/disable the events having a common
+prefix in a batch. For example, virtio-blk trace events could be enabled using
+the following monitor command:
+
+ trace-event virtio_blk_* on
+
== Trace backends ==
The "tracetool" script automates tedious trace event code generation and also
The trace backend is chosen at configure time and only one trace backend can
be built into the binary:
- ./configure --trace-backend=simple
+ ./configure --trace-backends=simple
For a list of supported trace backends, try ./configure --help or see below.
The "simple" backend currently does not capture string arguments, it simply
records the char* pointer value instead of the string that is pointed to.
-==== Monitor commands ====
+=== Ftrace ===
+
+The "ftrace" backend writes trace data to ftrace marker. This effectively
+sends trace events to ftrace ring buffer, and you can compare qemu trace
+data and kernel(especially kvm.ko when using KVM) trace data.
+
+if you use KVM, enable kvm events in ftrace:
+
+ # echo 1 > /sys/kernel/debug/tracing/events/kvm/enable
+
+After running qemu by root user, you can get the trace:
-* info trace
- Display the contents of trace buffer. This command dumps the trace buffer
- with simple formatting. For full pretty-printing, use the simpletrace.py
- script on a binary trace file.
+ # cat /sys/kernel/debug/tracing/trace
- The trace buffer is written into until full. The full trace buffer is
- flushed and emptied. This means the 'info trace' will display few or no
- entries if the buffer has just been flushed.
+Restriction: "ftrace" backend is restricted to Linux only.
+
+==== Monitor commands ====
* trace-file on|off|flush|set <path>
Enable/disable/flush the trace file or set the trace file name.
simpletrace.py script. The script takes the "trace-events" file and the binary
trace:
- ./simpletrace.py trace-events trace-12345
+ ./scripts/simpletrace.py trace-events trace-12345
You must ensure that the same "trace-events" file was used to build QEMU,
otherwise trace event declarations may have changed and output will not be
monitor commands built into QEMU, instead UST utilities should be used to list,
enable/disable, and dump traces.
+Package lttng-tools is required for userspace tracing. You must ensure that the
+current user belongs to the "tracing" group, or manually launch the
+lttng-sessiond daemon for the current user prior to running any instance of
+QEMU.
+
+While running an instrumented QEMU, LTTng should be able to list all available
+events:
+
+ lttng list -u
+
+Create tracing session:
+
+ lttng create mysession
+
+Enable events:
+
+ lttng enable-event qemu:g_malloc -u
+
+Where the events can either be a comma-separated list of events, or "-a" to
+enable all tracepoint events. Start and stop tracing as needed:
+
+ lttng start
+ lttng stop
+
+View the trace:
+
+ lttng view
+
+Destroy tracing session:
+
+ lttng destroy
+
+Babeltrace can be used at any later time to view the trace:
+
+ babeltrace $HOME/lttng-traces/mysession-<date>-<time>
+
=== SystemTap ===
The "dtrace" backend uses DTrace sdt probes but has only been tested with
scripts/tracetool --dtrace --stap \
--binary path/to/qemu-binary \
--target-type system \
- --target-arch x86_64 \
+ --target-name x86_64 \
<trace-events >qemu.stp
+
+== Trace event properties ==
+
+Each event in the "trace-events" file can be prefixed with a space-separated
+list of zero or more of the following event properties.
+
+=== "disable" ===
+
+If a specific trace event is going to be invoked a huge number of times, this
+might have a noticeable performance impact even when the event is
+programmatically disabled.
+
+In this case you should declare such event with the "disable" property. This
+will effectively disable the event at compile time (by using the "nop" backend),
+thus having no performance impact at all on regular builds (i.e., unless you
+edit the "trace-events" file).
+
+In addition, there might be cases where relatively complex computations must be
+performed to generate values that are only used as arguments for a trace
+function. In these cases you can use the macro 'TRACE_${EVENT_NAME}_ENABLED' to
+guard such computations and avoid its compilation when the event is disabled:
+
+ #include "trace.h" /* needed for trace event prototype */
+
+ void *qemu_vmalloc(size_t size)
+ {
+ void *ptr;
+ size_t align = QEMU_VMALLOC_ALIGN;
+
+ if (size < align) {
+ align = getpagesize();
+ }
+ ptr = qemu_memalign(align, size);
+ if (TRACE_QEMU_VMALLOC_ENABLED) { /* preprocessor macro */
+ void *complex;
+ /* some complex computations to produce the 'complex' value */
+ trace_qemu_vmalloc(size, ptr, complex);
+ }
+ return ptr;
+ }
+
+You can check both if the event has been disabled and is dynamically enabled at
+the same time using the 'trace_event_get_state' routine (see header
+"trace/control.h" for more information).