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