cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

tracing.rst (17898B)


      1=======
      2Tracing
      3=======
      4
      5Introduction
      6============
      7
      8This document describes the tracing infrastructure in QEMU and how to use it
      9for debugging, profiling, and observing execution.
     10
     11Quickstart
     12==========
     13
     14Enable tracing of ``memory_region_ops_read`` and ``memory_region_ops_write``
     15events::
     16
     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
     21
     22This output comes from the "log" trace backend that is enabled by default when
     23``./configure --enable-trace-backends=BACKENDS`` was not explicitly specified.
     24
     25Multiple patterns can be specified by repeating the ``--trace`` option::
     26
     27    $ qemu --trace "kvm_*" --trace "virtio_*" ...
     28
     29When patterns are used frequently it is more convenient to store them in a
     30file to avoid long command-line options::
     31
     32    $ echo "memory_region_ops_*" >/tmp/events
     33    $ echo "kvm_*" >>/tmp/events
     34    $ qemu --trace events=/tmp/events ...
     35
     36Trace events
     37============
     38
     39Sub-directory setup
     40-------------------
     41
     42Each 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
     44listed in the "trace_events_subdirs" variable in the top level meson.build
     45file. During build, the "trace-events" file in each listed subdirectory will be
     46processed by the "tracetool" script to generate code for the trace events.
     47
     48The individual "trace-events" files are merged into a "trace-events-all" file,
     49which is also installed into "/usr/share/qemu" with the name "trace-events".
     50This merged file is to be used by the "simpletrace.py" script to later analyse
     51traces in the simpletrace data format.
     52
     53The following files are automatically generated in <builddir>/trace/ during the
     54build:
     55
     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
     62
     63Here <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"
     65becomes "trace-accel_kvm.c".
     66
     67Source files in the source tree do not directly include generated files in
     68"<builddir>/trace/". Instead they #include the local "trace.h" file, without
     69any sub-directory path prefix. eg io/channel-buffer.c would do::
     70
     71  #include "trace.h"
     72
     73The "io/trace.h" file must be created manually with an #include of the
     74corresponding "trace/trace-<subdir>.h" file that will be generated in the
     75builddir::
     76
     77  $ echo '#include "trace/trace-io.h"' >io/trace.h
     78
     79While it is possible to include a trace.h file from outside a source file's own
     80sub-directory, this is discouraged in general. It is strongly preferred that
     81all events be declared directly in the sub-directory that uses them. The only
     82exception is where there are some shared trace events defined in the top level
     83directory trace-events file.  The top level directory generates trace files
     84with a filename prefix of "trace/trace-root" instead of just "trace". This is
     85to avoid ambiguity between a trace.h in the current directory, vs the top level
     86directory.
     87
     88Using trace events
     89------------------
     90
     91Trace events are invoked directly from source code like this::
     92
     93    #include "trace.h"  /* needed for trace event prototype */
     94    
     95    void *qemu_vmalloc(size_t size)
     96    {
     97        void *ptr;
     98        size_t align = QEMU_VMALLOC_ALIGN;
     99     
    100        if (size < align) {
    101            align = getpagesize();
    102        }
    103        ptr = qemu_memalign(align, size);
    104        trace_qemu_vmalloc(size, ptr);
    105        return ptr;
    106    }
    107
    108Declaring trace events
    109----------------------
    110
    111The "tracetool" script produces the trace.h header file which is included by
    112every source file that uses trace events.  Since many source files include
    113trace.h, it uses a minimum of types and other header files included to keep the
    114namespace clean and compile times and dependencies down.
    115
    116Trace 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
    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
    136Format strings should reflect the types defined in the trace event.  Take
    137special care to use PRId64 and PRIu64 for int64_t and uint64_t types,
    138respectively.  This ensures portability between 32- and 64-bit platforms.
    139Format strings must not end with a newline character.  It is the responsibility
    140of backends to adapt line ending for proper logging.
    141
    142Each event declaration will start with the event name, then its arguments,
    143finally a format string for pretty-printing. For example::
    144
    145    qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p"
    146    qemu_vfree(void *ptr) "ptr %p"
    147
    148
    149Hints for adding new trace events
    150---------------------------------
    151
    1521. 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
    1572. 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
    1613. 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
    1664. 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
    169Generic interface and monitor commands
    170======================================
    171
    172You can programmatically query and control the state of trace events through a
    173backend-agnostic interface provided by the header "trace/control.h".
    174
    175Note that some of the backends do not provide an implementation for some parts
    176of this interface, in which case QEMU will just print a warning (please refer to
    177header "trace/control.h" to see which routines are backend-dependent).
    178
    179The state of events can also be queried and modified through monitor commands:
    180
    181* ``info trace-events``
    182  View available trace events and their state.  State 1 means enabled, state 0
    183  means disabled.
    184
    185* ``trace-event NAME on|off``
    186  Enable/disable a given trace event or a group of events (using wildcards).
    187
    188The "--trace events=<file>" command line argument can be used to enable the
    189events listed in <file> from the very beginning of the program. This file must
    190contain one event name per line.
    191
    192If a line in the "--trace events=<file>" file begins with a '-', the trace event
    193will be disabled instead of enabled.  This is useful when a wildcard was used
    194to enable an entire family of events but one noisy event needs to be disabled.
    195
    196Wildcard matching is supported in both the monitor command "trace-event" and the
    197events list file. That means you can enable/disable the events having a common
    198prefix in a batch. For example, virtio-blk trace events could be enabled using
    199the following monitor command::
    200
    201    trace-event virtio_blk_* on
    202
    203Trace backends
    204==============
    205
    206The "tracetool" script automates tedious trace event code generation and also
    207keeps the trace event declarations independent of the trace backend.  The trace
    208events are not tightly coupled to a specific trace backend, such as LTTng or
    209SystemTap.  Support for trace backends can be added by extending the "tracetool"
    210script.
    211
    212The trace backends are chosen at configure time::
    213
    214    ./configure --enable-trace-backends=simple,dtrace
    215
    216For a list of supported trace backends, try ./configure --help or see below.
    217If multiple backends are enabled, the trace is sent to them all.
    218
    219If no backends are explicitly selected, configure will default to the
    220"log" backend.
    221
    222The following subsections describe the supported trace backends.
    223
    224Nop
    225---
    226
    227The "nop" backend generates empty trace event functions so that the compiler
    228can optimize out trace events completely.  This imposes no performance
    229penalty.
    230
    231Note that regardless of the selected trace backend, events with the "disable"
    232property will be generated with the "nop" backend.
    233
    234Log
    235---
    236
    237The "log" backend sends trace events directly to standard error.  This
    238effectively turns trace events into debug printfs.
    239
    240This is the simplest backend and can be used together with existing code that
    241uses DPRINTF().
    242
    243The -msg timestamp=on|off command-line option controls whether or not to print
    244the tid/timestamp prefix for each trace event.
    245
    246Simpletrace
    247-----------
    248
    249The "simple" backend writes binary trace logs to a file from a thread, making
    250it lower overhead than the "log" backend. A Python API is available for writing
    251offline trace file analysis scripts. It may not be as powerful as
    252platform-specific or third-party trace backends but it is portable and has no
    253special library dependencies.
    254
    255Monitor commands
    256~~~~~~~~~~~~~~~~
    257
    258* ``trace-file on|off|flush|set <path>``
    259  Enable/disable/flush the trace file or set the trace file name.
    260
    261Analyzing trace files
    262~~~~~~~~~~~~~~~~~~~~~
    263
    264The "simple" backend produces binary trace files that can be formatted with the
    265simpletrace.py script.  The script takes the "trace-events-all" file and the
    266binary trace::
    267
    268    ./scripts/simpletrace.py trace-events-all trace-12345
    269
    270You must ensure that the same "trace-events-all" file was used to build QEMU,
    271otherwise trace event declarations may have changed and output will not be
    272consistent.
    273
    274Ftrace
    275------
    276
    277The "ftrace" backend writes trace data to ftrace marker. This effectively
    278sends trace events to ftrace ring buffer, and you can compare qemu trace
    279data and kernel(especially kvm.ko when using KVM) trace data.
    280
    281if you use KVM, enable kvm events in ftrace::
    282
    283   # echo 1 > /sys/kernel/debug/tracing/events/kvm/enable
    284
    285After running qemu by root user, you can get the trace::
    286
    287   # cat /sys/kernel/debug/tracing/trace
    288
    289Restriction: "ftrace" backend is restricted to Linux only.
    290
    291Syslog
    292------
    293
    294The "syslog" backend sends trace events using the POSIX syslog API. The log
    295is opened specifying the LOG_DAEMON facility and LOG_PID option (so events
    296are tagged with the pid of the particular QEMU process that generated
    297them). All events are logged at LOG_INFO level.
    298
    299NOTE: syslog may squash duplicate consecutive trace events and apply rate
    300      limiting.
    301
    302Restriction: "syslog" backend is restricted to POSIX compliant OS.
    303
    304LTTng Userspace Tracer
    305----------------------
    306
    307The "ust" backend uses the LTTng Userspace Tracer library.  There are no
    308monitor commands built into QEMU, instead UST utilities should be used to list,
    309enable/disable, and dump traces.
    310
    311Package lttng-tools is required for userspace tracing. You must ensure that the
    312current user belongs to the "tracing" group, or manually launch the
    313lttng-sessiond daemon for the current user prior to running any instance of
    314QEMU.
    315
    316While running an instrumented QEMU, LTTng should be able to list all available
    317events::
    318
    319    lttng list -u
    320
    321Create tracing session::
    322
    323    lttng create mysession
    324
    325Enable events::
    326
    327    lttng enable-event qemu:g_malloc -u
    328
    329Where the events can either be a comma-separated list of events, or "-a" to
    330enable all tracepoint events. Start and stop tracing as needed::
    331
    332    lttng start
    333    lttng stop
    334
    335View the trace::
    336
    337    lttng view
    338
    339Destroy tracing session::
    340
    341    lttng destroy
    342
    343Babeltrace can be used at any later time to view the trace::
    344
    345    babeltrace $HOME/lttng-traces/mysession-<date>-<time>
    346
    347SystemTap
    348---------
    349
    350The "dtrace" backend uses DTrace sdt probes but has only been tested with
    351SystemTap.  When SystemTap support is detected a .stp file with wrapper probes
    352is generated to make use in scripts more convenient.  This step can also be
    353performed manually after a build in order to change the binary name in the .stp
    354probes::
    355
    356    scripts/tracetool.py --backends=dtrace --format=stap \
    357                         --binary path/to/qemu-binary \
    358                         --target-type system \
    359                         --target-name x86_64 \
    360                         --group=all \
    361                         trace-events-all \
    362                         qemu.stp
    363
    364To facilitate simple usage of systemtap where there merely needs to be printf
    365logging of certain probes, a helper script "qemu-trace-stap" is provided.
    366Consult its manual page for guidance on its usage.
    367
    368Trace event properties
    369======================
    370
    371Each event in the "trace-events-all" file can be prefixed with a space-separated
    372list of zero or more of the following event properties.
    373
    374"disable"
    375---------
    376
    377If a specific trace event is going to be invoked a huge number of times, this
    378might have a noticeable performance impact even when the event is
    379programmatically disabled.
    380
    381In this case you should declare such event with the "disable" property. This
    382will effectively disable the event at compile time (by using the "nop" backend),
    383thus having no performance impact at all on regular builds (i.e., unless you
    384edit the "trace-events-all" file).
    385
    386In addition, there might be cases where relatively complex computations must be
    387performed to generate values that are only used as arguments for a trace
    388function. In these cases you can use 'trace_event_get_state_backends()' to
    389guard such computations, so they are skipped if the event has been either
    390compile-time disabled or run-time disabled. If the event is compile-time
    391disabled, this check will have no performance impact.
    392
    393::
    394
    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);
    406        if (trace_event_get_state_backends(TRACE_QEMU_VMALLOC)) {
    407            void *complex;
    408            /* some complex computations to produce the 'complex' value */
    409            trace_qemu_vmalloc(size, ptr, complex);
    410        }
    411        return ptr;
    412    }
    413
    414"tcg"
    415-----
    416
    417Guest code generated by TCG can be traced by defining an event with the "tcg"
    418event 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
    422Instead of using these two events, you should instead use the function
    423"trace_<eventname>_tcg" during translation (TCG code generation). This function
    424will automatically call "trace_<eventname>_trans", and will generate the
    425necessary TCG code to call "trace_<eventname>_exec" during guest code execution.
    426
    427Events with the "tcg" property can be declared in the "trace-events" file with a
    428mix of native and TCG types, and "trace_<eventname>_tcg" will gracefully forward
    429them to the "<eventname>_trans" and "<eventname>_exec" events. Since TCG values
    430are not known at translation time, these are ignored by the "<eventname>_trans"
    431event. Because of this, the entry in the "trace-events" file needs two printing
    432formats (separated by a comma)::
    433
    434    tcg foo(uint8_t a1, TCGv_i32 a2) "a1=%d", "a1=%d a2=%d"
    435
    436For example::
    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
    447This will immediately call::
    448
    449    void trace_foo_trans(uint8_t a1);
    450
    451and will generate the TCG code to call::
    452
    453    void trace_foo(uint8_t a1, uint32_t a2);
    454
    455"vcpu"
    456------
    457
    458Identifies events that trace vCPU-specific information. It implicitly adds a
    459"CPUState*" argument, and extends the tracing print format to show the vCPU
    460information. 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
    462points to the vCPU when guest code is executed (usually the "cpu_env" variable).
    463
    464The "tcg" and "vcpu" properties are currently only honored in the root
    465./trace-events file.
    466
    467The following example events::
    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
    473Can be used as::
    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 */
    485        trace_bar(env_cpu(env), 0xd2);
    486        /* trace emitted at this point (env) and when guest code is executed (cpu_env) */
    487        trace_baz_tcg(env_cpu(env), cpu_env, 0xd3);
    488    }
    489
    490If the translating vCPU has address 0xc1 and code is later executed by vCPU
    4910xc2, this would be an example output::
    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