root / docs / tracing.txt @ 0b5538c3
History | View | Annotate | Download (7.4 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 | 81a97d9d | Stefan Hajnoczi | 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 | 81a97d9d | Stefan Hajnoczi | 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 | 81a97d9d | Stefan Hajnoczi | 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 | 81a97d9d | Stefan Hajnoczi | trace.h, it uses a minimum of types and other header files included to keep |
58 | 81a97d9d | Stefan Hajnoczi | the 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 | 81a97d9d | Stefan Hajnoczi | * For everything else, use primitive scalar types (char, int, long) with the |
73 | 81a97d9d | Stefan Hajnoczi | appropriate signedness. |
74 | 81a97d9d | Stefan Hajnoczi | |
75 | 9a85d394 | Stefan Hajnoczi | Format strings should reflect the types defined in the trace event. Take |
76 | 9a85d394 | Stefan Hajnoczi | special care to use PRId64 and PRIu64 for int64_t and uint64_t types, |
77 | cf85cf8e | Stefan Hajnoczi | respectively. This ensures portability between 32- and 64-bit platforms. Note |
78 | cf85cf8e | Stefan Hajnoczi | that format strings must begin and end with double quotes. When using |
79 | cf85cf8e | Stefan Hajnoczi | portability macros, ensure they are preceded and followed by double quotes: |
80 | cf85cf8e | Stefan Hajnoczi | "value %"PRIx64"". |
81 | 9a85d394 | Stefan Hajnoczi | |
82 | 81a97d9d | Stefan Hajnoczi | === Hints for adding new trace events === |
83 | 81a97d9d | Stefan Hajnoczi | |
84 | 81a97d9d | Stefan Hajnoczi | 1. Trace state changes in the code. Interesting points in the code usually |
85 | 81a97d9d | Stefan Hajnoczi | involve a state change like starting, stopping, allocating, freeing. State |
86 | 81a97d9d | Stefan Hajnoczi | changes are good trace events because they can be used to understand the |
87 | 81a97d9d | Stefan Hajnoczi | execution of the system. |
88 | 81a97d9d | Stefan Hajnoczi | |
89 | 81a97d9d | Stefan Hajnoczi | 2. Trace guest operations. Guest I/O accesses like reading device registers |
90 | 81a97d9d | Stefan Hajnoczi | are good trace events because they can be used to understand guest |
91 | 81a97d9d | Stefan Hajnoczi | interactions. |
92 | 81a97d9d | Stefan Hajnoczi | |
93 | 81a97d9d | Stefan Hajnoczi | 3. Use correlator fields so the context of an individual line of trace output |
94 | 81a97d9d | Stefan Hajnoczi | can be understood. For example, trace the pointer returned by malloc and |
95 | 81a97d9d | Stefan Hajnoczi | used as an argument to free. This way mallocs and frees can be matched up. |
96 | 81a97d9d | Stefan Hajnoczi | Trace events with no context are not very useful. |
97 | 81a97d9d | Stefan Hajnoczi | |
98 | 81a97d9d | Stefan Hajnoczi | 4. Name trace events after their function. If there are multiple trace events |
99 | 81a97d9d | Stefan Hajnoczi | in one function, append a unique distinguisher at the end of the name. |
100 | 81a97d9d | Stefan Hajnoczi | |
101 | 81a97d9d | Stefan Hajnoczi | 5. Declare trace events with the "disable" keyword. Some trace events can |
102 | 81a97d9d | Stefan Hajnoczi | produce a lot of output and users are typically only interested in a subset |
103 | 81a97d9d | Stefan Hajnoczi | of trace events. Marking trace events disabled by default saves the user |
104 | 81a97d9d | Stefan Hajnoczi | from having to manually disable noisy trace events. |
105 | 81a97d9d | Stefan Hajnoczi | |
106 | 81a97d9d | Stefan Hajnoczi | == Trace backends == |
107 | 81a97d9d | Stefan Hajnoczi | |
108 | 81a97d9d | Stefan Hajnoczi | The tracetool script automates tedious trace event code generation and also |
109 | 81a97d9d | Stefan Hajnoczi | keeps the trace event declarations independent of the trace backend. The trace |
110 | 81a97d9d | Stefan Hajnoczi | events are not tightly coupled to a specific trace backend, such as LTTng or |
111 | 81a97d9d | Stefan Hajnoczi | SystemTap. Support for trace backends can be added by extending the tracetool |
112 | 81a97d9d | Stefan Hajnoczi | script. |
113 | 81a97d9d | Stefan Hajnoczi | |
114 | 81a97d9d | Stefan Hajnoczi | The trace backend is chosen at configure time and only one trace backend can |
115 | 81a97d9d | Stefan Hajnoczi | be built into the binary: |
116 | 81a97d9d | Stefan Hajnoczi | |
117 | 81a97d9d | Stefan Hajnoczi | ./configure --trace-backend=simple |
118 | 81a97d9d | Stefan Hajnoczi | |
119 | 81a97d9d | Stefan Hajnoczi | For a list of supported trace backends, try ./configure --help or see below. |
120 | 81a97d9d | Stefan Hajnoczi | |
121 | 81a97d9d | Stefan Hajnoczi | The following subsections describe the supported trace backends. |
122 | 81a97d9d | Stefan Hajnoczi | |
123 | 81a97d9d | Stefan Hajnoczi | === Nop === |
124 | 81a97d9d | Stefan Hajnoczi | |
125 | 81a97d9d | Stefan Hajnoczi | The "nop" backend generates empty trace event functions so that the compiler |
126 | 81a97d9d | Stefan Hajnoczi | can optimize out trace events completely. This is the default and imposes no |
127 | 81a97d9d | Stefan Hajnoczi | performance penalty. |
128 | 81a97d9d | Stefan Hajnoczi | |
129 | b48c20f7 | Stefan Hajnoczi | === Stderr === |
130 | b48c20f7 | Stefan Hajnoczi | |
131 | b48c20f7 | Stefan Hajnoczi | The "stderr" backend sends trace events directly to standard error. This |
132 | b48c20f7 | Stefan Hajnoczi | effectively turns trace events into debug printfs. |
133 | b48c20f7 | Stefan Hajnoczi | |
134 | b48c20f7 | Stefan Hajnoczi | This is the simplest backend and can be used together with existing code that |
135 | b48c20f7 | Stefan Hajnoczi | uses DPRINTF(). |
136 | b48c20f7 | Stefan Hajnoczi | |
137 | 81a97d9d | Stefan Hajnoczi | === Simpletrace === |
138 | 81a97d9d | Stefan Hajnoczi | |
139 | 81a97d9d | Stefan Hajnoczi | The "simple" backend supports common use cases and comes as part of the QEMU |
140 | 81a97d9d | Stefan Hajnoczi | source tree. It may not be as powerful as platform-specific or third-party |
141 | 81a97d9d | Stefan Hajnoczi | trace backends but it is portable. This is the recommended trace backend |
142 | 81a97d9d | Stefan Hajnoczi | unless you have specific needs for more advanced backends. |
143 | 81a97d9d | Stefan Hajnoczi | |
144 | 81a97d9d | Stefan Hajnoczi | ==== Monitor commands ==== |
145 | 81a97d9d | Stefan Hajnoczi | |
146 | 81a97d9d | Stefan Hajnoczi | * info trace |
147 | 81a97d9d | Stefan Hajnoczi | Display the contents of trace buffer. This command dumps the trace buffer |
148 | 81a97d9d | Stefan Hajnoczi | with simple formatting. For full pretty-printing, use the simpletrace.py |
149 | 81a97d9d | Stefan Hajnoczi | script on a binary trace file. |
150 | 81a97d9d | Stefan Hajnoczi | |
151 | 81a97d9d | Stefan Hajnoczi | The trace buffer is written into until full. The full trace buffer is |
152 | 81a97d9d | Stefan Hajnoczi | flushed and emptied. This means the 'info trace' will display few or no |
153 | 81a97d9d | Stefan Hajnoczi | entries if the buffer has just been flushed. |
154 | 81a97d9d | Stefan Hajnoczi | |
155 | 81a97d9d | Stefan Hajnoczi | * info trace-events |
156 | 81a97d9d | Stefan Hajnoczi | View available trace events and their state. State 1 means enabled, state 0 |
157 | 81a97d9d | Stefan Hajnoczi | means disabled. |
158 | 81a97d9d | Stefan Hajnoczi | |
159 | 81a97d9d | Stefan Hajnoczi | * trace-event NAME on|off |
160 | 81a97d9d | Stefan Hajnoczi | Enable/disable a given trace event. |
161 | 81a97d9d | Stefan Hajnoczi | |
162 | 81a97d9d | Stefan Hajnoczi | * trace-file on|off|flush|set <path> |
163 | 81a97d9d | Stefan Hajnoczi | Enable/disable/flush the trace file or set the trace file name. |
164 | 81a97d9d | Stefan Hajnoczi | |
165 | 81a97d9d | Stefan Hajnoczi | ==== Enabling/disabling trace events programmatically ==== |
166 | 81a97d9d | Stefan Hajnoczi | |
167 | 81a97d9d | Stefan Hajnoczi | The st_change_trace_event_state() function can be used to enable or disable trace |
168 | 81a97d9d | Stefan Hajnoczi | events at runtime inside QEMU: |
169 | 81a97d9d | Stefan Hajnoczi | |
170 | 81a97d9d | Stefan Hajnoczi | #include "trace.h" |
171 | 81a97d9d | Stefan Hajnoczi | |
172 | 81a97d9d | Stefan Hajnoczi | st_change_trace_event_state("virtio_irq", true); /* enable */ |
173 | 81a97d9d | Stefan Hajnoczi | [...] |
174 | 81a97d9d | Stefan Hajnoczi | st_change_trace_event_state("virtio_irq", false); /* disable */ |
175 | 81a97d9d | Stefan Hajnoczi | |
176 | 81a97d9d | Stefan Hajnoczi | ==== Analyzing trace files ==== |
177 | 81a97d9d | Stefan Hajnoczi | |
178 | 81a97d9d | Stefan Hajnoczi | The "simple" backend produces binary trace files that can be formatted with the |
179 | 81a97d9d | Stefan Hajnoczi | simpletrace.py script. The script takes the trace-events file and the binary |
180 | 81a97d9d | Stefan Hajnoczi | trace: |
181 | 81a97d9d | Stefan Hajnoczi | |
182 | 81a97d9d | Stefan Hajnoczi | ./simpletrace.py trace-events trace-12345 |
183 | 81a97d9d | Stefan Hajnoczi | |
184 | 81a97d9d | Stefan Hajnoczi | You must ensure that the same trace-events file was used to build QEMU, |
185 | 81a97d9d | Stefan Hajnoczi | otherwise trace event declarations may have changed and output will not be |
186 | 81a97d9d | Stefan Hajnoczi | consistent. |
187 | 81a97d9d | Stefan Hajnoczi | |
188 | 81a97d9d | Stefan Hajnoczi | === LTTng Userspace Tracer === |
189 | 81a97d9d | Stefan Hajnoczi | |
190 | 81a97d9d | Stefan Hajnoczi | The "ust" backend uses the LTTng Userspace Tracer library. There are no |
191 | 81a97d9d | Stefan Hajnoczi | monitor commands built into QEMU, instead UST utilities should be used to list, |
192 | 81a97d9d | Stefan Hajnoczi | enable/disable, and dump traces. |
193 | b48c20f7 | Stefan Hajnoczi | |
194 | b48c20f7 | Stefan Hajnoczi | === SystemTap === |
195 | b48c20f7 | Stefan Hajnoczi | |
196 | b48c20f7 | Stefan Hajnoczi | The "dtrace" backend uses DTrace sdt probes but has only been tested with |
197 | b48c20f7 | Stefan Hajnoczi | SystemTap. When SystemTap support is detected a .stp file with wrapper probes |
198 | b48c20f7 | Stefan Hajnoczi | is generated to make use in scripts more convenient. This step can also be |
199 | b48c20f7 | Stefan Hajnoczi | performed manually after a build in order to change the binary name in the .stp |
200 | b48c20f7 | Stefan Hajnoczi | probes: |
201 | b48c20f7 | Stefan Hajnoczi | |
202 | b48c20f7 | Stefan Hajnoczi | scripts/tracetool --dtrace --stap \ |
203 | b48c20f7 | Stefan Hajnoczi | --binary path/to/qemu-binary \ |
204 | b48c20f7 | Stefan Hajnoczi | --target-type system \ |
205 | b48c20f7 | Stefan Hajnoczi | --target-arch x86_64 \ |
206 | b48c20f7 | Stefan Hajnoczi | <trace-events >qemu.stp |