Pull request
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEhpWov9P5fNqsNXdanKSrs4Grc8gFAmAYImwACgkQnKSrs4Gr c8iiiggAwEm5WbDSQ5oNyDpPDiV7eGGEYCWrQg5sk2kFcBhohf85qUobChhgqv3I lCWQ+ye5f9ma1cTMX68e38a8/bVrIwso2royych8+8jIlnXsbMEwg45lVBP3/JLo 6xBo4PPkd7dZ1iEJQjF/1eSfLvwI8R5KlzxInHDYobuOwoBkks0japN259IDi61t wiDmzs+hUnBegpUib318sOXVfiGo8vRNv60Oc87sN/TlrFX6B3QpL2HsSuQqX+Sh VnpjJ1XWdHLSQQLDB8uFVgjk3m7kq+7h9/bvvoPPAH4gCSWurUYOsxVRJAY8OJ+7 c0BgEYqAl9c8jxErrzvRG38AH1G6iQ== =Zk08 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/stefanha-gitlab/tags/tracing-pull-request' into staging Pull request # gpg: Signature made Mon 01 Feb 2021 15:46:52 GMT # gpg: using RSA key 8695A8BFD3F97CDAAC35775A9CA4ABB381AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" [full] # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" [full] # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * remotes/stefanha-gitlab/tags/tracing-pull-request: trace: update docs with meson build information trace: document how to specify multiple --trace patterns simpletrace: build() missing 2 required positional arguments trace: make the 'log' backend timestamp configurable error: rename error_with_timestamp to message_with_timestamp trace: add meson custom_target() depend_files for tracetool tracetool: also strip %l and %ll from systemtap format strings tracetool: fix "PRI" macro decoding trace: recommend "log" backend for getting started with tracing tracing: convert documentation to rST trace: fix simpletrace doc mismerge Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
cf7ca7d5b9
|
@ -28,6 +28,7 @@ Contents:
|
|||
secure-coding-practices
|
||||
tcg
|
||||
tcg-icount
|
||||
tracing
|
||||
multi-thread-tcg
|
||||
tcg-plugins
|
||||
bitops
|
||||
|
|
|
@ -1,71 +1,94 @@
|
|||
= Tracing =
|
||||
=======
|
||||
Tracing
|
||||
=======
|
||||
|
||||
== Introduction ==
|
||||
Introduction
|
||||
============
|
||||
|
||||
This document describes the tracing infrastructure in QEMU and how to use it
|
||||
for debugging, profiling, and observing execution.
|
||||
|
||||
== Quickstart ==
|
||||
Quickstart
|
||||
==========
|
||||
|
||||
1. Build with the 'simple' trace backend:
|
||||
Enable tracing of ``memory_region_ops_read`` and ``memory_region_ops_write``
|
||||
events::
|
||||
|
||||
./configure --enable-trace-backends=simple
|
||||
make
|
||||
$ qemu --trace "memory_region_ops_*" ...
|
||||
...
|
||||
719585@1608130130.441188:memory_region_ops_read cpu 0 mr 0x562fdfbb3820 addr 0x3cc value 0x67 size 1
|
||||
719585@1608130130.441190:memory_region_ops_write cpu 0 mr 0x562fdfbd2f00 addr 0x3d4 value 0x70e size 2
|
||||
|
||||
2. Create a file with the events you want to trace:
|
||||
This output comes from the "log" trace backend that is enabled by default when
|
||||
``./configure --enable-trace-backends=BACKENDS`` was not explicitly specified.
|
||||
|
||||
echo memory_region_ops_read >/tmp/events
|
||||
Multiple patterns can be specified by repeating the ``--trace`` option::
|
||||
|
||||
3. Run the virtual machine to produce a trace file:
|
||||
$ qemu --trace "kvm_*" --trace "virtio_*" ...
|
||||
|
||||
qemu --trace events=/tmp/events ... # your normal QEMU invocation
|
||||
When patterns are used frequently it is more convenient to store them in a
|
||||
file to avoid long command-line options::
|
||||
|
||||
4. Pretty-print the binary trace file:
|
||||
$ echo "memory_region_ops_*" >/tmp/events
|
||||
$ echo "kvm_*" >>/tmp/events
|
||||
$ qemu --trace events=/tmp/events ...
|
||||
|
||||
./scripts/simpletrace.py trace-events-all trace-* # Override * with QEMU <pid>
|
||||
Trace events
|
||||
============
|
||||
|
||||
== Trace events ==
|
||||
Sub-directory setup
|
||||
-------------------
|
||||
|
||||
=== Sub-directory setup ===
|
||||
|
||||
Each directory in the source tree can declare a set of static trace events
|
||||
in a local "trace-events" file. All directories which contain "trace-events"
|
||||
files must be listed in the "trace-events-subdirs" make variable in the top
|
||||
level Makefile.objs. During build, the "trace-events" file in each listed
|
||||
subdirectory will be processed by the "tracetool" script to generate code for
|
||||
the trace events.
|
||||
Each directory in the source tree can declare a set of trace events in a local
|
||||
"trace-events" file. All directories which contain "trace-events" files must be
|
||||
listed in the "trace_events_subdirs" variable in the top level meson.build
|
||||
file. During build, the "trace-events" file in each listed subdirectory will be
|
||||
processed by the "tracetool" script to generate code for the trace events.
|
||||
|
||||
The individual "trace-events" files are merged into a "trace-events-all" file,
|
||||
which is also installed into "/usr/share/qemu" with the name "trace-events".
|
||||
This merged file is to be used by the "simpletrace.py" script to later analyse
|
||||
traces in the simpletrace data format.
|
||||
|
||||
In the sub-directory the following files will be automatically generated
|
||||
The following files are automatically generated in <builddir>/trace/ during the
|
||||
build:
|
||||
|
||||
- trace.c - the trace event state declarations
|
||||
- trace.h - the trace event enums and probe functions
|
||||
- trace-dtrace.h - DTrace event probe specification
|
||||
- trace-dtrace.dtrace - DTrace event probe helper declaration
|
||||
- trace-dtrace.o - binary DTrace provider (generated by dtrace)
|
||||
- trace-ust.h - UST event probe helper declarations
|
||||
- trace-<subdir>.c - the trace event state declarations
|
||||
- trace-<subdir>.h - the trace event enums and probe functions
|
||||
- trace-dtrace-<subdir>.h - DTrace event probe specification
|
||||
- trace-dtrace-<subdir>.dtrace - DTrace event probe helper declaration
|
||||
- trace-dtrace-<subdir>.o - binary DTrace provider (generated by dtrace)
|
||||
- trace-ust-<subdir>.h - UST event probe helper declarations
|
||||
|
||||
Source files in the sub-directory should #include the local 'trace.h' file,
|
||||
without any sub-directory path prefix. eg io/channel-buffer.c would do
|
||||
Here <subdir> is the sub-directory path with '/' replaced by '_'. For example,
|
||||
"accel/kvm" becomes "accel_kvm" and the final filename for "trace-<subdir>.c"
|
||||
becomes "trace-accel_kvm.c".
|
||||
|
||||
Source files in the source tree do not directly include generated files in
|
||||
"<builddir>/trace/". Instead they #include the local "trace.h" file, without
|
||||
any sub-directory path prefix. eg io/channel-buffer.c would do::
|
||||
|
||||
#include "trace.h"
|
||||
|
||||
To access the 'io/trace.h' file. While it is possible to include a trace.h
|
||||
file from outside a source file's own sub-directory, this is discouraged in
|
||||
general. It is strongly preferred that all events be declared directly in
|
||||
the sub-directory that uses them. The only exception is where there are some
|
||||
shared trace events defined in the top level directory trace-events file.
|
||||
The top level directory generates trace files with a filename prefix of
|
||||
"trace/trace-root" instead of just "trace". This is to avoid ambiguity between
|
||||
a trace.h in the current directory, vs the top level directory.
|
||||
The "io/trace.h" file must be created manually with an #include of the
|
||||
corresponding "trace/trace-<subdir>.h" file that will be generated in the
|
||||
builddir::
|
||||
|
||||
=== Using trace events ===
|
||||
$ echo '#include "trace/trace-io.h"' >io/trace.h
|
||||
|
||||
Trace events are invoked directly from source code like this:
|
||||
While it is possible to include a trace.h file from outside a source file's own
|
||||
sub-directory, this is discouraged in general. It is strongly preferred that
|
||||
all events be declared directly in the sub-directory that uses them. The only
|
||||
exception is where there are some shared trace events defined in the top level
|
||||
directory trace-events file. The top level directory generates trace files
|
||||
with a filename prefix of "trace/trace-root" instead of just "trace". This is
|
||||
to avoid ambiguity between a trace.h in the current directory, vs the top level
|
||||
directory.
|
||||
|
||||
Using trace events
|
||||
------------------
|
||||
|
||||
Trace events are invoked directly from source code like this::
|
||||
|
||||
#include "trace.h" /* needed for trace event prototype */
|
||||
|
||||
|
@ -82,7 +105,8 @@ Trace events are invoked directly from source code like this:
|
|||
return ptr;
|
||||
}
|
||||
|
||||
=== Declaring trace events ===
|
||||
Declaring trace events
|
||||
----------------------
|
||||
|
||||
The "tracetool" script produces the trace.h header file which is included by
|
||||
every source file that uses trace events. Since many source files include
|
||||
|
@ -116,13 +140,14 @@ Format strings must not end with a newline character. It is the responsibility
|
|||
of backends to adapt line ending for proper logging.
|
||||
|
||||
Each event declaration will start with the event name, then its arguments,
|
||||
finally a format string for pretty-printing. For example:
|
||||
finally a format string for pretty-printing. For example::
|
||||
|
||||
qemu_vmalloc(size_t size, void *ptr) "size %zu ptr %p"
|
||||
qemu_vfree(void *ptr) "ptr %p"
|
||||
|
||||
|
||||
=== Hints for adding new trace events ===
|
||||
Hints for adding new trace events
|
||||
---------------------------------
|
||||
|
||||
1. Trace state changes in the code. Interesting points in the code usually
|
||||
involve a state change like starting, stopping, allocating, freeing. State
|
||||
|
@ -141,7 +166,8 @@ finally a format string for pretty-printing. For example:
|
|||
4. Name trace events after their function. If there are multiple trace events
|
||||
in one function, append a unique distinguisher at the end of the name.
|
||||
|
||||
== Generic interface and monitor commands ==
|
||||
Generic interface and monitor commands
|
||||
======================================
|
||||
|
||||
You can programmatically query and control the state of trace events through a
|
||||
backend-agnostic interface provided by the header "trace/control.h".
|
||||
|
@ -152,11 +178,11 @@ header "trace/control.h" to see which routines are backend-dependent).
|
|||
|
||||
The state of events can also be queried and modified through monitor commands:
|
||||
|
||||
* info trace-events
|
||||
* ``info trace-events``
|
||||
View available trace events and their state. State 1 means enabled, state 0
|
||||
means disabled.
|
||||
|
||||
* trace-event NAME on|off
|
||||
* ``trace-event NAME on|off``
|
||||
Enable/disable a given trace event or a group of events (using wildcards).
|
||||
|
||||
The "--trace events=<file>" command line argument can be used to enable the
|
||||
|
@ -170,11 +196,12 @@ to enable an entire family of events but one noisy event needs to be disabled.
|
|||
Wildcard matching is supported in both the monitor command "trace-event" and the
|
||||
events list file. That means you can enable/disable the events having a common
|
||||
prefix in a batch. For example, virtio-blk trace events could be enabled using
|
||||
the following monitor command:
|
||||
the following monitor command::
|
||||
|
||||
trace-event virtio_blk_* on
|
||||
|
||||
== Trace backends ==
|
||||
Trace backends
|
||||
==============
|
||||
|
||||
The "tracetool" script automates tedious trace event code generation and also
|
||||
keeps the trace event declarations independent of the trace backend. The trace
|
||||
|
@ -182,9 +209,9 @@ events are not tightly coupled to a specific trace backend, such as LTTng or
|
|||
SystemTap. Support for trace backends can be added by extending the "tracetool"
|
||||
script.
|
||||
|
||||
The trace backends are chosen at configure time:
|
||||
The trace backends are chosen at configure time::
|
||||
|
||||
./configure --enable-trace-backends=simple
|
||||
./configure --enable-trace-backends=simple,dtrace
|
||||
|
||||
For a list of supported trace backends, try ./configure --help or see below.
|
||||
If multiple backends are enabled, the trace is sent to them all.
|
||||
|
@ -194,7 +221,8 @@ If no backends are explicitly selected, configure will default to the
|
|||
|
||||
The following subsections describe the supported trace backends.
|
||||
|
||||
=== Nop ===
|
||||
Nop
|
||||
---
|
||||
|
||||
The "nop" backend generates empty trace event functions so that the compiler
|
||||
can optimize out trace events completely. This imposes no performance
|
||||
|
@ -203,7 +231,8 @@ penalty.
|
|||
Note that regardless of the selected trace backend, events with the "disable"
|
||||
property will be generated with the "nop" backend.
|
||||
|
||||
=== Log ===
|
||||
Log
|
||||
---
|
||||
|
||||
The "log" backend sends trace events directly to standard error. This
|
||||
effectively turns trace events into debug printfs.
|
||||
|
@ -211,30 +240,56 @@ effectively turns trace events into debug printfs.
|
|||
This is the simplest backend and can be used together with existing code that
|
||||
uses DPRINTF().
|
||||
|
||||
=== Simpletrace ===
|
||||
The -msg timestamp=on|off command-line option controls whether or not to print
|
||||
the tid/timestamp prefix for each trace event.
|
||||
|
||||
The "simple" backend supports common use cases and comes as part of the QEMU
|
||||
source tree. It may not be as powerful as platform-specific or third-party
|
||||
trace backends but it is portable. This is the recommended trace backend
|
||||
unless you have specific needs for more advanced backends.
|
||||
Simpletrace
|
||||
-----------
|
||||
|
||||
=== Ftrace ===
|
||||
The "simple" backend writes binary trace logs to a file from a thread, making
|
||||
it lower overhead than the "log" backend. A Python API is available for writing
|
||||
offline trace file analysis scripts. It may not be as powerful as
|
||||
platform-specific or third-party trace backends but it is portable and has no
|
||||
special library dependencies.
|
||||
|
||||
Monitor commands
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
* ``trace-file on|off|flush|set <path>``
|
||||
Enable/disable/flush the trace file or set the trace file name.
|
||||
|
||||
Analyzing trace files
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The "simple" backend produces binary trace files that can be formatted with the
|
||||
simpletrace.py script. The script takes the "trace-events-all" file and the
|
||||
binary trace::
|
||||
|
||||
./scripts/simpletrace.py trace-events-all trace-12345
|
||||
|
||||
You must ensure that the same "trace-events-all" file was used to build QEMU,
|
||||
otherwise trace event declarations may have changed and output will not be
|
||||
consistent.
|
||||
|
||||
Ftrace
|
||||
------
|
||||
|
||||
The "ftrace" backend writes trace data to ftrace marker. This effectively
|
||||
sends trace events to ftrace ring buffer, and you can compare qemu trace
|
||||
data and kernel(especially kvm.ko when using KVM) trace data.
|
||||
|
||||
if you use KVM, enable kvm events in ftrace:
|
||||
if you use KVM, enable kvm events in ftrace::
|
||||
|
||||
# echo 1 > /sys/kernel/debug/tracing/events/kvm/enable
|
||||
|
||||
After running qemu by root user, you can get the trace:
|
||||
After running qemu by root user, you can get the trace::
|
||||
|
||||
# cat /sys/kernel/debug/tracing/trace
|
||||
|
||||
Restriction: "ftrace" backend is restricted to Linux only.
|
||||
|
||||
=== Syslog ===
|
||||
Syslog
|
||||
------
|
||||
|
||||
The "syslog" backend sends trace events using the POSIX syslog API. The log
|
||||
is opened specifying the LOG_DAEMON facility and LOG_PID option (so events
|
||||
|
@ -246,24 +301,8 @@ NOTE: syslog may squash duplicate consecutive trace events and apply rate
|
|||
|
||||
Restriction: "syslog" backend is restricted to POSIX compliant OS.
|
||||
|
||||
==== Monitor commands ====
|
||||
|
||||
* trace-file on|off|flush|set <path>
|
||||
Enable/disable/flush the trace file or set the trace file name.
|
||||
|
||||
==== Analyzing trace files ====
|
||||
|
||||
The "simple" backend produces binary trace files that can be formatted with the
|
||||
simpletrace.py script. The script takes the "trace-events-all" file and the
|
||||
binary trace:
|
||||
|
||||
./scripts/simpletrace.py trace-events-all trace-12345
|
||||
|
||||
You must ensure that the same "trace-events-all" file was used to build QEMU,
|
||||
otherwise trace event declarations may have changed and output will not be
|
||||
consistent.
|
||||
|
||||
=== LTTng Userspace Tracer ===
|
||||
LTTng Userspace Tracer
|
||||
----------------------
|
||||
|
||||
The "ust" backend uses the LTTng Userspace Tracer library. There are no
|
||||
monitor commands built into QEMU, instead UST utilities should be used to list,
|
||||
|
@ -275,43 +314,44 @@ lttng-sessiond daemon for the current user prior to running any instance of
|
|||
QEMU.
|
||||
|
||||
While running an instrumented QEMU, LTTng should be able to list all available
|
||||
events:
|
||||
events::
|
||||
|
||||
lttng list -u
|
||||
|
||||
Create tracing session:
|
||||
Create tracing session::
|
||||
|
||||
lttng create mysession
|
||||
|
||||
Enable events:
|
||||
Enable events::
|
||||
|
||||
lttng enable-event qemu:g_malloc -u
|
||||
|
||||
Where the events can either be a comma-separated list of events, or "-a" to
|
||||
enable all tracepoint events. Start and stop tracing as needed:
|
||||
enable all tracepoint events. Start and stop tracing as needed::
|
||||
|
||||
lttng start
|
||||
lttng stop
|
||||
|
||||
View the trace:
|
||||
View the trace::
|
||||
|
||||
lttng view
|
||||
|
||||
Destroy tracing session:
|
||||
Destroy tracing session::
|
||||
|
||||
lttng destroy
|
||||
|
||||
Babeltrace can be used at any later time to view the trace:
|
||||
Babeltrace can be used at any later time to view the trace::
|
||||
|
||||
babeltrace $HOME/lttng-traces/mysession-<date>-<time>
|
||||
|
||||
=== SystemTap ===
|
||||
SystemTap
|
||||
---------
|
||||
|
||||
The "dtrace" backend uses DTrace sdt probes but has only been tested with
|
||||
SystemTap. When SystemTap support is detected a .stp file with wrapper probes
|
||||
is generated to make use in scripts more convenient. This step can also be
|
||||
performed manually after a build in order to change the binary name in the .stp
|
||||
probes:
|
||||
probes::
|
||||
|
||||
scripts/tracetool.py --backends=dtrace --format=stap \
|
||||
--binary path/to/qemu-binary \
|
||||
|
@ -325,12 +365,14 @@ To facilitate simple usage of systemtap where there merely needs to be printf
|
|||
logging of certain probes, a helper script "qemu-trace-stap" is provided.
|
||||
Consult its manual page for guidance on its usage.
|
||||
|
||||
== Trace event properties ==
|
||||
Trace event properties
|
||||
======================
|
||||
|
||||
Each event in the "trace-events-all" file can be prefixed with a space-separated
|
||||
list of zero or more of the following event properties.
|
||||
|
||||
=== "disable" ===
|
||||
"disable"
|
||||
---------
|
||||
|
||||
If a specific trace event is going to be invoked a huge number of times, this
|
||||
might have a noticeable performance impact even when the event is
|
||||
|
@ -348,6 +390,8 @@ guard such computations, so they are skipped if the event has been either
|
|||
compile-time disabled or run-time disabled. If the event is compile-time
|
||||
disabled, this check will have no performance impact.
|
||||
|
||||
::
|
||||
|
||||
#include "trace.h" /* needed for trace event prototype */
|
||||
|
||||
void *qemu_vmalloc(size_t size)
|
||||
|
@ -367,7 +411,8 @@ disabled, this check will have no performance impact.
|
|||
return ptr;
|
||||
}
|
||||
|
||||
=== "tcg" ===
|
||||
"tcg"
|
||||
-----
|
||||
|
||||
Guest code generated by TCG can be traced by defining an event with the "tcg"
|
||||
event property. Internally, this property generates two events:
|
||||
|
@ -384,11 +429,11 @@ mix of native and TCG types, and "trace_<eventname>_tcg" will gracefully forward
|
|||
them to the "<eventname>_trans" and "<eventname>_exec" events. Since TCG values
|
||||
are not known at translation time, these are ignored by the "<eventname>_trans"
|
||||
event. Because of this, the entry in the "trace-events" file needs two printing
|
||||
formats (separated by a comma):
|
||||
formats (separated by a comma)::
|
||||
|
||||
tcg foo(uint8_t a1, TCGv_i32 a2) "a1=%d", "a1=%d a2=%d"
|
||||
|
||||
For example:
|
||||
For example::
|
||||
|
||||
#include "trace-tcg.h"
|
||||
|
||||
|
@ -399,15 +444,16 @@ For example:
|
|||
trace_foo_tcg(a1, a2);
|
||||
}
|
||||
|
||||
This will immediately call:
|
||||
This will immediately call::
|
||||
|
||||
void trace_foo_trans(uint8_t a1);
|
||||
|
||||
and will generate the TCG code to call:
|
||||
and will generate the TCG code to call::
|
||||
|
||||
void trace_foo(uint8_t a1, uint32_t a2);
|
||||
|
||||
=== "vcpu" ===
|
||||
"vcpu"
|
||||
------
|
||||
|
||||
Identifies events that trace vCPU-specific information. It implicitly adds a
|
||||
"CPUState*" argument, and extends the tracing print format to show the vCPU
|
||||
|
@ -418,13 +464,13 @@ points to the vCPU when guest code is executed (usually the "cpu_env" variable).
|
|||
The "tcg" and "vcpu" properties are currently only honored in the root
|
||||
./trace-events file.
|
||||
|
||||
The following example events:
|
||||
The following example events::
|
||||
|
||||
foo(uint32_t a) "a=%x"
|
||||
vcpu bar(uint32_t a) "a=%x"
|
||||
tcg vcpu baz(uint32_t a) "a=%x", "a=%x"
|
||||
|
||||
Can be used as:
|
||||
Can be used as::
|
||||
|
||||
#include "trace-tcg.h"
|
||||
|
||||
|
@ -442,7 +488,7 @@ Can be used as:
|
|||
}
|
||||
|
||||
If the translating vCPU has address 0xc1 and code is later executed by vCPU
|
||||
0xc2, this would be an example output:
|
||||
0xc2, this would be an example output::
|
||||
|
||||
// at guest code translation
|
||||
foo a=0xd1
|
|
@ -74,7 +74,7 @@ void error_init(const char *argv0);
|
|||
|
||||
const char *error_get_progname(void);
|
||||
|
||||
extern bool error_with_timestamp;
|
||||
extern bool message_with_timestamp;
|
||||
extern bool error_with_guestname;
|
||||
extern const char *error_guest_name;
|
||||
|
||||
|
|
28
meson.build
28
meson.build
|
@ -1632,6 +1632,31 @@ tracetool = [
|
|||
python, files('scripts/tracetool.py'),
|
||||
'--backend=' + config_host['TRACE_BACKENDS']
|
||||
]
|
||||
tracetool_depends = files(
|
||||
'scripts/tracetool/backend/log.py',
|
||||
'scripts/tracetool/backend/__init__.py',
|
||||
'scripts/tracetool/backend/dtrace.py',
|
||||
'scripts/tracetool/backend/ftrace.py',
|
||||
'scripts/tracetool/backend/simple.py',
|
||||
'scripts/tracetool/backend/syslog.py',
|
||||
'scripts/tracetool/backend/ust.py',
|
||||
'scripts/tracetool/format/tcg_h.py',
|
||||
'scripts/tracetool/format/ust_events_c.py',
|
||||
'scripts/tracetool/format/ust_events_h.py',
|
||||
'scripts/tracetool/format/__init__.py',
|
||||
'scripts/tracetool/format/d.py',
|
||||
'scripts/tracetool/format/tcg_helper_c.py',
|
||||
'scripts/tracetool/format/simpletrace_stap.py',
|
||||
'scripts/tracetool/format/c.py',
|
||||
'scripts/tracetool/format/h.py',
|
||||
'scripts/tracetool/format/tcg_helper_h.py',
|
||||
'scripts/tracetool/format/log_stap.py',
|
||||
'scripts/tracetool/format/stap.py',
|
||||
'scripts/tracetool/format/tcg_helper_wrapper_h.py',
|
||||
'scripts/tracetool/__init__.py',
|
||||
'scripts/tracetool/transform.py',
|
||||
'scripts/tracetool/vcpu.py'
|
||||
)
|
||||
|
||||
qemu_version_cmd = [find_program('scripts/qemu-version.sh'),
|
||||
meson.current_source_dir(),
|
||||
|
@ -2219,7 +2244,8 @@ foreach target : target_dirs
|
|||
'--target-type=' + target_type,
|
||||
'--probe-prefix=qemu.' + target_type + '.' + target_name,
|
||||
'@INPUT@', '@OUTPUT@'
|
||||
])
|
||||
],
|
||||
depend_files: tracetool_depends)
|
||||
endforeach
|
||||
endif
|
||||
endforeach
|
||||
|
|
|
@ -174,7 +174,9 @@ def process(events, log, analyzer, read_header=True):
|
|||
if read_header:
|
||||
read_trace_header(log)
|
||||
|
||||
dropped_event = Event.build("Dropped_Event(uint64_t num_events_dropped)")
|
||||
frameinfo = inspect.getframeinfo(inspect.currentframe())
|
||||
dropped_event = Event.build("Dropped_Event(uint64_t num_events_dropped)",
|
||||
frameinfo.lineno + 1, frameinfo.filename)
|
||||
edict = {"dropped": dropped_event}
|
||||
idtoname = {dropped_event_id: "dropped"}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ PUBLIC = True
|
|||
|
||||
def generate_h_begin(events, group):
|
||||
out('#include "qemu/log-for-trace.h"',
|
||||
'#include "qemu/error-report.h"',
|
||||
'')
|
||||
|
||||
|
||||
|
@ -35,14 +36,20 @@ def generate_h(event, group):
|
|||
cond = "trace_event_get_state(%s)" % ("TRACE_" + event.name.upper())
|
||||
|
||||
out(' if (%(cond)s && qemu_loglevel_mask(LOG_TRACE)) {',
|
||||
' struct timeval _now;',
|
||||
' gettimeofday(&_now, NULL);',
|
||||
' if (message_with_timestamp) {',
|
||||
' struct timeval _now;',
|
||||
' gettimeofday(&_now, NULL);',
|
||||
'#line %(event_lineno)d "%(event_filename)s"',
|
||||
' qemu_log("%%d@%%zu.%%06zu:%(name)s " %(fmt)s "\\n",',
|
||||
' qemu_get_thread_id(),',
|
||||
' (size_t)_now.tv_sec, (size_t)_now.tv_usec',
|
||||
' %(argnames)s);',
|
||||
' qemu_log("%%d@%%zu.%%06zu:%(name)s " %(fmt)s "\\n",',
|
||||
' qemu_get_thread_id(),',
|
||||
' (size_t)_now.tv_sec, (size_t)_now.tv_usec',
|
||||
' %(argnames)s);',
|
||||
'#line %(out_next_lineno)d "%(out_filename)s"',
|
||||
' } else {',
|
||||
'#line %(event_lineno)d "%(event_filename)s"',
|
||||
' qemu_log("%(name)s " %(fmt)s "\\n"%(argnames)s);',
|
||||
'#line %(out_next_lineno)d "%(out_filename)s"',
|
||||
' }',
|
||||
' }',
|
||||
cond=cond,
|
||||
event_lineno=event.lineno,
|
||||
|
|
|
@ -54,6 +54,7 @@ def c_fmt_to_stap(fmt):
|
|||
else:
|
||||
if state == STATE_MACRO:
|
||||
bits.append(c_macro_to_format(macro))
|
||||
macro = ""
|
||||
state = STATE_LITERAL
|
||||
elif fmt[i] == ' ' or fmt[i] == '\t':
|
||||
if state == STATE_MACRO:
|
||||
|
@ -77,7 +78,12 @@ def c_fmt_to_stap(fmt):
|
|||
elif state == STATE_LITERAL:
|
||||
bits.append(literal)
|
||||
|
||||
fmt = re.sub("%(\d*)z(x|u|d)", "%\\1\\2", "".join(bits))
|
||||
# All variables in systemtap are 64-bit in size
|
||||
# The "%l" integer size qualifier is thus redundant
|
||||
# and "%ll" is not valid at all. Similarly the size_t
|
||||
# based "%z" size qualifier is not valid. We just
|
||||
# strip all size qualifiers for sanity.
|
||||
fmt = re.sub("%(\d*)(l+|z)(x|u|d)", "%\\1\\3", "".join(bits))
|
||||
return fmt
|
||||
|
||||
def generate(events, backend, group):
|
||||
|
|
|
@ -737,7 +737,7 @@ static void realtime_init(void)
|
|||
|
||||
static void configure_msg(QemuOpts *opts)
|
||||
{
|
||||
error_with_timestamp = qemu_opt_get_bool(opts, "timestamp", false);
|
||||
message_with_timestamp = qemu_opt_get_bool(opts, "timestamp", false);
|
||||
error_with_guestname = qemu_opt_get_bool(opts, "guest-name", false);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,17 +12,20 @@ foreach dir : [ '.' ] + trace_events_subdirs
|
|||
trace_h = custom_target(fmt.format('trace', 'h'),
|
||||
output: fmt.format('trace', 'h'),
|
||||
input: trace_events_file,
|
||||
command: [ tracetool, group, '--format=h', '@INPUT@', '@OUTPUT@' ])
|
||||
command: [ tracetool, group, '--format=h', '@INPUT@', '@OUTPUT@' ],
|
||||
depend_files: tracetool_depends)
|
||||
genh += trace_h
|
||||
trace_c = custom_target(fmt.format('trace', 'c'),
|
||||
output: fmt.format('trace', 'c'),
|
||||
input: trace_events_file,
|
||||
command: [ tracetool, group, '--format=c', '@INPUT@', '@OUTPUT@' ])
|
||||
command: [ tracetool, group, '--format=c', '@INPUT@', '@OUTPUT@' ],
|
||||
depend_files: tracetool_depends)
|
||||
if 'CONFIG_TRACE_UST' in config_host
|
||||
trace_ust_h = custom_target(fmt.format('trace-ust', 'h'),
|
||||
output: fmt.format('trace-ust', 'h'),
|
||||
input: trace_events_file,
|
||||
command: [ tracetool, group, '--format=ust-events-h', '@INPUT@', '@OUTPUT@' ])
|
||||
command: [ tracetool, group, '--format=ust-events-h', '@INPUT@', '@OUTPUT@' ],
|
||||
depend_files: tracetool_depends)
|
||||
trace_ss.add(trace_ust_h, lttng, urcubp)
|
||||
genh += trace_ust_h
|
||||
endif
|
||||
|
@ -31,7 +34,8 @@ foreach dir : [ '.' ] + trace_events_subdirs
|
|||
trace_dtrace = custom_target(fmt.format('trace-dtrace', 'dtrace'),
|
||||
output: fmt.format('trace-dtrace', 'dtrace'),
|
||||
input: trace_events_file,
|
||||
command: [ tracetool, group, '--format=d', '@INPUT@', '@OUTPUT@' ])
|
||||
command: [ tracetool, group, '--format=d', '@INPUT@', '@OUTPUT@' ],
|
||||
depend_files: tracetool_depends)
|
||||
trace_dtrace_h = custom_target(fmt.format('trace-dtrace', 'h'),
|
||||
output: fmt.format('trace-dtrace', 'h'),
|
||||
input: trace_dtrace,
|
||||
|
@ -66,7 +70,8 @@ foreach d : [
|
|||
gen = custom_target(d[0],
|
||||
output: d[0],
|
||||
input: meson.source_root() / 'trace-events',
|
||||
command: [ tracetool, '--group=root', '--format=@0@'.format(d[1]), '@INPUT@', '@OUTPUT@' ])
|
||||
command: [ tracetool, '--group=root', '--format=@0@'.format(d[1]), '@INPUT@', '@OUTPUT@' ],
|
||||
depend_files: tracetool_depends)
|
||||
specific_ss.add(when: 'CONFIG_TCG', if_true: gen)
|
||||
endforeach
|
||||
|
||||
|
@ -74,11 +79,13 @@ if 'CONFIG_TRACE_UST' in config_host
|
|||
trace_ust_all_h = custom_target('trace-ust-all.h',
|
||||
output: 'trace-ust-all.h',
|
||||
input: trace_events_files,
|
||||
command: [ tracetool, '--group=all', '--format=ust-events-h', '@INPUT@', '@OUTPUT@' ])
|
||||
command: [ tracetool, '--group=all', '--format=ust-events-h', '@INPUT@', '@OUTPUT@' ],
|
||||
depend_files: tracetool_depends)
|
||||
trace_ust_all_c = custom_target('trace-ust-all.c',
|
||||
output: 'trace-ust-all.c',
|
||||
input: trace_events_files,
|
||||
command: [ tracetool, '--group=all', '--format=ust-events-c', '@INPUT@', '@OUTPUT@' ])
|
||||
command: [ tracetool, '--group=all', '--format=ust-events-c', '@INPUT@', '@OUTPUT@' ],
|
||||
depend_files: tracetool_depends)
|
||||
trace_ss.add(trace_ust_all_h, trace_ust_all_c)
|
||||
genh += trace_ust_all_h
|
||||
endif
|
||||
|
|
|
@ -25,7 +25,7 @@ typedef enum {
|
|||
} report_type;
|
||||
|
||||
/* Prepend timestamp to messages */
|
||||
bool error_with_timestamp;
|
||||
bool message_with_timestamp;
|
||||
bool error_with_guestname;
|
||||
const char *error_guest_name;
|
||||
|
||||
|
@ -208,7 +208,7 @@ static void vreport(report_type type, const char *fmt, va_list ap)
|
|||
GTimeVal tv;
|
||||
gchar *timestr;
|
||||
|
||||
if (error_with_timestamp && !monitor_cur()) {
|
||||
if (message_with_timestamp && !monitor_cur()) {
|
||||
g_get_current_time(&tv);
|
||||
timestr = g_time_val_to_iso8601(&tv);
|
||||
error_printf("%s ", timestr);
|
||||
|
|
Loading…
Reference in a new issue