Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 1 | ======= |
| 2 | Tracing |
| 3 | ======= |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 4 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 5 | Introduction |
| 6 | ============ |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 7 | |
| 8 | This document describes the tracing infrastructure in QEMU and how to use it |
| 9 | for debugging, profiling, and observing execution. |
| 10 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 11 | Quickstart |
| 12 | ========== |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 13 | |
Stefan Hajnoczi | 7e46d5f | 2020-12-16 16:09:23 +0000 | [diff] [blame] | 14 | Enable tracing of ``memory_region_ops_read`` and ``memory_region_ops_write`` |
| 15 | events:: |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 16 | |
Stefan Hajnoczi | 7e46d5f | 2020-12-16 16:09:23 +0000 | [diff] [blame] | 17 | $ qemu --trace "memory_region_ops_*" ... |
| 18 | ... |
| 19 | 719585@1608130130.441188:memory_region_ops_read cpu 0 mr 0x562fdfbb3820 addr 0x3cc value 0x67 size 1 |
| 20 | 719585@1608130130.441190:memory_region_ops_write cpu 0 mr 0x562fdfbd2f00 addr 0x3d4 value 0x70e size 2 |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 21 | |
Stefan Hajnoczi | 7e46d5f | 2020-12-16 16:09:23 +0000 | [diff] [blame] | 22 | This output comes from the "log" trace backend that is enabled by default when |
| 23 | ``./configure --enable-trace-backends=BACKENDS`` was not explicitly specified. |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 24 | |
Stefan Hajnoczi | 3faf22e | 2021-01-12 16:58:58 +0000 | [diff] [blame] | 25 | Multiple patterns can be specified by repeating the ``--trace`` option:: |
| 26 | |
| 27 | $ qemu --trace "kvm_*" --trace "virtio_*" ... |
| 28 | |
| 29 | When patterns are used frequently it is more convenient to store them in a |
| 30 | file to avoid long command-line options:: |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 31 | |
Stefan Hajnoczi | 7e46d5f | 2020-12-16 16:09:23 +0000 | [diff] [blame] | 32 | $ echo "memory_region_ops_*" >/tmp/events |
Stefan Hajnoczi | 3faf22e | 2021-01-12 16:58:58 +0000 | [diff] [blame] | 33 | $ echo "kvm_*" >>/tmp/events |
Stefan Hajnoczi | 7e46d5f | 2020-12-16 16:09:23 +0000 | [diff] [blame] | 34 | $ qemu --trace events=/tmp/events ... |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 35 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 36 | Trace events |
| 37 | ============ |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 38 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 39 | Sub-directory setup |
| 40 | ------------------- |
Daniel P. Berrange | d4fa843 | 2017-01-25 16:14:16 +0000 | [diff] [blame] | 41 | |
Stefan Hajnoczi | 0dfb3ca | 2021-01-12 16:58:59 +0000 | [diff] [blame] | 42 | Each directory in the source tree can declare a set of trace events in a local |
| 43 | "trace-events" file. All directories which contain "trace-events" files must be |
| 44 | listed in the "trace_events_subdirs" variable in the top level meson.build |
| 45 | file. During build, the "trace-events" file in each listed subdirectory will be |
| 46 | processed by the "tracetool" script to generate code for the trace events. |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 47 | |
Daniel P. Berrange | d4fa843 | 2017-01-25 16:14:16 +0000 | [diff] [blame] | 48 | The individual "trace-events" files are merged into a "trace-events-all" file, |
| 49 | which is also installed into "/usr/share/qemu" with the name "trace-events". |
| 50 | This merged file is to be used by the "simpletrace.py" script to later analyse |
| 51 | traces in the simpletrace data format. |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 52 | |
Stefan Hajnoczi | 0dfb3ca | 2021-01-12 16:58:59 +0000 | [diff] [blame] | 53 | The following files are automatically generated in <builddir>/trace/ during the |
| 54 | build: |
Daniel P. Berrange | d4fa843 | 2017-01-25 16:14:16 +0000 | [diff] [blame] | 55 | |
Stefan Hajnoczi | 0dfb3ca | 2021-01-12 16:58:59 +0000 | [diff] [blame] | 56 | - trace-<subdir>.c - the trace event state declarations |
| 57 | - trace-<subdir>.h - the trace event enums and probe functions |
| 58 | - trace-dtrace-<subdir>.h - DTrace event probe specification |
| 59 | - trace-dtrace-<subdir>.dtrace - DTrace event probe helper declaration |
| 60 | - trace-dtrace-<subdir>.o - binary DTrace provider (generated by dtrace) |
| 61 | - trace-ust-<subdir>.h - UST event probe helper declarations |
Daniel P. Berrange | d4fa843 | 2017-01-25 16:14:16 +0000 | [diff] [blame] | 62 | |
Stefan Hajnoczi | 0dfb3ca | 2021-01-12 16:58:59 +0000 | [diff] [blame] | 63 | Here <subdir> is the sub-directory path with '/' replaced by '_'. For example, |
| 64 | "accel/kvm" becomes "accel_kvm" and the final filename for "trace-<subdir>.c" |
| 65 | becomes "trace-accel_kvm.c". |
| 66 | |
| 67 | Source files in the source tree do not directly include generated files in |
| 68 | "<builddir>/trace/". Instead they #include the local "trace.h" file, without |
| 69 | any sub-directory path prefix. eg io/channel-buffer.c would do:: |
Daniel P. Berrange | d4fa843 | 2017-01-25 16:14:16 +0000 | [diff] [blame] | 70 | |
| 71 | #include "trace.h" |
| 72 | |
Stefan Hajnoczi | 0dfb3ca | 2021-01-12 16:58:59 +0000 | [diff] [blame] | 73 | The "io/trace.h" file must be created manually with an #include of the |
| 74 | corresponding "trace/trace-<subdir>.h" file that will be generated in the |
| 75 | builddir:: |
| 76 | |
| 77 | $ echo '#include "trace/trace-io.h"' >io/trace.h |
| 78 | |
| 79 | While it is possible to include a trace.h file from outside a source file's own |
| 80 | sub-directory, this is discouraged in general. It is strongly preferred that |
| 81 | all events be declared directly in the sub-directory that uses them. The only |
| 82 | exception is where there are some shared trace events defined in the top level |
| 83 | directory trace-events file. The top level directory generates trace files |
| 84 | with a filename prefix of "trace/trace-root" instead of just "trace". This is |
| 85 | to avoid ambiguity between a trace.h in the current directory, vs the top level |
| 86 | directory. |
Daniel P. Berrange | d4fa843 | 2017-01-25 16:14:16 +0000 | [diff] [blame] | 87 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 88 | Using trace events |
| 89 | ------------------ |
Daniel P. Berrange | 1412cf5 | 2016-06-16 09:39:47 +0100 | [diff] [blame] | 90 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 91 | Trace events are invoked directly from source code like this:: |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 92 | |
| 93 | #include "trace.h" /* needed for trace event prototype */ |
Lluís | 4992604 | 2011-08-31 20:31:10 +0200 | [diff] [blame] | 94 | |
Lluís Vilanova | 4b710a3 | 2011-09-20 21:03:48 +0200 | [diff] [blame] | 95 | void *qemu_vmalloc(size_t size) |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 96 | { |
| 97 | void *ptr; |
Lluís Vilanova | 4b710a3 | 2011-09-20 21:03:48 +0200 | [diff] [blame] | 98 | size_t align = QEMU_VMALLOC_ALIGN; |
| 99 | |
| 100 | if (size < align) { |
| 101 | align = getpagesize(); |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 102 | } |
Lluís Vilanova | 4b710a3 | 2011-09-20 21:03:48 +0200 | [diff] [blame] | 103 | ptr = qemu_memalign(align, size); |
| 104 | trace_qemu_vmalloc(size, ptr); |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 105 | return ptr; |
| 106 | } |
| 107 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 108 | Declaring trace events |
| 109 | ---------------------- |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 110 | |
Lluís | 7b92e5b | 2011-04-06 20:33:56 +0200 | [diff] [blame] | 111 | The "tracetool" script produces the trace.h header file which is included by |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 112 | every source file that uses trace events. Since many source files include |
Lluís | 7b92e5b | 2011-04-06 20:33:56 +0200 | [diff] [blame] | 113 | trace.h, it uses a minimum of types and other header files included to keep the |
| 114 | namespace clean and compile times and dependencies down. |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 115 | |
| 116 | Trace events should use types as follows: |
| 117 | |
| 118 | * Use stdint.h types for fixed-size types. Most offsets and guest memory |
| 119 | addresses are best represented with uint32_t or uint64_t. Use fixed-size |
| 120 | types over primitive types whose size may change depending on the host |
| 121 | (32-bit versus 64-bit) so trace events don't truncate values or break |
| 122 | the build. |
| 123 | |
| 124 | * Use void * for pointers to structs or for arrays. The trace.h header |
| 125 | cannot include all user-defined struct declarations and it is therefore |
| 126 | necessary to use void * for pointers to structs. |
| 127 | |
| 128 | * For everything else, use primitive scalar types (char, int, long) with the |
| 129 | appropriate signedness. |
| 130 | |
Stefan Hajnoczi | ec09f87 | 2018-06-21 16:02:54 +0100 | [diff] [blame] | 131 | * Avoid floating point types (float and double) because SystemTap does not |
| 132 | support them. In most cases it is possible to round to an integer type |
| 133 | instead. This may require scaling the value first by multiplying it by 1000 |
| 134 | or the like when digits after the decimal point need to be preserved. |
| 135 | |
Stefan Hajnoczi | 9a85d39 | 2010-10-05 14:28:50 +0100 | [diff] [blame] | 136 | Format strings should reflect the types defined in the trace event. Take |
| 137 | special care to use PRId64 and PRIu64 for int64_t and uint64_t types, |
Stefan Hajnoczi | 913540a | 2011-09-13 13:34:35 +0100 | [diff] [blame] | 138 | respectively. This ensures portability between 32- and 64-bit platforms. |
Philippe Mathieu-Daudé | 9f7ad79 | 2019-09-16 11:51:21 +0200 | [diff] [blame] | 139 | Format strings must not end with a newline character. It is the responsibility |
| 140 | of backends to adapt line ending for proper logging. |
Stefan Hajnoczi | 9a85d39 | 2010-10-05 14:28:50 +0100 | [diff] [blame] | 141 | |
Daniel P. Berrange | d4fa843 | 2017-01-25 16:14:16 +0000 | [diff] [blame] | 142 | Each event declaration will start with the event name, then its arguments, |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 143 | finally a format string for pretty-printing. For example:: |
Daniel P. Berrange | d4fa843 | 2017-01-25 16:14:16 +0000 | [diff] [blame] | 144 | |
| 145 | qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p" |
| 146 | qemu_vfree(void *ptr) "ptr %p" |
| 147 | |
| 148 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 149 | Hints for adding new trace events |
| 150 | --------------------------------- |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 151 | |
| 152 | 1. Trace state changes in the code. Interesting points in the code usually |
| 153 | involve a state change like starting, stopping, allocating, freeing. State |
| 154 | changes are good trace events because they can be used to understand the |
| 155 | execution of the system. |
| 156 | |
| 157 | 2. Trace guest operations. Guest I/O accesses like reading device registers |
| 158 | are good trace events because they can be used to understand guest |
| 159 | interactions. |
| 160 | |
| 161 | 3. Use correlator fields so the context of an individual line of trace output |
| 162 | can be understood. For example, trace the pointer returned by malloc and |
| 163 | used as an argument to free. This way mallocs and frees can be matched up. |
| 164 | Trace events with no context are not very useful. |
| 165 | |
| 166 | 4. Name trace events after their function. If there are multiple trace events |
| 167 | in one function, append a unique distinguisher at the end of the name. |
| 168 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 169 | Generic interface and monitor commands |
| 170 | ====================================== |
Lluís | 31965ae | 2011-08-31 20:31:24 +0200 | [diff] [blame] | 171 | |
Lluís Vilanova | b1bae81 | 2013-03-05 14:47:38 +0100 | [diff] [blame] | 172 | You can programmatically query and control the state of trace events through a |
| 173 | backend-agnostic interface provided by the header "trace/control.h". |
Lluís | 31965ae | 2011-08-31 20:31:24 +0200 | [diff] [blame] | 174 | |
Lluís Vilanova | b1bae81 | 2013-03-05 14:47:38 +0100 | [diff] [blame] | 175 | Note that some of the backends do not provide an implementation for some parts |
| 176 | of this interface, in which case QEMU will just print a warning (please refer to |
| 177 | header "trace/control.h" to see which routines are backend-dependent). |
Lluís | 31965ae | 2011-08-31 20:31:24 +0200 | [diff] [blame] | 178 | |
Lluís Vilanova | b1bae81 | 2013-03-05 14:47:38 +0100 | [diff] [blame] | 179 | The state of events can also be queried and modified through monitor commands: |
Lluís | 31965ae | 2011-08-31 20:31:24 +0200 | [diff] [blame] | 180 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 181 | * ``info trace-events`` |
Lluís | 31965ae | 2011-08-31 20:31:24 +0200 | [diff] [blame] | 182 | View available trace events and their state. State 1 means enabled, state 0 |
| 183 | means disabled. |
| 184 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 185 | * ``trace-event NAME on|off`` |
Lluís Vilanova | b1bae81 | 2013-03-05 14:47:38 +0100 | [diff] [blame] | 186 | Enable/disable a given trace event or a group of events (using wildcards). |
Lluís | 31965ae | 2011-08-31 20:31:24 +0200 | [diff] [blame] | 187 | |
Yaowei Bai | db817b8 | 2018-07-04 11:17:27 +0800 | [diff] [blame] | 188 | The "--trace events=<file>" command line argument can be used to enable the |
Lluís | 23d15e8 | 2011-08-31 20:31:31 +0200 | [diff] [blame] | 189 | events listed in <file> from the very beginning of the program. This file must |
| 190 | contain one event name per line. |
| 191 | |
Yaowei Bai | db817b8 | 2018-07-04 11:17:27 +0800 | [diff] [blame] | 192 | If a line in the "--trace events=<file>" file begins with a '-', the trace event |
Stefan Hajnoczi | 8f5a0fb | 2012-11-05 08:48:29 +0100 | [diff] [blame] | 193 | will be disabled instead of enabled. This is useful when a wildcard was used |
| 194 | to enable an entire family of events but one noisy event needs to be disabled. |
| 195 | |
Lluís Vilanova | b1bae81 | 2013-03-05 14:47:38 +0100 | [diff] [blame] | 196 | Wildcard matching is supported in both the monitor command "trace-event" and the |
| 197 | events list file. That means you can enable/disable the events having a common |
| 198 | prefix in a batch. For example, virtio-blk trace events could be enabled using |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 199 | the following monitor command:: |
Lluís Vilanova | b1bae81 | 2013-03-05 14:47:38 +0100 | [diff] [blame] | 200 | |
| 201 | trace-event virtio_blk_* on |
| 202 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 203 | Trace backends |
| 204 | ============== |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 205 | |
Lluís | 7b92e5b | 2011-04-06 20:33:56 +0200 | [diff] [blame] | 206 | The "tracetool" script automates tedious trace event code generation and also |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 207 | keeps the trace event declarations independent of the trace backend. The trace |
| 208 | events are not tightly coupled to a specific trace backend, such as LTTng or |
Lluís | 7b92e5b | 2011-04-06 20:33:56 +0200 | [diff] [blame] | 209 | SystemTap. Support for trace backends can be added by extending the "tracetool" |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 210 | script. |
| 211 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 212 | The trace backends are chosen at configure time:: |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 213 | |
Stefan Hajnoczi | 7e46d5f | 2020-12-16 16:09:23 +0000 | [diff] [blame] | 214 | ./configure --enable-trace-backends=simple,dtrace |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 215 | |
| 216 | For a list of supported trace backends, try ./configure --help or see below. |
Dr. David Alan Gilbert | b73e8bd | 2014-10-07 15:12:41 +0100 | [diff] [blame] | 217 | If multiple backends are enabled, the trace is sent to them all. |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 218 | |
Peter Maydell | 3b0fc80 | 2016-11-04 16:27:17 +0000 | [diff] [blame] | 219 | If no backends are explicitly selected, configure will default to the |
| 220 | "log" backend. |
| 221 | |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 222 | The following subsections describe the supported trace backends. |
| 223 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 224 | Nop |
| 225 | --- |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 226 | |
| 227 | The "nop" backend generates empty trace event functions so that the compiler |
Peter Maydell | 3b0fc80 | 2016-11-04 16:27:17 +0000 | [diff] [blame] | 228 | can optimize out trace events completely. This imposes no performance |
| 229 | penalty. |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 230 | |
Lluís | dd215f6 | 2011-08-31 20:31:38 +0200 | [diff] [blame] | 231 | Note that regardless of the selected trace backend, events with the "disable" |
| 232 | property will be generated with the "nop" backend. |
| 233 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 234 | Log |
| 235 | --- |
Stefan Hajnoczi | b48c20f | 2011-02-23 14:00:21 +0000 | [diff] [blame] | 236 | |
Richard W.M. Jones | ab8eb29 | 2016-03-20 21:00:14 +0000 | [diff] [blame] | 237 | The "log" backend sends trace events directly to standard error. This |
Stefan Hajnoczi | b48c20f | 2011-02-23 14:00:21 +0000 | [diff] [blame] | 238 | effectively turns trace events into debug printfs. |
| 239 | |
| 240 | This is the simplest backend and can be used together with existing code that |
| 241 | uses DPRINTF(). |
| 242 | |
Stefan Hajnoczi | 418ed14 | 2021-01-25 11:35:07 +0000 | [diff] [blame] | 243 | The -msg timestamp=on|off command-line option controls whether or not to print |
| 244 | the tid/timestamp prefix for each trace event. |
| 245 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 246 | Simpletrace |
| 247 | ----------- |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 248 | |
Stefan Hajnoczi | 7e46d5f | 2020-12-16 16:09:23 +0000 | [diff] [blame] | 249 | The "simple" backend writes binary trace logs to a file from a thread, making |
| 250 | it lower overhead than the "log" backend. A Python API is available for writing |
| 251 | offline trace file analysis scripts. It may not be as powerful as |
| 252 | platform-specific or third-party trace backends but it is portable and has no |
| 253 | special library dependencies. |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 254 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 255 | Monitor commands |
| 256 | ~~~~~~~~~~~~~~~~ |
Stefan Hajnoczi | c72e3e4 | 2020-12-16 16:09:21 +0000 | [diff] [blame] | 257 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 258 | * ``trace-file on|off|flush|set <path>`` |
Stefan Hajnoczi | c72e3e4 | 2020-12-16 16:09:21 +0000 | [diff] [blame] | 259 | Enable/disable/flush the trace file or set the trace file name. |
| 260 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 261 | Analyzing trace files |
| 262 | ~~~~~~~~~~~~~~~~~~~~~ |
Stefan Hajnoczi | c72e3e4 | 2020-12-16 16:09:21 +0000 | [diff] [blame] | 263 | |
| 264 | The "simple" backend produces binary trace files that can be formatted with the |
| 265 | simpletrace.py script. The script takes the "trace-events-all" file and the |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 266 | binary trace:: |
Stefan Hajnoczi | c72e3e4 | 2020-12-16 16:09:21 +0000 | [diff] [blame] | 267 | |
| 268 | ./scripts/simpletrace.py trace-events-all trace-12345 |
| 269 | |
| 270 | You must ensure that the same "trace-events-all" file was used to build QEMU, |
| 271 | otherwise trace event declarations may have changed and output will not be |
| 272 | consistent. |
| 273 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 274 | Ftrace |
| 275 | ------ |
Eiichi Tsukata | e64dd5e | 2013-04-11 20:25:16 +0900 | [diff] [blame] | 276 | |
| 277 | The "ftrace" backend writes trace data to ftrace marker. This effectively |
| 278 | sends trace events to ftrace ring buffer, and you can compare qemu trace |
| 279 | data and kernel(especially kvm.ko when using KVM) trace data. |
| 280 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 281 | if you use KVM, enable kvm events in ftrace:: |
Eiichi Tsukata | e64dd5e | 2013-04-11 20:25:16 +0900 | [diff] [blame] | 282 | |
| 283 | # echo 1 > /sys/kernel/debug/tracing/events/kvm/enable |
| 284 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 285 | After running qemu by root user, you can get the trace:: |
Eiichi Tsukata | e64dd5e | 2013-04-11 20:25:16 +0900 | [diff] [blame] | 286 | |
| 287 | # cat /sys/kernel/debug/tracing/trace |
| 288 | |
| 289 | Restriction: "ftrace" backend is restricted to Linux only. |
| 290 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 291 | Syslog |
| 292 | ------ |
Paul Durrant | 0a85241 | 2016-08-04 14:44:14 +0100 | [diff] [blame] | 293 | |
| 294 | The "syslog" backend sends trace events using the POSIX syslog API. The log |
| 295 | is opened specifying the LOG_DAEMON facility and LOG_PID option (so events |
| 296 | are tagged with the pid of the particular QEMU process that generated |
| 297 | them). All events are logged at LOG_INFO level. |
| 298 | |
| 299 | NOTE: syslog may squash duplicate consecutive trace events and apply rate |
| 300 | limiting. |
| 301 | |
| 302 | Restriction: "syslog" backend is restricted to POSIX compliant OS. |
| 303 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 304 | LTTng Userspace Tracer |
| 305 | ---------------------- |
Stefan Hajnoczi | 81a97d9 | 2010-06-22 15:07:09 +0100 | [diff] [blame] | 306 | |
| 307 | The "ust" backend uses the LTTng Userspace Tracer library. There are no |
| 308 | monitor commands built into QEMU, instead UST utilities should be used to list, |
| 309 | enable/disable, and dump traces. |
Stefan Hajnoczi | b48c20f | 2011-02-23 14:00:21 +0000 | [diff] [blame] | 310 | |
Mohamad Gebai | ef3ef4a | 2014-01-29 22:47:57 -0500 | [diff] [blame] | 311 | Package lttng-tools is required for userspace tracing. You must ensure that the |
| 312 | current user belongs to the "tracing" group, or manually launch the |
| 313 | lttng-sessiond daemon for the current user prior to running any instance of |
| 314 | QEMU. |
| 315 | |
| 316 | While running an instrumented QEMU, LTTng should be able to list all available |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 317 | events:: |
Mohamad Gebai | ef3ef4a | 2014-01-29 22:47:57 -0500 | [diff] [blame] | 318 | |
| 319 | lttng list -u |
| 320 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 321 | Create tracing session:: |
Mohamad Gebai | ef3ef4a | 2014-01-29 22:47:57 -0500 | [diff] [blame] | 322 | |
| 323 | lttng create mysession |
| 324 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 325 | Enable events:: |
Mohamad Gebai | ef3ef4a | 2014-01-29 22:47:57 -0500 | [diff] [blame] | 326 | |
| 327 | lttng enable-event qemu:g_malloc -u |
| 328 | |
| 329 | Where the events can either be a comma-separated list of events, or "-a" to |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 330 | enable all tracepoint events. Start and stop tracing as needed:: |
Mohamad Gebai | ef3ef4a | 2014-01-29 22:47:57 -0500 | [diff] [blame] | 331 | |
| 332 | lttng start |
| 333 | lttng stop |
| 334 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 335 | View the trace:: |
Mohamad Gebai | ef3ef4a | 2014-01-29 22:47:57 -0500 | [diff] [blame] | 336 | |
| 337 | lttng view |
| 338 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 339 | Destroy tracing session:: |
Mohamad Gebai | ef3ef4a | 2014-01-29 22:47:57 -0500 | [diff] [blame] | 340 | |
| 341 | lttng destroy |
| 342 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 343 | Babeltrace can be used at any later time to view the trace:: |
Mohamad Gebai | ef3ef4a | 2014-01-29 22:47:57 -0500 | [diff] [blame] | 344 | |
| 345 | babeltrace $HOME/lttng-traces/mysession-<date>-<time> |
| 346 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 347 | SystemTap |
| 348 | --------- |
Stefan Hajnoczi | b48c20f | 2011-02-23 14:00:21 +0000 | [diff] [blame] | 349 | |
| 350 | The "dtrace" backend uses DTrace sdt probes but has only been tested with |
| 351 | SystemTap. When SystemTap support is detected a .stp file with wrapper probes |
| 352 | is generated to make use in scripts more convenient. This step can also be |
| 353 | performed manually after a build in order to change the binary name in the .stp |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 354 | probes:: |
Stefan Hajnoczi | b48c20f | 2011-02-23 14:00:21 +0000 | [diff] [blame] | 355 | |
Lin Ma | 2e4ccbb | 2015-09-11 14:58:50 +0800 | [diff] [blame] | 356 | scripts/tracetool.py --backends=dtrace --format=stap \ |
| 357 | --binary path/to/qemu-binary \ |
| 358 | --target-type system \ |
| 359 | --target-name x86_64 \ |
Stefan Hajnoczi | bd20038 | 2019-10-09 14:51:54 +0100 | [diff] [blame] | 360 | --group=all \ |
Stefan Hajnoczi | c05012a | 2020-08-27 15:29:12 +0100 | [diff] [blame] | 361 | trace-events-all \ |
| 362 | qemu.stp |
Lluís Vilanova | b7d66a7 | 2011-12-06 17:38:15 +0100 | [diff] [blame] | 363 | |
Daniel P. Berrangé | 62dd104 | 2019-01-23 12:00:16 +0000 | [diff] [blame] | 364 | To facilitate simple usage of systemtap where there merely needs to be printf |
| 365 | logging of certain probes, a helper script "qemu-trace-stap" is provided. |
| 366 | Consult its manual page for guidance on its usage. |
| 367 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 368 | Trace event properties |
| 369 | ====================== |
Lluís Vilanova | b7d66a7 | 2011-12-06 17:38:15 +0100 | [diff] [blame] | 370 | |
Daniel P. Berrange | 1412cf5 | 2016-06-16 09:39:47 +0100 | [diff] [blame] | 371 | Each event in the "trace-events-all" file can be prefixed with a space-separated |
Lluís Vilanova | b7d66a7 | 2011-12-06 17:38:15 +0100 | [diff] [blame] | 372 | list of zero or more of the following event properties. |
| 373 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 374 | "disable" |
| 375 | --------- |
Lluís Vilanova | b7d66a7 | 2011-12-06 17:38:15 +0100 | [diff] [blame] | 376 | |
| 377 | If a specific trace event is going to be invoked a huge number of times, this |
| 378 | might have a noticeable performance impact even when the event is |
| 379 | programmatically disabled. |
| 380 | |
| 381 | In this case you should declare such event with the "disable" property. This |
| 382 | will effectively disable the event at compile time (by using the "nop" backend), |
| 383 | thus having no performance impact at all on regular builds (i.e., unless you |
Daniel P. Berrange | 1412cf5 | 2016-06-16 09:39:47 +0100 | [diff] [blame] | 384 | edit the "trace-events-all" file). |
Lluís Vilanova | b7d66a7 | 2011-12-06 17:38:15 +0100 | [diff] [blame] | 385 | |
| 386 | In addition, there might be cases where relatively complex computations must be |
| 387 | performed to generate values that are only used as arguments for a trace |
Peter Maydell | 1aa6430 | 2020-01-20 15:11:40 +0000 | [diff] [blame] | 388 | function. In these cases you can use 'trace_event_get_state_backends()' to |
| 389 | guard such computations, so they are skipped if the event has been either |
| 390 | compile-time disabled or run-time disabled. If the event is compile-time |
| 391 | disabled, this check will have no performance impact. |
Lluís Vilanova | b7d66a7 | 2011-12-06 17:38:15 +0100 | [diff] [blame] | 392 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 393 | :: |
| 394 | |
Lluís Vilanova | b7d66a7 | 2011-12-06 17:38:15 +0100 | [diff] [blame] | 395 | #include "trace.h" /* needed for trace event prototype */ |
| 396 | |
| 397 | void *qemu_vmalloc(size_t size) |
| 398 | { |
| 399 | void *ptr; |
| 400 | size_t align = QEMU_VMALLOC_ALIGN; |
| 401 | |
| 402 | if (size < align) { |
| 403 | align = getpagesize(); |
| 404 | } |
| 405 | ptr = qemu_memalign(align, size); |
Peter Maydell | 1aa6430 | 2020-01-20 15:11:40 +0000 | [diff] [blame] | 406 | if (trace_event_get_state_backends(TRACE_QEMU_VMALLOC)) { |
Lluís Vilanova | b7d66a7 | 2011-12-06 17:38:15 +0100 | [diff] [blame] | 407 | void *complex; |
| 408 | /* some complex computations to produce the 'complex' value */ |
| 409 | trace_qemu_vmalloc(size, ptr, complex); |
| 410 | } |
| 411 | return ptr; |
| 412 | } |
Lluís Vilanova | b1bae81 | 2013-03-05 14:47:38 +0100 | [diff] [blame] | 413 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 414 | "tcg" |
| 415 | ----- |
Lluís Vilanova | 0bb403b | 2014-05-30 14:11:26 +0200 | [diff] [blame] | 416 | |
| 417 | Guest code generated by TCG can be traced by defining an event with the "tcg" |
| 418 | event property. Internally, this property generates two events: |
| 419 | "<eventname>_trans" to trace the event at translation time, and |
| 420 | "<eventname>_exec" to trace the event at execution time. |
| 421 | |
| 422 | Instead of using these two events, you should instead use the function |
| 423 | "trace_<eventname>_tcg" during translation (TCG code generation). This function |
| 424 | will automatically call "trace_<eventname>_trans", and will generate the |
| 425 | necessary TCG code to call "trace_<eventname>_exec" during guest code execution. |
| 426 | |
| 427 | Events with the "tcg" property can be declared in the "trace-events" file with a |
| 428 | mix of native and TCG types, and "trace_<eventname>_tcg" will gracefully forward |
| 429 | them to the "<eventname>_trans" and "<eventname>_exec" events. Since TCG values |
| 430 | are not known at translation time, these are ignored by the "<eventname>_trans" |
| 431 | event. Because of this, the entry in the "trace-events" file needs two printing |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 432 | formats (separated by a comma):: |
Lluís Vilanova | 0bb403b | 2014-05-30 14:11:26 +0200 | [diff] [blame] | 433 | |
| 434 | tcg foo(uint8_t a1, TCGv_i32 a2) "a1=%d", "a1=%d a2=%d" |
| 435 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 436 | For example:: |
Lluís Vilanova | 0bb403b | 2014-05-30 14:11:26 +0200 | [diff] [blame] | 437 | |
| 438 | #include "trace-tcg.h" |
| 439 | |
| 440 | void some_disassembly_func (...) |
| 441 | { |
| 442 | uint8_t a1 = ...; |
| 443 | TCGv_i32 a2 = ...; |
| 444 | trace_foo_tcg(a1, a2); |
| 445 | } |
| 446 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 447 | This will immediately call:: |
Lluís Vilanova | 0bb403b | 2014-05-30 14:11:26 +0200 | [diff] [blame] | 448 | |
| 449 | void trace_foo_trans(uint8_t a1); |
| 450 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 451 | and will generate the TCG code to call:: |
Lluís Vilanova | 0bb403b | 2014-05-30 14:11:26 +0200 | [diff] [blame] | 452 | |
| 453 | void trace_foo(uint8_t a1, uint32_t a2); |
Lluís Vilanova | 3d211d9 | 2016-02-25 17:43:38 +0100 | [diff] [blame] | 454 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 455 | "vcpu" |
| 456 | ------ |
Lluís Vilanova | 3d211d9 | 2016-02-25 17:43:38 +0100 | [diff] [blame] | 457 | |
| 458 | Identifies events that trace vCPU-specific information. It implicitly adds a |
| 459 | "CPUState*" argument, and extends the tracing print format to show the vCPU |
| 460 | information. If used together with the "tcg" property, it adds a second |
| 461 | "TCGv_env" argument that must point to the per-target global TCG register that |
| 462 | points to the vCPU when guest code is executed (usually the "cpu_env" variable). |
| 463 | |
Stefan Hajnoczi | 7609ffb | 2017-03-27 14:17:18 +0100 | [diff] [blame] | 464 | The "tcg" and "vcpu" properties are currently only honored in the root |
| 465 | ./trace-events file. |
| 466 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 467 | The following example events:: |
Lluís Vilanova | 3d211d9 | 2016-02-25 17:43:38 +0100 | [diff] [blame] | 468 | |
| 469 | foo(uint32_t a) "a=%x" |
| 470 | vcpu bar(uint32_t a) "a=%x" |
| 471 | tcg vcpu baz(uint32_t a) "a=%x", "a=%x" |
| 472 | |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 473 | Can be used as:: |
Lluís Vilanova | 3d211d9 | 2016-02-25 17:43:38 +0100 | [diff] [blame] | 474 | |
| 475 | #include "trace-tcg.h" |
| 476 | |
| 477 | CPUArchState *env; |
| 478 | TCGv_ptr cpu_env; |
| 479 | |
| 480 | void some_disassembly_func(...) |
| 481 | { |
| 482 | /* trace emitted at this point */ |
| 483 | trace_foo(0xd1); |
| 484 | /* trace emitted at this point */ |
Richard Henderson | 29a0af6 | 2019-03-22 16:07:18 -0700 | [diff] [blame] | 485 | trace_bar(env_cpu(env), 0xd2); |
Lluís Vilanova | 3d211d9 | 2016-02-25 17:43:38 +0100 | [diff] [blame] | 486 | /* trace emitted at this point (env) and when guest code is executed (cpu_env) */ |
Richard Henderson | 29a0af6 | 2019-03-22 16:07:18 -0700 | [diff] [blame] | 487 | trace_baz_tcg(env_cpu(env), cpu_env, 0xd3); |
Lluís Vilanova | 3d211d9 | 2016-02-25 17:43:38 +0100 | [diff] [blame] | 488 | } |
| 489 | |
| 490 | If the translating vCPU has address 0xc1 and code is later executed by vCPU |
Stefan Hajnoczi | e50caf4 | 2020-12-16 16:09:22 +0000 | [diff] [blame] | 491 | 0xc2, this would be an example output:: |
Lluís Vilanova | 3d211d9 | 2016-02-25 17:43:38 +0100 | [diff] [blame] | 492 | |
| 493 | // at guest code translation |
| 494 | foo a=0xd1 |
| 495 | bar cpu=0xc1 a=0xd2 |
| 496 | baz_trans cpu=0xc1 a=0xd3 |
| 497 | // at guest code execution |
| 498 | baz_exec cpu=0xc2 a=0xd3 |