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
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