1. Build with the 'simple' trace backend:
- ./configure --enable-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:
- ./scripts/simpletrace.py trace-events trace-*
+ ./scripts/simpletrace.py trace-events trace-* # Override * with QEMU <pid>
== Trace events ==
SystemTap. Support for trace backends can be added by extending the "tracetool"
script.
-The trace backend is chosen at configure time and only one trace backend can
-be built into the binary:
+The trace backends are chosen at configure time:
- ./configure --trace-backend=simple
+ ./configure --enable-trace-backends=simple
For a list of supported trace backends, try ./configure --help or see below.
+If multiple backends are enabled, the trace is sent to them all.
The following subsections describe the supported trace backends.
trace backends but it is portable. This is the recommended trace backend
unless you have specific needs for more advanced backends.
-The "simple" backend currently does not capture string arguments, it simply
-records the char* pointer value instead of the string that is pointed to.
-
=== Ftrace ===
The "ftrace" backend writes trace data to ftrace marker. This effectively
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
performed manually after a build in order to change the binary name in the .stp
probes:
- scripts/tracetool --dtrace --stap \
- --binary path/to/qemu-binary \
- --target-type system \
- --target-name x86_64 \
- <trace-events >qemu.stp
+ scripts/tracetool.py --backends=dtrace --format=stap \
+ --binary path/to/qemu-binary \
+ --target-type system \
+ --target-name x86_64 \
+ <trace-events >qemu.stp
== Trace event properties ==
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).
+
+=== "tcg" ===
+
+Guest code generated by TCG can be traced by defining an event with the "tcg"
+event property. Internally, this property generates two events:
+"<eventname>_trans" to trace the event at translation time, and
+"<eventname>_exec" to trace the event at execution time.
+
+Instead of using these two events, you should instead use the function
+"trace_<eventname>_tcg" during translation (TCG code generation). This function
+will automatically call "trace_<eventname>_trans", and will generate the
+necessary TCG code to call "trace_<eventname>_exec" during guest code execution.
+
+Events with the "tcg" property can be declared in the "trace-events" file with a
+mix of native and TCG types, and "trace_<eventname>_tcg" will gracefully forward
+them to the "<eventname>_trans" and "<eventname>_exec" events. Since TCG values
+are not known at translation time, these are ignored by the "<eventname>_trans"
+event. Because of this, the entry in the "trace-events" file needs two printing
+formats (separated by a comma):
+
+ tcg foo(uint8_t a1, TCGv_i32 a2) "a1=%d", "a1=%d a2=%d"
+
+For example:
+
+ #include "trace-tcg.h"
+
+ void some_disassembly_func (...)
+ {
+ uint8_t a1 = ...;
+ TCGv_i32 a2 = ...;
+ trace_foo_tcg(a1, a2);
+ }
+
+This will immediately call:
+
+ void trace_foo_trans(uint8_t a1);
+
+and will generate the TCG code to call:
+
+ void trace_foo(uint8_t a1, uint32_t a2);
+
+=== "vcpu" ===
+
+Identifies events that trace vCPU-specific information. It implicitly adds a
+"CPUState*" argument, and extends the tracing print format to show the vCPU
+information. If used together with the "tcg" property, it adds a second
+"TCGv_env" argument that must point to the per-target global TCG register that
+points to the vCPU when guest code is executed (usually the "cpu_env" variable).
+
+The following example events:
+
+ foo(uint32_t a) "a=%x"
+ vcpu bar(uint32_t a) "a=%x"
+ tcg vcpu baz(uint32_t a) "a=%x", "a=%x"
+
+Can be used as:
+
+ #include "trace-tcg.h"
+
+ CPUArchState *env;
+ TCGv_ptr cpu_env;
+
+ void some_disassembly_func(...)
+ {
+ /* trace emitted at this point */
+ trace_foo(0xd1);
+ /* trace emitted at this point */
+ trace_bar(ENV_GET_CPU(env), 0xd2);
+ /* trace emitted at this point (env) and when guest code is executed (cpu_env) */
+ trace_baz_tcg(ENV_GET_CPU(env), cpu_env, 0xd3);
+ }
+
+If the translating vCPU has address 0xc1 and code is later executed by vCPU
+0xc2, this would be an example output:
+
+ // at guest code translation
+ foo a=0xd1
+ bar cpu=0xc1 a=0xd2
+ baz_trans cpu=0xc1 a=0xd3
+ // at guest code execution
+ baz_exec cpu=0xc2 a=0xd3