Revision 81a97d9d
b/docs/tracing.txt | ||
---|---|---|
1 |
= Tracing = |
|
2 |
|
|
3 |
== Introduction == |
|
4 |
|
|
5 |
This document describes the tracing infrastructure in QEMU and how to use it |
|
6 |
for debugging, profiling, and observing execution. |
|
7 |
|
|
8 |
== Quickstart == |
|
9 |
|
|
10 |
1. Build with the 'simple' trace backend: |
|
11 |
|
|
12 |
./configure --trace-backend=simple |
|
13 |
make |
|
14 |
|
|
15 |
2. Enable trace events you are interested in: |
|
16 |
|
|
17 |
$EDITOR trace-events # remove "disable" from events you want |
|
18 |
|
|
19 |
3. Run the virtual machine to produce a trace file: |
|
20 |
|
|
21 |
qemu ... # your normal QEMU invocation |
|
22 |
|
|
23 |
4. Pretty-print the binary trace file: |
|
24 |
|
|
25 |
./simpletrace.py trace-events trace-* |
|
26 |
|
|
27 |
== Trace events == |
|
28 |
|
|
29 |
There is a set of static trace events declared in the trace-events source |
|
30 |
file. Each trace event declaration names the event, its arguments, and the |
|
31 |
format string which can be used for pretty-printing: |
|
32 |
|
|
33 |
qemu_malloc(size_t size, void *ptr) "size %zu ptr %p" |
|
34 |
qemu_free(void *ptr) "ptr %p" |
|
35 |
|
|
36 |
The trace-events file is processed by the tracetool script during build to |
|
37 |
generate code for the trace events. Trace events are invoked directly from |
|
38 |
source code like this: |
|
39 |
|
|
40 |
#include "trace.h" /* needed for trace event prototype */ |
|
41 |
|
|
42 |
void *qemu_malloc(size_t size) |
|
43 |
{ |
|
44 |
void *ptr; |
|
45 |
if (!size && !allow_zero_malloc()) { |
|
46 |
abort(); |
|
47 |
} |
|
48 |
ptr = oom_check(malloc(size ? size : 1)); |
|
49 |
trace_qemu_malloc(size, ptr); /* <-- trace event */ |
|
50 |
return ptr; |
|
51 |
} |
|
52 |
|
|
53 |
=== Declaring trace events === |
|
54 |
|
|
55 |
The tracetool script produces the trace.h header file which is included by |
|
56 |
every source file that uses trace events. Since many source files include |
|
57 |
trace.h, it uses a minimum of types and other header files included to keep |
|
58 |
the namespace clean and compile times and dependencies down. |
|
59 |
|
|
60 |
Trace events should use types as follows: |
|
61 |
|
|
62 |
* Use stdint.h types for fixed-size types. Most offsets and guest memory |
|
63 |
addresses are best represented with uint32_t or uint64_t. Use fixed-size |
|
64 |
types over primitive types whose size may change depending on the host |
|
65 |
(32-bit versus 64-bit) so trace events don't truncate values or break |
|
66 |
the build. |
|
67 |
|
|
68 |
* Use void * for pointers to structs or for arrays. The trace.h header |
|
69 |
cannot include all user-defined struct declarations and it is therefore |
|
70 |
necessary to use void * for pointers to structs. |
|
71 |
|
|
72 |
* For everything else, use primitive scalar types (char, int, long) with the |
|
73 |
appropriate signedness. |
|
74 |
|
|
75 |
=== Hints for adding new trace events === |
|
76 |
|
|
77 |
1. Trace state changes in the code. Interesting points in the code usually |
|
78 |
involve a state change like starting, stopping, allocating, freeing. State |
|
79 |
changes are good trace events because they can be used to understand the |
|
80 |
execution of the system. |
|
81 |
|
|
82 |
2. Trace guest operations. Guest I/O accesses like reading device registers |
|
83 |
are good trace events because they can be used to understand guest |
|
84 |
interactions. |
|
85 |
|
|
86 |
3. Use correlator fields so the context of an individual line of trace output |
|
87 |
can be understood. For example, trace the pointer returned by malloc and |
|
88 |
used as an argument to free. This way mallocs and frees can be matched up. |
|
89 |
Trace events with no context are not very useful. |
|
90 |
|
|
91 |
4. Name trace events after their function. If there are multiple trace events |
|
92 |
in one function, append a unique distinguisher at the end of the name. |
|
93 |
|
|
94 |
5. Declare trace events with the "disable" keyword. Some trace events can |
|
95 |
produce a lot of output and users are typically only interested in a subset |
|
96 |
of trace events. Marking trace events disabled by default saves the user |
|
97 |
from having to manually disable noisy trace events. |
|
98 |
|
|
99 |
== Trace backends == |
|
100 |
|
|
101 |
The tracetool script automates tedious trace event code generation and also |
|
102 |
keeps the trace event declarations independent of the trace backend. The trace |
|
103 |
events are not tightly coupled to a specific trace backend, such as LTTng or |
|
104 |
SystemTap. Support for trace backends can be added by extending the tracetool |
|
105 |
script. |
|
106 |
|
|
107 |
The trace backend is chosen at configure time and only one trace backend can |
|
108 |
be built into the binary: |
|
109 |
|
|
110 |
./configure --trace-backend=simple |
|
111 |
|
|
112 |
For a list of supported trace backends, try ./configure --help or see below. |
|
113 |
|
|
114 |
The following subsections describe the supported trace backends. |
|
115 |
|
|
116 |
=== Nop === |
|
117 |
|
|
118 |
The "nop" backend generates empty trace event functions so that the compiler |
|
119 |
can optimize out trace events completely. This is the default and imposes no |
|
120 |
performance penalty. |
|
121 |
|
|
122 |
=== Simpletrace === |
|
123 |
|
|
124 |
The "simple" backend supports common use cases and comes as part of the QEMU |
|
125 |
source tree. It may not be as powerful as platform-specific or third-party |
|
126 |
trace backends but it is portable. This is the recommended trace backend |
|
127 |
unless you have specific needs for more advanced backends. |
|
128 |
|
|
129 |
==== Monitor commands ==== |
|
130 |
|
|
131 |
* info trace |
|
132 |
Display the contents of trace buffer. This command dumps the trace buffer |
|
133 |
with simple formatting. For full pretty-printing, use the simpletrace.py |
|
134 |
script on a binary trace file. |
|
135 |
|
|
136 |
The trace buffer is written into until full. The full trace buffer is |
|
137 |
flushed and emptied. This means the 'info trace' will display few or no |
|
138 |
entries if the buffer has just been flushed. |
|
139 |
|
|
140 |
* info trace-events |
|
141 |
View available trace events and their state. State 1 means enabled, state 0 |
|
142 |
means disabled. |
|
143 |
|
|
144 |
* trace-event NAME on|off |
|
145 |
Enable/disable a given trace event. |
|
146 |
|
|
147 |
* trace-file on|off|flush|set <path> |
|
148 |
Enable/disable/flush the trace file or set the trace file name. |
|
149 |
|
|
150 |
==== Enabling/disabling trace events programmatically ==== |
|
151 |
|
|
152 |
The st_change_trace_event_state() function can be used to enable or disable trace |
|
153 |
events at runtime inside QEMU: |
|
154 |
|
|
155 |
#include "trace.h" |
|
156 |
|
|
157 |
st_change_trace_event_state("virtio_irq", true); /* enable */ |
|
158 |
[...] |
|
159 |
st_change_trace_event_state("virtio_irq", false); /* disable */ |
|
160 |
|
|
161 |
==== Analyzing trace files ==== |
|
162 |
|
|
163 |
The "simple" backend produces binary trace files that can be formatted with the |
|
164 |
simpletrace.py script. The script takes the trace-events file and the binary |
|
165 |
trace: |
|
166 |
|
|
167 |
./simpletrace.py trace-events trace-12345 |
|
168 |
|
|
169 |
You must ensure that the same trace-events file was used to build QEMU, |
|
170 |
otherwise trace event declarations may have changed and output will not be |
|
171 |
consistent. |
|
172 |
|
|
173 |
=== LTTng Userspace Tracer === |
|
174 |
|
|
175 |
The "ust" backend uses the LTTng Userspace Tracer library. There are no |
|
176 |
monitor commands built into QEMU, instead UST utilities should be used to list, |
|
177 |
enable/disable, and dump traces. |
Also available in: Unified diff