* [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines
@ 2013-04-21 19:11 Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 01/24] instrument: Add documentation Lluís Vilanova
` (24 more replies)
0 siblings, 25 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:11 UTC (permalink / raw)
To: qemu-devel
TODO: Operations 'instr_load' and 'instr_unload' are not thread safe.
(qemu_cpu_kick?)
TODO: Do cmdline actions have to be implemented on top of QMP routines?
TODO: HMP and QMP interfaces only accept one argument to "instr-load".
TODO: Replace programmatic 'InstrLoadError' in favour of QAPI's 'InstrLoadCode'?
(harder to find using code navigation tools, as it's auto-generated; but
provides a single point to manage the enumeration values, which is less
error-prone)
The whole set of patch series is available at:
https://projects.gso.ac.upc.edu/projects/qemu-dbi
Adds the "instrument" event property to declare which tracing events in QEMU
must be instrumentable. Still, in case the user only wants to wrap around the
tracing events, the original tracing implementation is accessible through the
appropriate routines.
The instrumentation can be performed either through a dynamically-loaded library
or through user-provided code that is compiled into QEMU itself (useful when
instrumenting high-frequency events, as the fast-path of the instrumentation can
be inlined into QEMU).
As a side-effect this series adds an API for the instrumentation code to have
some basic interaction with QEMU.
See the documentation added in the first patch for more information.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Changes in v3:
* Rename QAPI 'input' primitive to 'include' (Eric Blake).
* Use 'error_setg' instead of 'errot_set' (Eric Blake).
* Added copyright and fixed docs on "instrument/qapi-schema.json" (Eric Blake).
* Rename internal 'args' variable in "qapi-commands.py" to 'args_'.
* Rename argument 'iargs' in QAPI command 'instr-load' to 'args', and make it
optional (Eric Blake).
* Fixed loop in 'qmp_instr_laod'.
* Revamped QAPI commands "instr-load" and "instr-unload" to use a proper return
value.
* Fixed QMP arguments for "instr-load".
* Added 'instr_type' and 'instr_active'.
* Use 'instr_type' instead of CONFIG_TRACE_INSTRUMENT* whenever possible.
* Change QAPI interfaces to appear as if providing support for multiple
libraries (Eric Blake).
* Reimplemented HMP commands on top of QMP commands.
Changes in v2:
* Rebased on latest master (e2ec3f9).
* Added "libqemutools.a".
* Have 'tracetool' forbid certain event argument names.
* Fixed title in path for "linux-headers" include path (Peter Maydell).
* Small fixes to qapi/qmp (Eric Blake).
* Have 'qi_init' accept a list of strings as arguments (Eric Blake)
Lluís Vilanova (24):
instrument: Add documentation
trace: [simple] Do not include "trace/simple.h" in generated tracer headers
trace: Let the user specify her own trace-events file
tracetool: Use method 'Event.api' to get the name of public routines
trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops
instrument: [none] Add null instrumentation
system: [linux] Use absolute include path for linux-headers
instrument: [static] Call statically linked user-provided routines
build: Add variable 'tools-obj-y' for tool-only files
instrument: [dynamic] Call dynamically linked user-provided routines
qapi: Add a primitive to include other files from a QAPI schema file
qapi: [trivial] Set the input root directory when parsing QAPI files
qapi: [trivial] Allow user to use 'args' as an argument name
instrument: Add internal control interface
instrument: [qmp, qapi] Add control interface
instrument: [hmp] Add control interface
Let makefiles add entries to the set of target architecture objects
instrument: Add commandline options to start with an instrumentation library
instrument: Add client-side API to enumerate events
instrument: Add client-side API to control tracing state of events
instrument: Add client-side API to control event instrumentation
build: Fix installation of target-dependant files
instrument: Install headers for dynamic instrumentation clients
trace: Do not use the word 'new' in event arguments
.gitignore | 4
Makefile | 57 +++
Makefile.objs | 9
Makefile.target | 7
bsd-user/main.c | 22 +
bsd-user/syscall.c | 5
configure | 96 +++++
docs/instrumentation.txt | 496 +++++++++++++++++++++++++++
docs/tracing.txt | 9
hmp-commands.hx | 42 ++
hw/virtio/virtio.c | 1
include/trace.h | 2
instrument/Makefile.objs | 87 +++++
instrument/api-control.c | 14 +
instrument/api-trace.c | 14 +
instrument/cmdline.c | 91 +++++
instrument/cmdline.h | 52 +++
instrument/control-internal.h | 40 ++
instrument/control.c | 226 ++++++++++++
instrument/control.h | 152 ++++++++
instrument/hmp.c | 79 ++++
instrument/hmp.h | 21 +
instrument/qapi-schema.json | 150 ++++++++
instrument/qemu-instr/control-internal.h | 69 ++++
instrument/qemu-instr/control.h | 199 +++++++++++
instrument/qemu-instr/trace-internal.h | 32 ++
instrument/qemu-instr/trace.h | 91 +++++
instrument/qemu-instr/visibility-internal.h | 94 +++++
instrument/qmp.c | 78 ++++
libcacard/Makefile | 4
linux-user/main.c | 31 ++
linux-user/syscall.c | 4
monitor.c | 5
qapi-schema.json | 2
qemu-options.hx | 18 +
qmp-commands.hx | 71 ++++
qmp.c | 4
rules.mak | 3
scripts/qapi-commands.py | 18 +
scripts/qapi-types.py | 10 -
scripts/qapi-visit.py | 10 -
scripts/qapi.py | 12 +
scripts/tracetool.py | 14 +
scripts/tracetool/__init__.py | 44 ++
scripts/tracetool/backend/dtrace.py | 6
scripts/tracetool/backend/instr_dynamic.py | 93 +++++
scripts/tracetool/backend/instr_none.py | 44 ++
scripts/tracetool/backend/instr_static.py | 82 ++++
scripts/tracetool/backend/simple.py | 13 -
scripts/tracetool/backend/stderr.py | 5
scripts/tracetool/backend/ust.py | 8
scripts/tracetool/format/api_c.py | 24 +
scripts/tracetool/format/api_events_h.py | 56 +++
scripts/tracetool/format/api_h.py | 39 ++
scripts/tracetool/format/events_c.py | 42 ++
scripts/tracetool/format/h.py | 15 +
scripts/tracetool/format/qemu_h.py | 68 ++++
trace-events | 8
trace/Makefile.objs | 10 -
trace/control-internal.h | 4
trace/control.c | 4
trace/control.h | 9
trace/default.c | 4
trace/event-internal.h | 17 +
trace/simple.c | 6
trace/simple.h | 1
trace/stderr.c | 4
vl.c | 41 ++
68 files changed, 3016 insertions(+), 76 deletions(-)
create mode 100644 docs/instrumentation.txt
create mode 100644 instrument/Makefile.objs
create mode 100644 instrument/api-control.c
create mode 100644 instrument/api-trace.c
create mode 100644 instrument/cmdline.c
create mode 100644 instrument/cmdline.h
create mode 100644 instrument/control-internal.h
create mode 100644 instrument/control.c
create mode 100644 instrument/control.h
create mode 100644 instrument/hmp.c
create mode 100644 instrument/hmp.h
create mode 100644 instrument/qapi-schema.json
create mode 100644 instrument/qemu-instr/control-internal.h
create mode 100644 instrument/qemu-instr/control.h
create mode 100644 instrument/qemu-instr/trace-internal.h
create mode 100644 instrument/qemu-instr/trace.h
create mode 100644 instrument/qemu-instr/visibility-internal.h
create mode 100644 instrument/qmp.c
create mode 100644 scripts/tracetool/backend/instr_dynamic.py
create mode 100644 scripts/tracetool/backend/instr_none.py
create mode 100644 scripts/tracetool/backend/instr_static.py
create mode 100644 scripts/tracetool/format/api_c.py
create mode 100644 scripts/tracetool/format/api_events_h.py
create mode 100644 scripts/tracetool/format/api_h.py
create mode 100644 scripts/tracetool/format/qemu_h.py
To: qemu-devel@nongnu.org
Cc: Stefan Hajnoczi <stefanha@gmail.com>
Cc: Eric Blake <eblake@redhat.com>
^ permalink raw reply [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 01/24] instrument: Add documentation
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
@ 2013-04-21 19:11 ` Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 02/24] trace: [simple] Do not include "trace/simple.h" in generated tracer headers Lluís Vilanova
` (23 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:11 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
docs/instrumentation.txt | 496 ++++++++++++++++++++++++++++++++++++++++++++++
docs/tracing.txt | 9 +
2 files changed, 505 insertions(+)
create mode 100644 docs/instrumentation.txt
diff --git a/docs/instrumentation.txt b/docs/instrumentation.txt
new file mode 100644
index 0000000..e55aea3
--- /dev/null
+++ b/docs/instrumentation.txt
@@ -0,0 +1,496 @@
+= Trace instrumentation =
+
+== Introduction ==
+
+This document describes how the events provided by the tracing infrastructure
+(described in the document "tracing.txt") can be extended with user-provided
+code.
+
+Instrumentation comes in two (three) flavours; dynamic and static (and none at
+all). Both provide means for you to associate code to specific tracing events
+that have the "instrument" property in the "trace-events" file.
+
+As opposed to using tracing backends that can dynamically load user-defined code
+into the tracing events (e.g., "dtrace"), trace instrumentation provides a
+well-defined API for the user-provided code to interact with QEMU.
+
+In the case of dynamic instrumentation, you can load and unload a shared object
+(a dynamic library) to establish your instrumentation callbacks. This mechanism
+provides a trade-off between performance and the simplicity of reusing the same
+QEMU binary for different instrumentation scenarios.
+
+In the case of static instrumentation, you must provide a static library that is
+compiled directly into QEMU. This mechanism can provide better performance, at
+the expense of having to recompile QEMU for each different instrumentation
+scenario.
+
+
+
+== Selecting the events to instrument ==
+
+You must declare which events to instrument before compiling QEMU.
+
+This can be done by adding the "instrument" property (and removing the "disable"
+property, if any) in the events listed in the "trace-events" file.
+
+In order to avoid modifying the QEMU sources, you can simply create a new
+trace-events file with your modifications:
+
+ cp /path/to/qemu-source/trace-events /tmp/trace-events
+ sed -i -e "s/qemu_vmalloc(/instrument qemu_vmalloc(/g" /tmp/trace-events
+
+Note: You must remove the "disable" property (if any) if you want to add the
+"instrument" property of an event, as these are mutually exclusive.
+
+
+== Pre-defined instrumentation callbacks ==
+
+If you are using dynamic auto-instrumentation (see 'QI_CTRL_INSTR_AUTO' below)
+or static instrumentation, your callbacks must follow a specific naming scheme:
+'qi_event_${event}'.
+
+Two other default callbacks are provided by QEMU:
+
+* 'qi_event_${event}_nop'
+
+ Does nothing.
+
+ This is the default callback for all instrumentable events when using dynamic
+ instrumentation.
+
+* 'qi_event_${event}_trace'
+
+ Call QEMU's tracing backend. That is, trace the event using whatever tracing
+ backend QEMU has been configured with.
+
+ See document "tracing.txt" to learn more about tracing events with QEMU (e.g.,
+ write events into a file or print them on the screen).
+
+All these callbacks are declared in the "qemu-instr/events.h" header.
+
+
+== Dynamic instrumentation ==
+
+Dynamic instrumentation is based on dynamically loadable libraries that can be
+loaded and unloaded from QEMU at any point in time. This also includes an API to
+dynamically set the per-event tracing instrumentation callback at any point in
+time.
+
+Being able to load and unload an instrumentation library provides a comfortable
+mechanism to test multiple instrumentation approaches without having to
+recompile or restart QEMU between instrumentation tests.
+
+Note: By default, events are set to use the 'qi_event_${event}_nop' callback.
+
+
+=== Example ===
+
+1. Select the events to instrument in file "trace-events" (see above).
+
+2. Build QEMU with dynamic trace intrumentation:
+
+ mkdir -p /tmp/qemu-build
+ cd /tmp/qemu-build
+ /path/to/qemu-source/configure \
+ --with-trace-events=/tmp/trace-events \
+ --with-trace-instrument=dynamic \
+ --enable-trace-backend=stderr \
+ --prefix=/tmp/qemu-install
+ make
+ make install
+
+3. Create the "Makefile" to build the instrumentation library:
+
+ mkdir -p /tmp/my-dinstrument
+
+ cat > /tmp/my-dinstrument/Makefile <<EOF
+ QEMU_PATH=/tmp/qemu-install/
+
+ CFLAGS += -O3
+ CFLAGS += -Werror -Wall
+ CFLAGS += -I$(QEMU_PATH)/include
+
+ all: libtrace-instrument.la
+
+ libtrace-instrument.la: instrument.lo
+ libtool --mode=link --tag=CC $(CC) -module -rpath /usr/local/lib -o $@ $^
+
+ %.lo: %.c
+ libtool --mode=compile --tag=CC $(CC) $(CFLAGS) -c $^
+
+ clean:
+ $(RM) -f *.o *.so *.lo
+ $(RM) -Rf .libs
+ EOF
+
+4. Create the necessary source code files to implement your event instrumentation:
+
+ cat > /tmp/my-dinstrument/instrument.c <<EOF
+ #include <stdio.h>
+ #include <assert.h>
+
+ /* get event declarations */
+ #include <qemu-instr/events.h>
+
+ /* enumerate events and manipulate their instrumentation callbacks */
+ #include <qemu-instr/control.h>
+
+ /* manipulate the dynamic tracing state of events */
+ #include <qemu-instr/trace.h>
+
+ /* define instrumentation callbacks during event execution:
+ * qi_event_${event}
+ */
+
+ /* called every time QEMU traces event 'qemu_vmalloc' */
+ void qi_event_qemu_vmalloc(size_t size, void *ptr)
+ {
+ fprintf(stderr, "qemu_vmalloc! [instrument]\n");
+
+ /* call the original tracing routine */
+ qi_event_qemu_vmalloc_trace(size, ptr);
+
+ /* disable instrumentation and tracing after 10 calls */
+ static int c = 0;
+ if (c++ > 10) {
+ QIEvent *ev = qi_ctrl_event_id(QI_EVENT_QEMU_VMALLOC);
+ qi_ctrl_event_set(ev, QI_CTRL_INSTR_NOP);
+ qi_trace_event_set_state_dynamic(ev, false);
+ }
+ }
+
+
+
+ /* mandatory initialization callback */
+ void qi_init(int argc, const char *argv)
+ {
+ int i;
+ fprintf(stderr, "init!\n");
+ fprintf(stderr, " argc :: %d\n", argc);
+ for (i = 0; i < argc; i++) {
+ fprintf(stderr, " -> %s\n", argv[i]);
+ }
+
+ /* iterate on all trace events */
+ QIEvent *ev = NULL;
+ while ((ev = qi_ctrl_event_pattern("*", ev)) != NULL) {
+
+ /* auto-instrument all events instrumentable at execution time */
+ if (qi_ctrl_event_is_available(ev)) {
+
+ printf("[exec] instrumenting '%s'\n",
+ qi_ctrl_event_get_name(ev));
+
+ /* auto-detect instrumentation routines */
+ bool instrumented = qi_ctrl_event_set(ev, QI_CTRL_INSTR_AUTO);
+ assert(instrumented);
+
+ /* activate tracing for that event
+ * (otherwise qi_event_${event}_trace does nothing when using
+ * the 'stderr' backend)
+ */
+ qi_trace_event_set_state_dynamic(ev, true);
+ }
+ }
+ }
+
+ /* mandatory finalization callback */
+ void qi_fini(void)
+ {
+ fprintf(stderr, "fini!\n");
+
+ /* ensure all tracing is disabled */
+ QIEvent *ev = NULL;
+ while ((ev = qi_ctrl_event_pattern("*", ev)) != NULL) {
+ qi_trace_event_set_state_dynamic(ev, false);
+ }
+
+ /* instrumentation callbacks are automatically reset by QEMU */
+ }
+ EOF
+
+5. Compile the instrumentation library:
+
+ make -C /tmp/my-dinstrument
+
+6. Start QEMU with the instrumentation library:
+
+ /tmp/qemu-install/bin/qemu-system-x86_64 \
+ -instr file=/tmp/my-dinstrument/.libs/libtrace-instrument.so
+
+
+Alternatively, you can explicitly set which events and with which callback you
+want to instrument them:
+
+ /* ... */
+ void qi_init(int argc, const char *argv)
+ {
+ int i;
+ fprintf(stderr, "init!\n");
+ fprintf(stderr, " argc :: %d\n", argc);
+ for (i = 0; i < argc; i++) {
+ fprintf(stderr, " -> %s\n", argv[i]);
+ }
+
+ QIEvent *ev;
+ bool instrumented;
+
+ /* NOTE: the callbacks can be pointers to arbitrary routines;
+ * there's no need to follow the 'qi_event_${event}' naming
+ * scheme if you're not using QI_CTRL_INSTR_AUTO.
+ */
+
+ ev = qi_ctrl_event_id(QI_EVENT_QEMU_VMALLOC);
+ assert(ev);
+ printf("[exec] instrumenting '%s'\n",
+ qi_ctrl_event_get_name(ev));
+ instrumented = qi_ctrl_event_set(ev, execute_qemu_vmalloc);
+ assert(instrumented);
+ qi_trace_event_set_state_dynamic(ev, true);
+ }
+ /* ... */
+
+
+
+== Static instrumentation ==
+
+Static instrumentation relies on you providing a directory that QEMU will
+compile on to produce a static library. The instrumentation library is compiled
+during the compilation of QEMU's target-dependant code, and the directory you
+provided will be present on the include path. This static library will then be
+linked into QEMU itself.
+
+This mechanism allows you to inline your own instrumentation code into the QEMU
+tracing routines. This requires the (partial) recompilation of QEMU whenever the
+instrumentation analysis code changes, and is thus intended for
+performance-critical event instrumentation analysis.
+
+For this reason, you can prototype your analysis using dynamic instrumentation
+before moving to static instrumentation.
+
+
+=== Example ===
+
+1. Select the events to instrument in file "trace-events" (see above).
+
+2. Create the "Makefile" to build the instrumentation library:
+
+ mkdir -p /tmp/my-sinstrument
+
+ cat > /tmp/my-sinstrument/Makefile <<EOF
+ include $(BUILD_DIR)/config-host.mak
+ include $(BUILD_DIR)/$(TARGET_DIR)../config-target.mak
+ include $(SRC_PATH)/rules.mak
+
+ vpath %.c /tmp/my-sinstrument
+
+ libtrace-instrument.a: CFLAGS += -I$(SRC_PATH)/instrument
+ libtrace-instrument.a: CFLAGS += -I$(BUILD_DIR)/instrument
+ libtrace-instrument.a: instrument.o
+
+ # Include automatically generated dependency files
+ -include $(wildcard *.d)
+ EOF
+
+3. Create the necessary source code files to implement the event instrumentation.
+
+ The same code on the dynamic instrumentation example can be used, eliminating
+ calls to 'qi_ctrl_event_set'.
+
+ See below for a description on how to reuse the same code to work with both
+ instrumentation types.
+
+4. Build QEMU with static trace intrumentation:
+
+ mkdir -p /tmp/qemu-build
+ cd /tmp/qemu-build
+ /path/to/qemu-source/configure \
+ --with-trace-events=/tmp/trace-events \
+ --with-trace-instrument=static \
+ --with-trace-instrument-path=/tmp/my-sinstrument \
+ --enable-trace-backend=stderr \
+ --prefix=/tmp/qemu-install
+ make
+ make install
+
+
+=== Performance optimizations ===
+
+You can create a few header files in the user-provided instrumentation path
+('--with-trace-instrument-path') to further optimize static instrumentation:
+
+* "events-pre.h"
+
+ Included before the code of the in-QEMU and tracing backend-specific header
+ ("trace.h").
+
+ This header can contain per-event defines to allow the user to provide an
+ inlined version of the instrumentation routine (see "events-post.h"):
+
+ #define QI_EVENT_${EVENT}_INLINE 1
+
+ Example:
+
+ #ifndef EVENTS_PRE_H
+ #define EVENTS_PRE_H
+
+ #define QI_EVENT_QEMU_VMALLOC_INLINE 1
+
+ #endif /* EVENTS_PRE_H */
+
+* "events-post.h"
+
+ Included after the code of the in-QEMU and tracing backend-specific header
+ ("trace.h").
+
+ This header can contain arbitrary user-provided code that will be inlined into
+ all QEMU files using tracing events. This includes inlined versions of the
+ instrumentation routines.
+
+ For example, inlining the fast-path of the instrumentation code:
+
+ #ifndef EVENTS_POST_H
+ #define EVENTS_POST_H
+
+ #include <qemu-instr/events.h>
+
+ // file residing in "/tmp/my-sinstrument/my-header.h",
+ // which declares 'my_trace_qemu_vmalloc_slow'
+ #include "my-header.h"
+
+
+ // requires "#define QI_EVENT_QEMU_VMALLOC_INLINE 1" in "events-pre.h"
+ static inline void qi_event_qemu_vmalloc(size_t size, void *ptr)
+ {
+ if (/* ... performance-critical condition ... */) {
+ /* ... performance-critical code ... */
+ } else {
+ my_trace_qemu_vmalloc_slow(size, ptr);
+ }
+ }
+
+ #endif /* EVENTS_POST_H */
+
+Note: All these headers are completely optional, and will only be used if they
+exist at compile time.
+
+
+
+== Loading and unloading instrumentation libraries ==
+
+QEMU starts with all instrumentation callbacks set to their default value, which
+corresponds to a call to 'qi_event_${event}_nop'.
+
+To load a dynamic instrumentation library, the user can either use the "-instr"
+command line argument, or the "instr-load" command available in the QEMU
+monitor, QAPI and QMP.
+
+Once loaded, QEMU will call the 'qi_init' routine in the instrumentation library.
+
+To unload a dynamic instrumentation library, the user can use the "instr-unload"
+command.
+
+When unloading, QEMU will call the 'qi_fini' routine in the instrumentation
+library, and immediately after restore all the instrumentation callbacks to
+their default value.
+
+In the case of static instrumentation, the commands "instr-load" and
+"instr-unload" are not available, and thus the instrumentation library is
+already loaded when QEMU starts, and is unloaded when QEMU exits.
+
+
+
+== Instrumentation API ==
+
+Both dynamic and static trace instrumentation libraries can interact with QEMU
+using the API provided in the headers found under the "qemu-instr" directory
+(installed alongside QEMU).
+
+
+=== Event enumeration ===
+
+Events can be obtained either by identifier or by name. Identifiers are values
+of the enumeration 'QIEventID' and follow the naming scheme 'QI_EVENT_${EVENT}'
+(e.g., 'QI_EVENT_QEMU_VMALLOC' for the "qemu_vmalloc" event).
+
+Identifiers, together with defines indicating if an event is enabled at
+compile-time ('QI_EVENT_${EVENT}_ENABLED') are located in the
+"qemu-instr/events-list.h" header.
+
+The interface to obtain and enumerate these events is located in the
+"qemu-instr/control.h" header.
+
+
+=== Event tracing ===
+
+You can interact with the state of QEMU's event tracing backend (see document
+"tracing.txt") through the API in the "qemu-instr/trace.h" header.
+
+
+=== Event instrumentation ===
+
+You can control the instrumentation callbacks of events through the API in the
+"qemu-instr/control.h" header.
+
+
+=== Instrumentation type discrimination ===
+
+The same source code for an instrumentation library can result in different code
+depending on the current instrumentation type (either dynamic or static):
+
+* "qemu-instr/config.h"
+
+ The define QI_TYPE_CONFIG_STATIC (QI_TYPE_CONFIG_DYNAMIC) will be available
+ and set to 1 if QEMU has been compiled with static (dynamic) instrumentation.
+
+* "qemu-instr/control.h"
+
+ Routine 'qi_ctrl_type' can be used to discriminate if dynamic instrumentation
+ is available.
+
+ Similarly, routine 'qi_ctrl_event_is_available' indicates whether the given
+ event is available for instrumentation (both static and dynamic).
+
+With this, you can ensure the same code will work under both instrumentation
+types.
+
+Example initialization:
+
+ #if defined(QI_TYPE_CONFIG_DYNAMIC)
+ #include "events-post.h"
+ #endif
+
+ void qi_init(int argc, const char *argv)
+ {
+ int i;
+ fprintf(stderr, "init!\n");
+ fprintf(stderr, " argc :: %d\n", argc);
+ for (i = 0; i < argc; i++) {
+ fprintf(stderr, " -> %s\n", argv[i]);
+ }
+
+ QIEvent *ev = NULL;
+ while ((ev = qi_ctrl_event_pattern("*", ev)) != NULL) {
+
+ if (qi_ctrl_event_is_available(ev)) {
+
+ /* changing the callback will fail during static instrumentation */
+ if (qi_ctrl_type() == QI_TYPE_DYNAMIC) {
+ bool instrumented = qi_ctrl_event_set(ev, QI_CTRL_INSTR_AUTO);
+ assert(instrumented);
+ }
+
+ qi_trace_event_set_state_dynamic(ev, true);
+ }
+ }
+ }
+
+Example "events-post.h":
+
+ #if defined(QI_TYPE_CONFIG_STATIC)
+ static inline
+ #endif
+ void qi_event_qemu_vmalloc(size_t size, void *ptr)
+ {
+ /* ... */
+ }
diff --git a/docs/tracing.txt b/docs/tracing.txt
index cf53c17..d33717b 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -255,3 +255,12 @@ guard such computations and avoid its compilation when the event is disabled:
You can check both if the event has been disabled and is dynamically enabled at
the same time using the 'trace_event_get_state' routine (see header
"trace/control.h" for more information).
+
+=== "instrument" ===
+
+When compiling QEMU with trace instrumentation enabled, the "instrument"
+property lets you provide your own implementation for that trace event. This
+implementation can override and/or wrap the backend-specific tracing code
+(regardless of the tracing backend).
+
+See the document "instrumentation.txt" for more information.
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 02/24] trace: [simple] Do not include "trace/simple.h" in generated tracer headers
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 01/24] instrument: Add documentation Lluís Vilanova
@ 2013-04-21 19:11 ` Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 03/24] trace: Let the user specify her own trace-events file Lluís Vilanova
` (22 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:11 UTC (permalink / raw)
To: qemu-devel
The header is not necessary, given that the simple backend does not define any
inlined tracing routines.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/tracetool/backend/simple.py | 5 +----
trace/simple.c | 2 ++
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py
index 37ef599..e754f0d 100644
--- a/scripts/tracetool/backend/simple.py
+++ b/scripts/tracetool/backend/simple.py
@@ -6,7 +6,7 @@ Simple built-in backend.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -93,9 +93,6 @@ def c(events):
def h(events):
- out('#include "trace/simple.h"',
- '')
-
for event in events:
out('void trace_%(name)s(%(args)s);',
name = event.name,
diff --git a/trace/simple.c b/trace/simple.c
index 1e3f691..8b59760 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -8,6 +8,8 @@
*
*/
+#include "trace/simple.h"
+
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 03/24] trace: Let the user specify her own trace-events file
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 01/24] instrument: Add documentation Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 02/24] trace: [simple] Do not include "trace/simple.h" in generated tracer headers Lluís Vilanova
@ 2013-04-21 19:11 ` Lluís Vilanova
2013-04-26 15:21 ` Paolo Bonzini
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 04/24] tracetool: Use method 'Event.api' to get the name of public routines Lluís Vilanova
` (21 subsequent siblings)
24 siblings, 1 reply; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:11 UTC (permalink / raw)
To: qemu-devel
With this option the user can perform multiple builds of QEMU with different
tracing event properties.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile.target | 2 +-
configure | 19 +++++++++++++++++++
trace/Makefile.objs | 10 +++++-----
3 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/Makefile.target b/Makefile.target
index 2bd6d14..f382559 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -47,7 +47,7 @@ else
TARGET_TYPE=system
endif
-$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
+$(QEMU_PROG).stp: $(TRACE_EVENTS)
$(call quiet-command,$(TRACETOOL) \
--format=stap \
--backend=$(TRACE_BACKEND) \
diff --git a/configure b/configure
index 73df181..a3bd336 100755
--- a/configure
+++ b/configure
@@ -221,6 +221,7 @@ blobs="yes"
pkgversion=""
pie=""
zero_malloc=""
+trace_events=`dirname $0`/trace-events
trace_backend="nop"
trace_file="trace"
spice=""
@@ -639,6 +640,8 @@ for opt do
;;
--target-list=*) target_list="$optarg"
;;
+ --with-trace-events=*) trace_events="$optarg"
+ ;;
--enable-trace-backend=*) trace_backend="$optarg"
;;
--with-trace-file=*) trace_file="$optarg"
@@ -1158,6 +1161,7 @@ echo " --enable-docs enable documentation build"
echo " --disable-docs disable documentation build"
echo " --disable-vhost-net disable vhost-net acceleration support"
echo " --enable-vhost-net enable vhost-net acceleration support"
+echo " --with-trace-events=PATH file with tracing events description (default: $trace_events)"
echo " --enable-trace-backend=B Set trace backend"
echo " Available backends:" $($python "$source_path"/scripts/tracetool.py --list-backends)
echo " --with-trace-file=NAME Full PATH,NAME of file to store traces"
@@ -3009,6 +3013,18 @@ if compile_prog "" "" ; then
fi
##########################################
+# check if trace-events file exists
+
+if test ! -f "$trace_events"; then
+ echo
+ echo "Error: the given trace-events file does not exist"
+ echo
+ exit 1
+else
+ trace_events=`readlink -f "$trace_events"`
+fi
+
+##########################################
# check if trace backend exists
$python "$source_path/scripts/tracetool.py" "--backend=$trace_backend" --check-backend > /dev/null 2> /dev/null
@@ -3418,6 +3434,7 @@ echo "sigev_thread_id $sigev_thread_id"
echo "uuid support $uuid"
echo "libcap-ng support $cap_ng"
echo "vhost-net support $vhost_net"
+echo "Trace events $trace_events"
echo "Trace backend $trace_backend"
echo "Trace output file $trace_file-<pid>"
echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
@@ -3810,6 +3827,8 @@ bsd)
;;
esac
+echo "TRACE_EVENTS=$trace_events" >> $config_host_mak
+
# use default implementation for tracing backend-specific routines
trace_default=yes
echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index a043072..bf0a965 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -4,7 +4,7 @@
# Auto-generated event descriptions
$(obj)/generated-events.h: $(obj)/generated-events.h-timestamp
-$(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events
+$(obj)/generated-events.h-timestamp: $(TRACE_EVENTS)
$(call quiet-command,$(TRACETOOL) \
--format=events-h \
--backend=events \
@@ -12,7 +12,7 @@ $(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
$(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/config-host.mak
-$(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events
+$(obj)/generated-events.c-timestamp: $(TRACE_EVENTS)
$(call quiet-command,$(TRACETOOL) \
--format=events-c \
--backend=events \
@@ -27,7 +27,7 @@ util-obj-y += generated-events.o
$(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp
@cmp -s $< $@ || cp $< $@
-$(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
+$(obj)/generated-tracers.h-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.mak
$(call quiet-command,$(TRACETOOL) \
--format=h \
--backend=$(TRACE_BACKEND) \
@@ -39,7 +39,7 @@ $(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/conf
ifneq ($(TRACE_BACKEND),dtrace)
$(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp
@cmp -s $< $@ || cp $< $@
-$(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
+$(obj)/generated-tracers.c-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.mak
$(call quiet-command,$(TRACETOOL) \
--format=c \
--backend=$(TRACE_BACKEND) \
@@ -57,7 +57,7 @@ endif
# rule file. So we use '.dtrace' instead
ifeq ($(TRACE_BACKEND),dtrace)
$(obj)/generated-tracers.dtrace: $(obj)/generated-tracers.dtrace-timestamp
-$(obj)/generated-tracers.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
+$(obj)/generated-tracers.dtrace-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.mak
$(call quiet-command,$(TRACETOOL) \
--format=d \
--backend=$(TRACE_BACKEND) \
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 04/24] tracetool: Use method 'Event.api' to get the name of public routines
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (2 preceding siblings ...)
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 03/24] trace: Let the user specify her own trace-events file Lluís Vilanova
@ 2013-04-21 19:11 ` Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 05/24] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops Lluís Vilanova
` (20 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:11 UTC (permalink / raw)
To: qemu-devel
This ensures proper naming across tracing backends, even when someone overrides
the value without backends knowing it.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/tracetool/__init__.py | 10 +++++++++-
scripts/tracetool/backend/dtrace.py | 6 +++---
scripts/tracetool/backend/simple.py | 8 ++++----
scripts/tracetool/backend/stderr.py | 5 +++--
scripts/tracetool/backend/ust.py | 8 +++++---
scripts/tracetool/format/h.py | 6 +++---
6 files changed, 27 insertions(+), 16 deletions(-)
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 175df08..7e4d651 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -6,7 +6,7 @@ Machinery for generating tracing-related intermediate files.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -173,6 +173,14 @@ class Event(object):
self.args,
self.fmt)
+
+ QEMU_TRACE = "trace_%(name)s"
+
+ def api(self, fmt = None):
+ if fmt is None:
+ fmt = Event.QEMU_TRACE
+ return fmt % { "name" : self.name }
+
def _read_events(fobj):
res = []
for line in fobj:
diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
index e31bc79..3a34600 100644
--- a/scripts/tracetool/backend/dtrace.py
+++ b/scripts/tracetool/backend/dtrace.py
@@ -6,7 +6,7 @@ DTrace/SystemTAP backend.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -44,10 +44,10 @@ def h(events):
'')
for e in events:
- out('static inline void trace_%(name)s(%(args)s) {',
+ out('static inline void %(api)s(%(args)s) {',
' QEMU_%(uppername)s(%(argnames)s);',
'}',
- name = e.name,
+ api = e.api(),
args = e.args,
uppername = e.name.upper(),
argnames = ", ".join(e.args.names()),
diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py
index e754f0d..b7337af 100644
--- a/scripts/tracetool/backend/simple.py
+++ b/scripts/tracetool/backend/simple.py
@@ -34,10 +34,10 @@ def c(events):
)
for num, event in enumerate(events):
- out('void trace_%(name)s(%(args)s)',
+ out('void %(api)s(%(args)s)',
'{',
' TraceBufferRecord rec;',
- name = event.name,
+ api = event.api(),
args = event.args,
)
sizes = []
@@ -94,7 +94,7 @@ def c(events):
def h(events):
for event in events:
- out('void trace_%(name)s(%(args)s);',
- name = event.name,
+ out('void %(api)s(%(args)s);',
+ api = event.api(),
args = event.args,
)
diff --git a/scripts/tracetool/backend/stderr.py b/scripts/tracetool/backend/stderr.py
index 6f93dbd..d9b7121 100644
--- a/scripts/tracetool/backend/stderr.py
+++ b/scripts/tracetool/backend/stderr.py
@@ -6,7 +6,7 @@ Stderr built-in backend.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -33,13 +33,14 @@ def h(events):
if len(e.args) > 0:
argnames = ", " + argnames
- out('static inline void trace_%(name)s(%(args)s)',
+ out('static inline void %(api)s(%(args)s)',
'{',
' bool _state = trace_event_get_state(%(event_id)s);',
' if (_state) {',
' fprintf(stderr, "%(name)s " %(fmt)s "\\n" %(argnames)s);',
' }',
'}',
+ api = e.api(),
name = e.name,
args = e.args,
event_id = "TRACE_" + e.name.upper(),
diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py
index ea36995..2f4cb23 100644
--- a/scripts/tracetool/backend/ust.py
+++ b/scripts/tracetool/backend/ust.py
@@ -6,7 +6,7 @@ LTTng User Space Tracing backend.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -78,7 +78,8 @@ def h(events):
for e in events:
if len(e.args) > 0:
out('DECLARE_TRACE(ust_%(name)s, TP_PROTO(%(args)s), TP_ARGS(%(argnames)s));',
- '#define trace_%(name)s trace_ust_%(name)s',
+ '#define %(api)s trace_ust_%(name)s',
+ api = e.api(),
name = e.name,
args = e.args,
argnames = ", ".join(e.args.names()),
@@ -86,7 +87,8 @@ def h(events):
else:
out('_DECLARE_TRACEPOINT_NOARGS(ust_%(name)s);',
- '#define trace_%(name)s trace_ust_%(name)s',
+ '#define %(api)s trace_ust_%(name)s',
+ api = e.api(),
name = e.name,
)
diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
index 93132fc..ed7c8a5 100644
--- a/scripts/tracetool/format/h.py
+++ b/scripts/tracetool/format/h.py
@@ -6,7 +6,7 @@ Generate .h file.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -30,9 +30,9 @@ def end(events):
def nop(events):
for e in events:
out('',
- 'static inline void trace_%(name)s(%(args)s)',
+ 'static inline void %(api)s(%(args)s)',
'{',
'}',
- name = e.name,
+ api = e.api(),
args = e.args,
)
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 05/24] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (3 preceding siblings ...)
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 04/24] tracetool: Use method 'Event.api' to get the name of public routines Lluís Vilanova
@ 2013-04-21 19:11 ` Lluís Vilanova
2013-04-26 15:23 ` Paolo Bonzini
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 06/24] instrument: [none] Add null instrumentation Lluís Vilanova
` (19 subsequent siblings)
24 siblings, 1 reply; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:11 UTC (permalink / raw)
To: qemu-devel
This problem arises in the following patches.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
hw/virtio/virtio.c | 1 +
monitor.c | 4 +++-
scripts/tracetool/format/h.py | 9 ++++++++-
trace/control-internal.h | 4 +++-
trace/control.c | 4 +++-
trace/control.h | 9 +++++++--
trace/default.c | 4 +++-
trace/simple.c | 4 +++-
trace/simple.h | 1 +
trace/stderr.c | 4 +++-
10 files changed, 35 insertions(+), 9 deletions(-)
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 1c2282c..a3dda2c 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -14,6 +14,7 @@
#include <inttypes.h>
#include "trace.h"
+#include "qemu-common.h"
#include "qemu/error-report.h"
#include "hw/virtio/virtio.h"
#include "qemu/atomic.h"
diff --git a/monitor.c b/monitor.c
index c897e80..a8f49d9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -22,6 +22,9 @@
* THE SOFTWARE.
*/
#include <dirent.h>
+#define TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
+#include "trace/control.h"
+#undef TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
#include "hw/hw.h"
#include "monitor/qdev.h"
#include "hw/usb.h"
@@ -59,7 +62,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "trace.h"
-#include "trace/control.h"
#ifdef CONFIG_TRACE_SIMPLE
#include "trace/simple.h"
#endif
diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
index ed7c8a5..c98aebd 100644
--- a/scripts/tracetool/format/h.py
+++ b/scripts/tracetool/format/h.py
@@ -22,7 +22,14 @@ def begin(events):
'#ifndef TRACE__GENERATED_TRACERS_H',
'#define TRACE__GENERATED_TRACERS_H',
'',
- '#include "qemu-common.h"')
+ '/* Do not directly include "qemu-common.h" to avoid circular dependencies */',
+ '#include <stdint.h>',
+ '#include <inttypes.h>',
+ '#include <stdbool.h>',
+ '#include <stddef.h>',
+ '#include <unistd.h>',
+ '',
+ )
def end(events):
out('#endif /* TRACE__GENERATED_TRACERS_H */')
diff --git a/trace/control-internal.h b/trace/control-internal.h
index cce2da4..a15a994 100644
--- a/trace/control-internal.h
+++ b/trace/control-internal.h
@@ -1,7 +1,7 @@
/*
* Interface for configuring and controlling the state of tracing events.
*
- * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2011-2013 Lluís Vilanova <vilanova@ac.upc.edu>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
@@ -11,6 +11,8 @@
#define TRACE__CONTROL_INTERNAL_H
#include <string.h>
+#include <assert.h>
+#include <stddef.h>
extern TraceEvent trace_events[];
diff --git a/trace/control.c b/trace/control.c
index 49f61e1..dd7b260 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -1,7 +1,7 @@
/*
* Interface for configuring and controlling the state of tracing events.
*
- * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2011-2013 Lluís Vilanova <vilanova@ac.upc.edu>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
@@ -9,6 +9,8 @@
#include "trace/control.h"
+#include "qemu-common.h"
+
TraceEvent *trace_event_name(const char *name)
{
diff --git a/trace/control.h b/trace/control.h
index cde8260..29ff9c1 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -1,7 +1,7 @@
/*
* Interface for configuring and controlling the state of tracing events.
*
- * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2011-2013 Lluís Vilanova <vilanova@ac.upc.edu>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
@@ -10,7 +10,6 @@
#ifndef TRACE__CONTROL_H
#define TRACE__CONTROL_H
-#include "qemu-common.h"
#include "trace/generated-events.h"
@@ -155,6 +154,10 @@ void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state);
+#if defined(TRACE__CONTROL__USE__TRACE_PRINT_EVENTS)
+/* Minimize inclusions of "qemu-common.h" to avoid circular dependencies */
+#include "qemu-common.h"
+
/**
* trace_print_events:
*
@@ -164,6 +167,8 @@ void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state);
*/
void trace_print_events(FILE *stream, fprintf_function stream_printf);
+#endif /* defined(TRACE__CONTROL__USE__TRACE_PRINT_EVENTS) */
+
/**
* trace_backend_init:
* @events: Name of file with events to be enabled at startup; may be NULL.
diff --git a/trace/default.c b/trace/default.c
index 6e07a47..4dbaf11 100644
--- a/trace/default.c
+++ b/trace/default.c
@@ -1,13 +1,15 @@
/*
* Default implementation for backend initialization from commandline.
*
- * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2011-2013 Lluís Vilanova <vilanova@ac.upc.edu>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/
+#define TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
#include "trace/control.h"
+#undef TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
void trace_print_events(FILE *stream, fprintf_function stream_printf)
diff --git a/trace/simple.c b/trace/simple.c
index 8b59760..cb4361f 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -19,8 +19,10 @@
#include <pthread.h>
#endif
#include "qemu/timer.h"
-#include "trace.h"
+#define TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
#include "trace/control.h"
+#undef TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
+#include "trace.h"
/** Trace file header event ID */
#define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */
diff --git a/trace/simple.h b/trace/simple.h
index 5260d9a..1541ea0 100644
--- a/trace/simple.h
+++ b/trace/simple.h
@@ -16,6 +16,7 @@
#include <stdio.h>
#include "trace/generated-events.h"
+#include "qemu-common.h"
void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
diff --git a/trace/stderr.c b/trace/stderr.c
index e212efd..3a6f4bd 100644
--- a/trace/stderr.c
+++ b/trace/stderr.c
@@ -1,5 +1,7 @@
-#include "trace.h"
+#define TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
#include "trace/control.h"
+#undef TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
+#include "trace.h"
void trace_print_events(FILE *stream, fprintf_function stream_printf)
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 06/24] instrument: [none] Add null instrumentation
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (4 preceding siblings ...)
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 05/24] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 07/24] system: [linux] Use absolute include path for linux-headers Lluís Vilanova
` (18 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
Splits the QEMU-side tracing interface into different layers (in order of nested
invocation):
* trace_*
The interface used by QEMU code to signal traceable/instrumentable events
(now generated according to the selected instrumentation type).
* qi_event_*
The interface provided by the user's instrumentation code (for which QEMU
provides default implementations depending on the instrumentation type).
* qi_event_*_trace / qi_event_*_nop
The interface provided by QEMU to the user's instrumentation code to invoke
the tracing backend. The nop variant simply does nothing.
* trace_*_backend
The interface provided by the tracing backend in QEMU. Originally exposed as
'trace_*' routines.
The 'none' instrumentation type (this one) skips through the qi_* layers and
directly calls 'trace_*_backend' from the 'trace_*' routines (providing the
original tracing behaviour).
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
.gitignore | 2 +
Makefile | 3 +
configure | 31 ++++++++++++++
include/trace.h | 2 -
instrument/Makefile.objs | 24 +++++++++++
scripts/tracetool/__init__.py | 9 +++-
scripts/tracetool/backend/instr_none.py | 41 +++++++++++++++++++
scripts/tracetool/format/api_h.py | 39 ++++++++++++++++++
scripts/tracetool/format/qemu_h.py | 68 +++++++++++++++++++++++++++++++
9 files changed, 216 insertions(+), 3 deletions(-)
create mode 100644 instrument/Makefile.objs
create mode 100644 scripts/tracetool/backend/instr_none.py
create mode 100644 scripts/tracetool/format/api_h.py
create mode 100644 scripts/tracetool/format/qemu_h.py
diff --git a/.gitignore b/.gitignore
index 487813a..2c9695c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,6 +10,8 @@ trace/generated-tracers.dtrace
trace/generated-events.h
trace/generated-events.c
libcacard/trace/generated-tracers.c
+instrument/generated-tracers.h
+instrument/qemu-instr/events.h
*-timestamp
*-softmmu
*-darwin-user
diff --git a/Makefile b/Makefile
index 0b6e6a1..028ef83 100644
--- a/Makefile
+++ b/Makefile
@@ -35,6 +35,9 @@ GENERATED_HEADERS = config-host.h qemu-options.def
GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h
GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c
+GENERATED_HEADERS += instrument/generated-tracers.h
+GENERATED_HEADERS += instrument/qemu-instr/events.h
+
GENERATED_HEADERS += trace/generated-events.h
GENERATED_SOURCES += trace/generated-events.c
diff --git a/configure b/configure
index a3bd336..2cddce4 100755
--- a/configure
+++ b/configure
@@ -224,6 +224,7 @@ zero_malloc=""
trace_events=`dirname $0`/trace-events
trace_backend="nop"
trace_file="trace"
+trace_instrument="none"
spice=""
rbd=""
smartcard_nss=""
@@ -646,6 +647,8 @@ for opt do
;;
--with-trace-file=*) trace_file="$optarg"
;;
+ --with-trace-instrument=*) trace_instrument="$optarg"
+ ;;
--enable-gprof) gprof="yes"
;;
--enable-gcov) gcov="yes"
@@ -1166,6 +1169,8 @@ echo " --enable-trace-backend=B Set trace backend"
echo " Available backends:" $($python "$source_path"/scripts/tracetool.py --list-backends)
echo " --with-trace-file=NAME Full PATH,NAME of file to store traces"
echo " Default:trace-<pid>"
+echo " --with-trace-instrument=TYPE"
+echo " Trace instrumentation type (none; default: $trace_instrument)"
echo " --disable-spice disable spice"
echo " --enable-spice enable spice"
echo " --enable-rbd enable building the rados block device (rbd)"
@@ -3062,6 +3067,15 @@ if test "$trace_backend" = "dtrace"; then
fi
##########################################
+# Check instrumentation type
+case "$trace_instrument" in
+none) ;;
+*) echo "Error: invalid trace instrumentation type: $trace_instrument"
+ exit 1
+ ;;
+esac
+
+##########################################
# __sync_fetch_and_and requires at least -march=i486. Many toolchains
# use i686 as default anyway, but for those that don't, an explicit
# specification is necessary
@@ -3437,6 +3451,7 @@ echo "vhost-net support $vhost_net"
echo "Trace events $trace_events"
echo "Trace backend $trace_backend"
echo "Trace output file $trace_file-<pid>"
+echo "Trace instrument $trace_instrument"
echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
echo "rbd support $rbd"
echo "xfsctl support $xfs"
@@ -3859,6 +3874,22 @@ if test "$trace_default" = "yes"; then
echo "CONFIG_TRACE_DEFAULT=y" >> $config_host_mak
fi
+##########################################
+# trace instrumentation
+config_qi=instrument/qemu-instr/config.h
+mkdir -p `dirname $config_qi`
+echo "/* Automatically generated by configure - do not modify */" > $config_qi
+
+echo "TRACE_INSTRUMENT_BACKEND=instr-$trace_instrument" >> $config_host_mak
+
+if test "$trace_instrument" = "none"; then
+ echo "#define QI_TYPE_CONFIG_NONE 1" >> $config_qi
+ echo "CONFIG_TRACE_INSTRUMENT_NONE=y" >> $config_host_mak
+else
+ echo "CONFIG_TRACE_INSTRUMENT=y" >> $config_host_mak
+fi
+##########################################
+
echo "TOOLS=$tools" >> $config_host_mak
echo "ROMS=$roms" >> $config_host_mak
echo "MAKE=$make" >> $config_host_mak
diff --git a/include/trace.h b/include/trace.h
index c15f498..5cd06c7 100644
--- a/include/trace.h
+++ b/include/trace.h
@@ -1,6 +1,6 @@
#ifndef TRACE_H
#define TRACE_H
-#include "trace/generated-tracers.h"
+#include "instrument/generated-tracers.h"
#endif /* TRACE_H */
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
new file mode 100644
index 0000000..9c5d5dc
--- /dev/null
+++ b/instrument/Makefile.objs
@@ -0,0 +1,24 @@
+# -*- mode: makefile -*-
+
+######################################################################
+# QEMU trace->instrument interface
+
+$(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp
+$(obj)/generated-tracers.h-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.mak
+ $(call quiet-command,$(TRACETOOL) \
+ --format=qemu-h \
+ --backend=$(TRACE_INSTRUMENT_BACKEND) \
+ < $< > $@," GEN $(patsubst %-timestamp,%,$@)")
+ @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+
+
+######################################################################
+# User interface
+
+$(obj)/qemu-instr/events.h: $(obj)/qemu-instr/events.h-timestamp
+$(obj)/qemu-instr/events.h-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.mak
+ $(call quiet-command,$(TRACETOOL) \
+ --format=api-h \
+ --backend=$(TRACE_INSTRUMENT_BACKEND) \
+ < $< > $@," GEN $(patsubst %-timestamp,%,$@)")
+ @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 7e4d651..f849e39 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -122,7 +122,7 @@ class Event(object):
_CRE = re.compile("((?P<props>.*)\s+)?(?P<name>[^(\s]+)\((?P<args>[^)]*)\)\s*(?P<fmt>\".*)?")
- _VALID_PROPS = set(["disable"])
+ _VALID_PROPS = set(["disable", "instrument"])
def __init__(self, name, props, fmt, args):
"""
@@ -146,6 +146,9 @@ class Event(object):
if len(unknown_props) > 0:
raise ValueError("Unknown properties: %s" % ", ".join(unknown_props))
+ if "instrument" in self.properties and "disable" in self.properties:
+ raise ValueError("Cannot instrument a disabled event: %s" % self.name)
+
@staticmethod
def build(line_str):
"""Build an Event instance from a string.
@@ -175,10 +178,12 @@ class Event(object):
QEMU_TRACE = "trace_%(name)s"
+ QEMU_TRACE_BACKEND = "trace_%(name)s_backend"
+ QI_TRACE_INSTRUMENT = "qi_event_%(name)s"
def api(self, fmt = None):
if fmt is None:
- fmt = Event.QEMU_TRACE
+ fmt = Event.QEMU_TRACE_BACKEND
return fmt % { "name" : self.name }
def _read_events(fobj):
diff --git a/scripts/tracetool/backend/instr_none.py b/scripts/tracetool/backend/instr_none.py
new file mode 100644
index 0000000..a1327c0
--- /dev/null
+++ b/scripts/tracetool/backend/instr_none.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+No-instrumentation proxy.
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "stefanha@linux.vnet.ibm.com"
+
+
+from tracetool import out
+import tracetool.format.qemu_h
+
+
+def qemu_h(events):
+ out('#include "instrument/qemu-instr/events.h"',
+ '',
+ )
+ tracetool.format.qemu_h.process_common(events)
+
+
+def api_h(events):
+ for e in events:
+ if "instrument" not in e.properties:
+ continue
+
+ out('static inline void %(qi)s(%(args)s)',
+ '{',
+ ' %(qemu_backend)s(%(argnames)s);',
+ '}',
+ '',
+ qi = e.api(e.QI_TRACE_INSTRUMENT),
+ args = e.args,
+ qemu_backend = e.api(e.QEMU_TRACE_BACKEND),
+ argnames = ", ".join(e.args.names()),
+ )
diff --git a/scripts/tracetool/format/api_h.py b/scripts/tracetool/format/api_h.py
new file mode 100644
index 0000000..70d8e9f
--- /dev/null
+++ b/scripts/tracetool/format/api_h.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .h for trace instrumentation clients.
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "stefanha@linux.vnet.ibm.com"
+
+
+from tracetool import out
+
+
+def begin(events):
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ '#ifndef QI__EVENTS_H',
+ '#define QI__EVENTS_H',
+ '',
+ '#ifdef __cplusplus',
+ 'extern "C" {',
+ '#endif',
+ '',
+ '#include <stdint.h>',
+ '',
+ )
+
+def end(events):
+ out('#ifdef __cplusplus',
+ '}',
+ '#endif',
+ '',
+ '#endif /* QI__EVENTS_H */',
+ )
diff --git a/scripts/tracetool/format/qemu_h.py b/scripts/tracetool/format/qemu_h.py
new file mode 100644
index 0000000..51bd02a
--- /dev/null
+++ b/scripts/tracetool/format/qemu_h.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .h for trace instrumentation proxy.
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "stefanha@linux.vnet.ibm.com"
+
+
+from tracetool import out
+
+
+def begin(events):
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ '#ifndef INSTRUMENT__GENERATED_TRACERS_H',
+ '#define INSTRUMENT__GENERATED_TRACERS_H',
+ '',
+ '#include "trace/generated-tracers.h"',
+ '',
+ )
+
+def end(events):
+ out('#include "trace/generated-events.h"',
+ '',
+ '#endif /* INSTRUMENT__GENERATED_TRACERS_H */',
+ )
+
+def nop(events):
+ for e in events:
+ out('static inline void %(qemu)s(%(args)s)',
+ '{',
+ ' %(qemu_backend)s(%(argnames)s);',
+ '}',
+ '',
+ qemu = e.api(e.QEMU_TRACE),
+ args = e.args,
+ qemu_backend = e.api(e.QEMU_TRACE_BACKEND),
+ argnames = ", ".join(e.args.names()),
+ )
+
+def process_common(events):
+ for e in events:
+ if "instrument" not in e.properties:
+ nop([e])
+ continue
+
+ out('static inline void %(qemu)s(%(args)s)',
+ '{',
+ '#if defined(QEMU_TOOLS)',
+ ' %(backend)s(%(argnames)s);',
+ '#else',
+ ' %(qi)s(%(argnames)s);',
+ '#endif',
+ '}',
+ '',
+ qemu = e.api(e.QEMU_TRACE),
+ args = e.args,
+ qi = e.api(e.QI_TRACE_INSTRUMENT),
+ backend = e.api(e.QEMU_TRACE_BACKEND),
+ argnames = ", ".join(e.args.names()),
+ )
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 07/24] system: [linux] Use absolute include path for linux-headers
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (5 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 06/24] instrument: [none] Add null instrumentation Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-26 15:17 ` Paolo Bonzini
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 08/24] instrument: [static] Call statically linked user-provided routines Lluís Vilanova
` (17 subsequent siblings)
24 siblings, 1 reply; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
Lets the include directive work regardless of the current directory.
This is needed for code compiled in directories deeper than one level from the
build root.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile.target | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.target b/Makefile.target
index f382559..2f9675a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -7,7 +7,7 @@ include $(SRC_PATH)/rules.mak
$(call set-vpath, $(SRC_PATH))
ifdef CONFIG_LINUX
-QEMU_CFLAGS += -I../linux-headers
+QEMU_CFLAGS += -I$(BUILD_DIR)/linux-headers
endif
QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -DNEED_CPU_H
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 08/24] instrument: [static] Call statically linked user-provided routines
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (6 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 07/24] system: [linux] Use absolute include path for linux-headers Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 09/24] build: Add variable 'tools-obj-y' for tool-only files Lluís Vilanova
` (16 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
Compiles a user-provided static library during QEMU compilation.
This library must provide the implementation of the 'qi_event_*' routines.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile.target | 2 +
configure | 42 +++++++++++++++-
instrument/Makefile.objs | 27 ++++++++++
scripts/tracetool.py | 14 ++++-
scripts/tracetool/__init__.py | 10 +++-
scripts/tracetool/backend/instr_static.py | 76 +++++++++++++++++++++++++++++
6 files changed, 165 insertions(+), 6 deletions(-)
create mode 100644 scripts/tracetool/backend/instr_static.py
diff --git a/Makefile.target b/Makefile.target
index 2f9675a..114fc39 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -149,6 +149,8 @@ include $(SRC_PATH)/Makefile.objs
all-obj-y = $(obj-y)
all-obj-y += $(addprefix ../, $(common-obj-y))
+all-obj-y += $(LIBTRACE_INSTRUMENT)
+
ifdef QEMU_PROGW
# The linker builds a windows executable. Make also a console executable.
$(QEMU_PROGW): $(all-obj-y) ../libqemuutil.a ../libqemustub.a
diff --git a/configure b/configure
index 2cddce4..0eafd5a 100755
--- a/configure
+++ b/configure
@@ -225,6 +225,7 @@ trace_events=`dirname $0`/trace-events
trace_backend="nop"
trace_file="trace"
trace_instrument="none"
+trace_instrument_path=""
spice=""
rbd=""
smartcard_nss=""
@@ -649,6 +650,8 @@ for opt do
;;
--with-trace-instrument=*) trace_instrument="$optarg"
;;
+ --with-trace-instrument-path=*) trace_instrument_path="$optarg"
+ ;;
--enable-gprof) gprof="yes"
;;
--enable-gcov) gcov="yes"
@@ -1170,7 +1173,9 @@ echo " Available backends:" $($python "$source_path"/s
echo " --with-trace-file=NAME Full PATH,NAME of file to store traces"
echo " Default:trace-<pid>"
echo " --with-trace-instrument=TYPE"
-echo " Trace instrumentation type (none; default: $trace_instrument)"
+echo " Trace instrumentation type (none static; default: $trace_instrument)"
+echo " --with-trace-instrument-path=PATH"
+echo " Directory to build user-provided static trace event instrumentation library"
echo " --disable-spice disable spice"
echo " --enable-spice enable spice"
echo " --enable-rbd enable building the rados block device (rbd)"
@@ -3069,13 +3074,32 @@ fi
##########################################
# Check instrumentation type
case "$trace_instrument" in
-none) ;;
+none|static) ;;
*) echo "Error: invalid trace instrumentation type: $trace_instrument"
exit 1
;;
esac
##########################################
+# check for a valid directory for static trace instrumentation
+if test "$trace_instrument" = "static" -a -z "$trace_instrument_path"; then
+ echo "Error: must provide '--with-trace-instrument-path' when using static trace instrumentation"
+ exit 1
+fi
+if test "$trace_instrument" != "static" -a -n "$trace_instrument_path"; then
+ echo "Error: cannot provide '--with-trace-instrument-path' when not using static trace instrumentation"
+ exit 1
+fi
+if test "$trace_instrument" = "static" -a ! -f "$trace_instrument_path/Makefile"; then
+ echo
+ echo "Error: cannot make into '$trace_instrument_path'"
+ echo "Please choose a directory where I can run 'make'"
+ echo
+ exit 1
+fi
+trace_instrument_path=`readlink -f "$trace_instrument_path"`
+
+##########################################
# __sync_fetch_and_and requires at least -march=i486. Many toolchains
# use i686 as default anyway, but for those that don't, an explicit
# specification is necessary
@@ -3452,6 +3476,9 @@ echo "Trace events $trace_events"
echo "Trace backend $trace_backend"
echo "Trace output file $trace_file-<pid>"
echo "Trace instrument $trace_instrument"
+if test -n "$trace_instrument_path"; then
+echo "Static instrument $trace_instrument_path"
+fi
echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
echo "rbd support $rbd"
echo "xfsctl support $xfs"
@@ -3888,6 +3915,13 @@ if test "$trace_instrument" = "none"; then
else
echo "CONFIG_TRACE_INSTRUMENT=y" >> $config_host_mak
fi
+if test "$trace_instrument" = "static"; then
+ echo "#define QI_TYPE_CONFIG_STATIC 1" >> $config_qi
+ echo "CONFIG_TRACE_INSTRUMENT_STATIC=y" >> $config_host_mak
+ echo "TRACE_INSTRUMENT_PATH=\"$trace_instrument_path\"" >> $config_host_mak
+ echo "TRACETOOL_INSTR_STATIC=--instr-static-path \"\$(TRACE_INSTRUMENT_PATH)\"" >> $config_host_mak
+ QEMU_CFLAGS="-I\"$trace_instrument_path\" $QEMU_CFLAGS"
+fi
##########################################
echo "TOOLS=$tools" >> $config_host_mak
@@ -4150,6 +4184,10 @@ if [ "$TARGET_BASE_ARCH" = "" ]; then
fi
symlink "$source_path/Makefile.target" "$target_dir/Makefile"
+if test -n "$trace_instrument_path"; then
+ mkdir -p $target_dir/libtrace-instrument
+ symlink $trace_instrument_path/Makefile $target_dir/libtrace-instrument/Makefile
+fi
upper() {
echo "$@"| LC_ALL=C tr '[a-z]' '[A-Z]'
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 9c5d5dc..4102b59 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -8,9 +8,15 @@ $(obj)/generated-tracers.h-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.m
$(call quiet-command,$(TRACETOOL) \
--format=qemu-h \
--backend=$(TRACE_INSTRUMENT_BACKEND) \
+ $(TRACETOOL_INSTR_STATIC) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+ifdef CONFIG_TRACE_INSTRUMENT_STATIC
+# Rebuild to check for user headers
+.PHONY: $(obj)/generated-tracers.h-timestamp
+endif
+
######################################################################
# User interface
@@ -20,5 +26,26 @@ $(obj)/qemu-instr/events.h-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.m
$(call quiet-command,$(TRACETOOL) \
--format=api-h \
--backend=$(TRACE_INSTRUMENT_BACKEND) \
+ $(TRACETOOL_INSTR_STATIC) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+
+
+######################################################################
+# User code (static instrumentation)
+
+ifdef CONFIG_TRACE_INSTRUMENT_STATIC
+LIBTRACE_INSTRUMENT = libtrace-instrument/libtrace-instrument.a
+
+.PHONY: force
+force:
+
+_libinstrument_cflags = $(subst libtrace-instrument,.,$(subst libtrace-instrument/,.,$(1)))
+$(LIBTRACE_INSTRUMENT): QEMU_CFLAGS += -I$(BUILD_DIR)/
+$(LIBTRACE_INSTRUMENT): VPATH = $(TRACE_INSTRUMENT_PATH)
+$(LIBTRACE_INSTRUMENT): $(dir $(LIBTRACE_INSTRUMENT))/Makefile force
+ $(call quiet-command,$(MAKE) $(SUBDIR_MAKEFLAGS) -C $(dir $@) \
+ QEMU_CFLAGS="$(call _libinstrument_cflags,$(QEMU_CFLAGS))" \
+ TARGET_DIR=$(TARGET_DIR)$(dir $@)/ VPATH=$(VPATH) \
+ SRC_PATH=$(SRC_PATH) V="$(V)" $(notdir $@))
+endif
diff --git a/scripts/tracetool.py b/scripts/tracetool.py
index a79ec0f..52d2cf4 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -6,7 +6,7 @@ Command-line wrapper for the tracetool machinery.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -48,7 +48,10 @@ Options:
--target-type <type> QEMU emulator target type ('system' or 'user').
--target-arch <arch> QEMU emulator target arch.
--probe-prefix <prefix> Prefix for dtrace probe names
- (default: qemu-<target-type>-<target-arch>).\
+ (default: qemu-<target-type>-<target-arch>).
+ --instr-static--path <path>
+ Path to directory containing static instrumentation
+ library.\
""" % {
"script" : _SCRIPT,
"backends" : backend_descr,
@@ -67,6 +70,7 @@ def main(args):
long_opts = [ "backend=", "format=", "help", "list-backends", "check-backend" ]
long_opts += [ "binary=", "target-type=", "target-arch=", "probe-prefix=" ]
+ long_opts += [ "instr-static-path=" ]
try:
opts, args = getopt.getopt(args[1:], "", long_opts)
@@ -80,6 +84,7 @@ def main(args):
target_type = None
target_arch = None
probe_prefix = None
+ instr_static_path = None
for opt, arg in opts:
if opt == "--help":
error_opt()
@@ -104,6 +109,8 @@ def main(args):
target_arch = arg
elif opt == '--probe-prefix':
probe_prefix = arg
+ elif opt == '--instr-static-path':
+ instr_static_path = arg
else:
error_opt("unhandled option: %s" % opt)
@@ -130,7 +137,8 @@ def main(args):
try:
tracetool.generate(sys.stdin, arg_format, arg_backend,
- binary = binary, probe_prefix = probe_prefix)
+ binary = binary, probe_prefix = probe_prefix,
+ instr_static_path = instr_static_path)
except tracetool.TracetoolError, e:
error_opt(str(e))
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index f849e39..5406a2b 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -180,6 +180,8 @@ class Event(object):
QEMU_TRACE = "trace_%(name)s"
QEMU_TRACE_BACKEND = "trace_%(name)s_backend"
QI_TRACE_INSTRUMENT = "qi_event_%(name)s"
+ QI_TRACE_NOP = "qi_event_%(name)s_nop"
+ QI_TRACE_BACKEND = "qi_event_%(name)s_trace"
def api(self, fmt = None):
if fmt is None:
@@ -229,7 +231,8 @@ def try_import(mod_name, attr_name = None, attr_default = None):
def generate(fevents, format, backend,
- binary = None, probe_prefix = None):
+ binary = None, probe_prefix = None,
+ instr_static_path = None):
"""Generate the output for the given (format, backend) pair.
Parameters
@@ -244,6 +247,8 @@ def generate(fevents, format, backend,
See tracetool.backend.dtrace.BINARY.
probe_prefix : str or None
See tracetool.backend.dtrace.PROBEPREFIX.
+ instr_static_path : str or None
+ See tracetool.backend.instr_static.PATH.
"""
# fix strange python error (UnboundLocalError tracetool)
import tracetool
@@ -270,6 +275,9 @@ def generate(fevents, format, backend,
tracetool.backend.dtrace.BINARY = binary
tracetool.backend.dtrace.PROBEPREFIX = probe_prefix
+ import tracetool.backend.instr_static
+ tracetool.backend.instr_static.PATH = instr_static_path
+
events = _read_events(fevents)
if backend == "nop":
diff --git a/scripts/tracetool/backend/instr_static.py b/scripts/tracetool/backend/instr_static.py
new file mode 100644
index 0000000..b010596
--- /dev/null
+++ b/scripts/tracetool/backend/instr_static.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Static instrumentation proxy.
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "stefanha@linux.vnet.ibm.com"
+
+
+import os
+
+from tracetool import out
+import tracetool.format.qemu_h
+
+
+PATH = None
+
+def _path():
+ if PATH is None:
+ raise ValueError("you must set PATH")
+ return PATH
+
+
+def qemu_h(events):
+ if _path() and os.path.exists(os.sep.join([_path(), "events-pre.h"])):
+ out('#include "events-pre.h"',
+ '',
+ )
+
+ out('#include "instrument/qemu-instr/events.h"',
+ '',
+ )
+ tracetool.format.qemu_h.process_common(events)
+
+ if _path() and os.path.exists(os.sep.join([_path(), "events-post.h"])):
+ out('#include "events-post.h"',
+ '',
+ )
+
+def api_h(events):
+ out('#include "trace/generated-tracers.h"',
+ '',
+ )
+
+ for e in events:
+ if "instrument" not in e.properties:
+ continue
+
+ out('#if defined(QI_EVENT_%(upper_name)s_INLINE)',
+ 'static',
+ '#endif',
+ 'void %(qi)s(%(args)s);',
+ '',
+ 'static inline void %(qi_nop)s(%(args)s)',
+ '{',
+ '}',
+ '',
+ 'static inline void %(qi_backend)s(%(args)s)',
+ '{',
+ ' %(qemu_backend)s(%(argnames)s);',
+ '}',
+ '',
+ qi = e.api(e.QI_TRACE_INSTRUMENT),
+ qi_nop = e.api(e.QI_TRACE_NOP),
+ qi_backend = e.api(e.QI_TRACE_BACKEND),
+ qemu_backend = e.api(e.QEMU_TRACE_BACKEND),
+ args = e.args,
+ argnames = ", ".join(e.args.names()),
+ upper_name = e.name.upper(),
+ )
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 09/24] build: Add variable 'tools-obj-y' for tool-only files
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (7 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 08/24] instrument: [static] Call statically linked user-provided routines Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 10/24] instrument: [dynamic] Call dynamically linked user-provided routines Lluís Vilanova
` (15 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile | 11 ++++++-----
libcacard/Makefile | 2 +-
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/Makefile b/Makefile
index 028ef83..2d3431a 100644
--- a/Makefile
+++ b/Makefile
@@ -171,18 +171,19 @@ Makefile: $(version-obj-y)
libqemustub.a: $(stub-obj-y)
libqemuutil.a: $(util-obj-y)
+libqemutools.a: $(tools-obj-y)
######################################################################
qemu-img.o: qemu-img-cmds.h
-qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a
-qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a
-qemu-io$(EXESUF): qemu-io.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a
+qemu-img$(EXESUF): qemu-img.o $(block-obj-y) libqemuutil.a libqemustub.a libqemutools.a
+qemu-nbd$(EXESUF): qemu-nbd.o $(block-obj-y) libqemuutil.a libqemustub.a libqemutools.a
+qemu-io$(EXESUF): qemu-io.o cmd.o $(block-obj-y) libqemuutil.a libqemustub.a libqemutools.a
qemu-bridge-helper$(EXESUF): qemu-bridge-helper.o
-fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o libqemuutil.a libqemustub.a
+fsdev/virtfs-proxy-helper$(EXESUF): fsdev/virtfs-proxy-helper.o fsdev/virtio-9p-marshal.o libqemuutil.a libqemustub.a libqemutools.a
fsdev/virtfs-proxy-helper$(EXESUF): LIBS += -lcap
qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
@@ -218,7 +219,7 @@ $(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
-qemu-ga$(EXESUF): $(qga-obj-y) libqemuutil.a libqemustub.a
+qemu-ga$(EXESUF): $(qga-obj-y) libqemuutil.a libqemustub.a libqemutools.a
$(call LINK, $^)
clean:
diff --git a/libcacard/Makefile b/libcacard/Makefile
index 47827a0..c0a5d66 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -16,7 +16,7 @@ $(libcacard-obj-y): | $(libcacard-lobj-y)
all: libcacard.la libcacard.pc
-vscclient$(EXESUF): libcacard/vscclient.o libcacard.la
+vscclient$(EXESUF): libcacard/vscclient.o libcacard.la libqemutools.a
$(call LINK,$^)
#########################################################################
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 10/24] instrument: [dynamic] Call dynamically linked user-provided routines
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (8 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 09/24] build: Add variable 'tools-obj-y' for tool-only files Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 11/24] qapi: Add a primitive to include other files from a QAPI schema file Lluís Vilanova
` (14 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
Provides a mechanism to dynamically change the routine invoked by 'trace_*'.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
.gitignore | 1
Makefile | 4 +
Makefile.objs | 6 ++
configure | 8 ++-
instrument/Makefile.objs | 11 ++++
libcacard/Makefile | 2 -
scripts/tracetool/__init__.py | 1
scripts/tracetool/backend/instr_dynamic.py | 87 ++++++++++++++++++++++++++++
scripts/tracetool/format/api_c.py | 24 ++++++++
scripts/tracetool/format/events_c.py | 36 +++++++++++-
trace/event-internal.h | 12 ++++
11 files changed, 186 insertions(+), 6 deletions(-)
create mode 100644 scripts/tracetool/backend/instr_dynamic.py
create mode 100644 scripts/tracetool/format/api_c.py
diff --git a/.gitignore b/.gitignore
index 2c9695c..2a0ea2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@ trace/generated-events.h
trace/generated-events.c
libcacard/trace/generated-tracers.c
instrument/generated-tracers.h
+instrument/generated-tracers.c
instrument/qemu-instr/events.h
*-timestamp
*-softmmu
diff --git a/Makefile b/Makefile
index 2d3431a..cf938be 100644
--- a/Makefile
+++ b/Makefile
@@ -36,6 +36,9 @@ GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h
GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c
GENERATED_HEADERS += instrument/generated-tracers.h
+ifdef CONFIG_TRACE_INSTRUMENT_DYNAMIC
+GENERATED_SOURCES += instrument/generated-tracers.c
+endif
GENERATED_HEADERS += instrument/qemu-instr/events.h
GENERATED_HEADERS += trace/generated-events.h
@@ -234,6 +237,7 @@ clean:
@# May not be present in GENERATED_HEADERS
rm -f trace/generated-tracers-dtrace.dtrace*
rm -f trace/generated-tracers-dtrace.h*
+ rm -f instrument/generated-tracers.c*
rm -f $(foreach f,$(GENERATED_HEADERS),$(f) $(f)-timestamp)
rm -f $(foreach f,$(GENERATED_SOURCES),$(f) $(f)-timestamp)
rm -rf qapi-generated
diff --git a/Makefile.objs b/Makefile.objs
index e568c01..5f8ea2d 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -91,6 +91,11 @@ common-obj-y += qom/
common-obj-y += disas/
######################################################################
+# instrumentation
+
+tools-obj-y += instrument/
+
+######################################################################
# guest agent
# FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed
@@ -108,5 +113,6 @@ nested-vars += \
util-obj-y \
qga-obj-y \
block-obj-y \
+ tools-obj-y \
common-obj-y
dummy := $(call unnest-vars)
diff --git a/configure b/configure
index 0eafd5a..b51436f 100755
--- a/configure
+++ b/configure
@@ -1173,7 +1173,7 @@ echo " Available backends:" $($python "$source_path"/s
echo " --with-trace-file=NAME Full PATH,NAME of file to store traces"
echo " Default:trace-<pid>"
echo " --with-trace-instrument=TYPE"
-echo " Trace instrumentation type (none static; default: $trace_instrument)"
+echo " Trace instrumentation type (none static dynamic; default: $trace_instrument)"
echo " --with-trace-instrument-path=PATH"
echo " Directory to build user-provided static trace event instrumentation library"
echo " --disable-spice disable spice"
@@ -3074,7 +3074,7 @@ fi
##########################################
# Check instrumentation type
case "$trace_instrument" in
-none|static) ;;
+none|static|dynamic) ;;
*) echo "Error: invalid trace instrumentation type: $trace_instrument"
exit 1
;;
@@ -3922,6 +3922,10 @@ if test "$trace_instrument" = "static"; then
echo "TRACETOOL_INSTR_STATIC=--instr-static-path \"\$(TRACE_INSTRUMENT_PATH)\"" >> $config_host_mak
QEMU_CFLAGS="-I\"$trace_instrument_path\" $QEMU_CFLAGS"
fi
+if test "$trace_instrument" = "dynamic"; then
+ echo "#define QI_TYPE_CONFIG_DYNAMIC 1" >> $config_qi
+ echo "CONFIG_TRACE_INSTRUMENT_DYNAMIC=y" >> $config_host_mak
+fi
##########################################
echo "TOOLS=$tools" >> $config_host_mak
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 4102b59..cae520d 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -17,6 +17,17 @@ ifdef CONFIG_TRACE_INSTRUMENT_STATIC
.PHONY: $(obj)/generated-tracers.h-timestamp
endif
+$(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp
+$(obj)/generated-tracers.c-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.mak
+ $(call quiet-command,$(TRACETOOL) \
+ --format=api-c \
+ --backend=$(TRACE_INSTRUMENT_BACKEND) \
+ < $< > $@," GEN $(patsubst %-timestamp,%,$@)")
+ @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+
+tools-obj-$(CONFIG_TRACE_INSTRUMENT_DYNAMIC) += generated-tracers.o
+target-obj-$(CONFIG_TRACE_INSTRUMENT_DYNAMIC) += generated-tracers.o
+
######################################################################
# User interface
diff --git a/libcacard/Makefile b/libcacard/Makefile
index c0a5d66..f3f9f28 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -7,7 +7,7 @@ libcacard-obj-y = $(stub-obj-y) $(libcacard-y)
libcacard-obj-y += util/osdep.o util/cutils.o util/qemu-timer-common.o util/error.o
libcacard-obj-$(CONFIG_WIN32) += util/oslib-win32.o util/qemu-thread-win32.o
libcacard-obj-$(CONFIG_POSIX) += util/oslib-posix.o util/qemu-thread-posix.o
-libcacard-obj-y += $(filter trace/%, $(util-obj-y))
+libcacard-obj-y += $(filter trace/%, $(util-obj-y)) $(filter instrument/%, $(util-obj-y))
libcacard-lobj-y=$(patsubst %.o,%.lo,$(libcacard-obj-y))
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 5406a2b..7624982 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -182,6 +182,7 @@ class Event(object):
QI_TRACE_INSTRUMENT = "qi_event_%(name)s"
QI_TRACE_NOP = "qi_event_%(name)s_nop"
QI_TRACE_BACKEND = "qi_event_%(name)s_trace"
+ QI_TRACE_CB = QI_TRACE_NOP
def api(self, fmt = None):
if fmt is None:
diff --git a/scripts/tracetool/backend/instr_dynamic.py b/scripts/tracetool/backend/instr_dynamic.py
new file mode 100644
index 0000000..a07ee64
--- /dev/null
+++ b/scripts/tracetool/backend/instr_dynamic.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Dynamic instrumentation proxy.
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "stefanha@linux.vnet.ibm.com"
+
+
+from tracetool import out
+import tracetool.format.qemu_h
+
+
+def qemu_h(events):
+ for e in events:
+ if "instrument" not in e.properties:
+ continue
+
+ out('extern void * %(qi)s_cb;',
+ 'static inline void %(qi)s(%(args)s)',
+ '{',
+ ' ((void (*)(%(argtypes)s))%(qi)s_cb)(%(argnames)s);',
+ '}',
+ qi = e.api(e.QI_TRACE_INSTRUMENT),
+ args = e.args,
+ argnames = ", ".join(e.args.names()),
+ argtypes = ", ".join(e.args.types()),
+ )
+
+ tracetool.format.qemu_h.process_common(events)
+
+
+
+def api_h(events):
+ out('#include <qemu-instr/visibility-internal.h>',
+ '',
+ )
+
+ for e in events:
+ if "instrument" not in e.properties:
+ continue
+
+ out('QI_VPUBLIC void %(qi)s(%(args)s);',
+ 'void %(qi_nop)s(%(args)s);',
+ 'void %(qi_backend)s(%(args)s);',
+ qi = e.api(e.QI_TRACE_INSTRUMENT),
+ qi_nop = e.api(e.QI_TRACE_NOP),
+ qi_backend = e.api(e.QI_TRACE_BACKEND),
+ args = e.args,
+ )
+
+def api_c(events):
+ out('#include "instrument/qemu-instr/events.h"',
+ '',
+ '#include "trace/generated-events.h"',
+ '#include "trace/generated-tracers.h"',
+ '',
+ )
+
+ for e in events:
+ if "instrument" not in e.properties:
+ continue
+
+ out('void %(qi_nop)s(%(args)s)',
+ '{',
+ '}',
+ '',
+ 'void %(qi_backend)s(%(args)s)',
+ '{',
+ ' %(qemu_backend)s(%(argnames)s);',
+ '}',
+ '',
+ 'void * %(qi)s_cb = %(qi_cb)s;',
+ qi = e.api(e.QI_TRACE_INSTRUMENT),
+ qi_nop = e.api(e.QI_TRACE_NOP),
+ qi_backend = e.api(e.QI_TRACE_BACKEND),
+ qi_cb = e.api(e.QI_TRACE_CB),
+ qemu_backend = e.api(e.QEMU_TRACE_BACKEND),
+ args = e.args,
+ argnames = ", ".join(e.args.names()),
+ )
diff --git a/scripts/tracetool/format/api_c.py b/scripts/tracetool/format/api_c.py
new file mode 100644
index 0000000..3787f5d
--- /dev/null
+++ b/scripts/tracetool/format/api_c.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .c for trace instrumentation clients.
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "stefanha@linux.vnet.ibm.com"
+
+
+from tracetool import out
+
+
+def begin(events):
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ '#include <stdlib.h>',
+ '',
+ )
diff --git a/scripts/tracetool/format/events_c.py b/scripts/tracetool/format/events_c.py
index d670ec8..7531c66 100644
--- a/scripts/tracetool/format/events_c.py
+++ b/scripts/tracetool/format/events_c.py
@@ -6,7 +6,7 @@ Generate .c for event description.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -19,17 +19,49 @@ from tracetool import out
def begin(events):
out('/* This file is autogenerated by tracetool, do not edit. */',
'',
+ '#include "config-host.h"',
'#include "trace.h"',
'#include "trace/generated-events.h"',
'#include "trace/control.h"',
'',
)
+ # declarations
+ out('#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)')
+ for e in events:
+ if "instrument" in e.properties:
+ out('void %(nop)s(%(args)s);',
+ 'void %(backend)s(%(args)s);',
+ nop = e.api(e.QI_TRACE_NOP),
+ backend = e.api(e.QI_TRACE_BACKEND),
+ args = e.args,
+ )
+ out('#endif',
+ '',
+ )
+
+ # event state
out('TraceEvent trace_events[TRACE_EVENT_COUNT] = {')
for e in events:
- out(' { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s, .dstate = 0 },',
+ cb = cb_nop = cb_backend = "NULL"
+
+ if "instrument" in e.properties:
+ cb = "&%s_cb" % e.api(e.QI_TRACE_INSTRUMENT)
+ cb_nop = e.api(e.QI_TRACE_NOP)
+ cb_backend = e.api(e.QI_TRACE_BACKEND)
+
+ out(' { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s, .dstate = 0,',
+ '#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)',
+ ' .instr_cb = %(cb)s,',
+ ' .instr_cb_nop = %(cb_nop)s,',
+ ' .instr_cb_backend = %(cb_backend)s,',
+ '#endif',
+ ' },',
id = "TRACE_" + e.name.upper(),
+ cb = cb,
+ cb_nop = cb_nop,
+ cb_backend = cb_backend,
name = e.name,
sstate = "TRACE_%s_ENABLED" % e.name.upper(),
)
diff --git a/trace/event-internal.h b/trace/event-internal.h
index b2310d9..aed4050 100644
--- a/trace/event-internal.h
+++ b/trace/event-internal.h
@@ -1,7 +1,7 @@
/*
* Interface for configuring and controlling the state of tracing events.
*
- * Copyright (C) 2012 Lluís Vilanova <vilanova@ac.upc.edu>
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
@@ -11,6 +11,7 @@
#define TRACE__EVENT_INTERNAL_H
#include "trace/generated-events.h"
+#include "config-host.h"
/**
@@ -19,6 +20,9 @@
* @name: Event name.
* @sstate: Static tracing state.
* @dstate: Dynamic tracing state.
+ * @instr_cb: Instrumentation callback pointer.
+ * @instr_cb_nop: Instrumentation callback pointer to no-operation.
+ * @instr_cb_backend: Instrumentation callback pointer to tracing backend.
*
* Opaque generic description of a tracing event.
*/
@@ -27,6 +31,12 @@ typedef struct TraceEvent {
const char * name;
const bool sstate;
bool dstate;
+
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+ void **instr_cb;
+ void *instr_cb_nop;
+ void *instr_cb_backend;
+#endif
} TraceEvent;
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 11/24] qapi: Add a primitive to include other files from a QAPI schema file
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (9 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 10/24] instrument: [dynamic] Call dynamically linked user-provided routines Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 12/24] qapi: [trivial] Set the input root directory when parsing QAPI files Lluís Vilanova
` (13 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
Adds the "include(...)" primitive to the syntax of QAPI schema files.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/qapi-commands.py | 10 +++++++---
scripts/qapi-types.py | 10 +++++++---
scripts/qapi-visit.py | 10 +++++++---
scripts/qapi.py | 12 +++++++++++-
4 files changed, 32 insertions(+), 10 deletions(-)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index e06332b..fa16651 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -386,13 +386,15 @@ def gen_command_def_prologue(prefix="", proxy=False):
try:
- opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:m",
+ opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:i:o:m",
["source", "header", "prefix=",
- "output-dir=", "type=", "middle"])
+ "input-dir=", "output-dir=",
+ "type=", "middle"])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
+input_dir = ""
output_dir = ""
prefix = ""
dispatch_type = "sync"
@@ -406,6 +408,8 @@ do_h = False
for o, a in opts:
if o in ("-p", "--prefix"):
prefix = a
+ elif o in ("-i", "--input-dir"):
+ input_dir = a
elif o in ("-o", "--output-dir"):
output_dir = a + "/"
elif o in ("-t", "--type"):
@@ -437,7 +441,7 @@ except os.error, e:
if e.errno != errno.EEXIST:
raise
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(sys.stdin, input_dir)
commands = filter(lambda expr: expr.has_key('command'), exprs)
commands = filter(lambda expr: not expr.has_key('gen'), commands)
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 9e19920..ea33668 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -184,13 +184,15 @@ void qapi_free_%(type)s(%(c_type)s obj)
try:
- opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:",
- ["source", "header", "prefix=", "output-dir="])
+ opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:i:o:",
+ ["source", "header", "prefix=",
+ "input-dir=", "output-dir="])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
output_dir = ""
+input_dir = ""
prefix = ""
c_file = 'qapi-types.c'
h_file = 'qapi-types.h'
@@ -201,6 +203,8 @@ do_h = False
for o, a in opts:
if o in ("-p", "--prefix"):
prefix = a
+ elif o in ("-i", "--input-dir"):
+ input_dir = a
elif o in ("-o", "--output-dir"):
output_dir = a + "/"
elif o in ("-c", "--source"):
@@ -279,7 +283,7 @@ fdecl.write(mcgen('''
''',
guard=guardname(h_file)))
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(sys.stdin, input_dir)
exprs = filter(lambda expr: not expr.has_key('gen'), exprs)
for expr in exprs:
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index a276540..c372e99 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -235,12 +235,14 @@ void visit_type_%(name)s(Visitor *m, %(name)s * obj, const char *name, Error **e
name=name)
try:
- opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:o:",
- ["source", "header", "prefix=", "output-dir="])
+ opts, args = getopt.gnu_getopt(sys.argv[1:], "chp:i:o:",
+ ["source", "header", "prefix=",
+ "input-dir=", "output-dir="])
except getopt.GetoptError, err:
print str(err)
sys.exit(1)
+input_dir = ""
output_dir = ""
prefix = ""
c_file = 'qapi-visit.c'
@@ -252,6 +254,8 @@ do_h = False
for o, a in opts:
if o in ("-p", "--prefix"):
prefix = a
+ elif o in ("-i", "--input-dir"):
+ input_dir = a
elif o in ("-o", "--output-dir"):
output_dir = a + "/"
elif o in ("-c", "--source"):
@@ -327,7 +331,7 @@ fdecl.write(mcgen('''
''',
prefix=prefix, guard=guardname(h_file)))
-exprs = parse_schema(sys.stdin)
+exprs = parse_schema(sys.stdin, input_dir)
for expr in exprs:
if expr.has_key('type'):
diff --git a/scripts/qapi.py b/scripts/qapi.py
index afc5f32..b4f98b5 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -9,8 +9,12 @@
# This work is licensed under the terms of the GNU GPLv2.
# See the COPYING.LIB file in the top-level directory.
+import os
+import re
from ordereddict import OrderedDict
+include_cre = re.compile("\s*include\(\"([^\"]*)\"\)")
+
def tokenize(data):
while len(data):
ch = data[0]
@@ -72,7 +76,7 @@ def parse(tokens):
def evaluate(string):
return parse(map(lambda x: x, tokenize(string)))[0]
-def parse_schema(fp):
+def parse_schema(fp, input_dir):
exprs = []
expr = ''
expr_eval = None
@@ -81,6 +85,12 @@ def parse_schema(fp):
if line.startswith('#') or line == '\n':
continue
+ line_file = include_cre.match(line)
+ if line_file is not None:
+ path = os.sep.join([input_dir, line_file.group(1)])
+ exprs += parse_schema(file(path), input_dir)
+ continue
+
if line.startswith(' '):
expr += line
elif expr:
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 12/24] qapi: [trivial] Set the input root directory when parsing QAPI files
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (10 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 11/24] qapi: Add a primitive to include other files from a QAPI schema file Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 13/24] qapi: [trivial] Allow user to use 'args' as an argument name Lluís Vilanova
` (12 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index cf938be..8280273 100644
--- a/Makefile
+++ b/Makefile
@@ -211,13 +211,19 @@ $(SRC_PATH)/qga/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
qapi-types.c qapi-types.h :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py $(gen-out-type) -o "." < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
+ $(gen-out-type) -o "." -i "$(SRC_PATH)" \
+ < $<, " GEN $@")
qapi-visit.c qapi-visit.h :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py $(gen-out-type) -o "." < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
+ $(gen-out-type) -o "." -i "$(SRC_PATH)" \
+ < $<, " GEN $@")
qmp-commands.h qmp-marshal.c :\
$(SRC_PATH)/qapi-schema.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py $(gen-out-type) -m -o "." < $<, " GEN $@")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
+ $(gen-out-type) -m -o "." -i "$(SRC_PATH)" \
+ < $<, " GEN $@")
QGALIB_GEN=$(addprefix qga/qapi-generated/, qga-qapi-types.h qga-qapi-visit.h qga-qmp-commands.h)
$(qga-obj-y) qemu-ga.o: $(QGALIB_GEN)
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 13/24] qapi: [trivial] Allow user to use 'args' as an argument name
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (11 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 12/24] qapi: [trivial] Set the input root directory when parsing QAPI files Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 14/24] instrument: Add internal control interface Lluís Vilanova
` (11 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/qapi-commands.py | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index fa16651..236a6ae 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -207,7 +207,7 @@ def gen_marshal_input_decl(name, args, ret_type, middle_mode):
if middle_mode:
return 'int qmp_marshal_input_%s(Monitor *mon, const QDict *qdict, QObject **ret)' % c_fun(name)
else:
- return 'static void qmp_marshal_input_%s(QDict *args, QObject **ret, Error **errp)' % c_fun(name)
+ return 'static void qmp_marshal_input_%s(QDict *args_, QObject **ret, Error **errp)' % c_fun(name)
@@ -224,7 +224,7 @@ def gen_marshal_input(name, args, ret_type, middle_mode):
ret += mcgen('''
Error *local_err = NULL;
Error **errp = &local_err;
- QDict *args = (QDict *)qdict;
+ QDict *args_ = (QDict *)qdict;
''')
if ret_type:
@@ -247,10 +247,10 @@ def gen_marshal_input(name, args, ret_type, middle_mode):
''',
visitor_input_containers_decl=gen_visitor_input_containers_decl(args),
visitor_input_vars_decl=gen_visitor_input_vars_decl(args),
- visitor_input_block=gen_visitor_input_block(args, "QOBJECT(args)"))
+ visitor_input_block=gen_visitor_input_block(args, "QOBJECT(args_)"))
else:
ret += mcgen('''
- (void)args;
+ (void)args_;
''')
ret += mcgen('''
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 14/24] instrument: Add internal control interface
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (12 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 13/24] qapi: [trivial] Allow user to use 'args' as an argument name Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-26 14:08 ` Eric Blake
2013-04-26 15:11 ` Paolo Bonzini
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 15/24] instrument: [qmp, qapi] Add " Lluís Vilanova
` (10 subsequent siblings)
24 siblings, 2 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
This interface provides two sets of operations:
* Loading/unloading a trace instrumentation library.
* Controls the instrumentation callbacks of the tracing events.
Note that in the case of static instrumentation, the library is not
loaded/unloaded, but is still properly (de)initialized when QEMU starts and
exits.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile.objs | 2
configure | 3
instrument/Makefile.objs | 6 +
instrument/control-internal.h | 40 +++++
instrument/control.c | 226 ++++++++++++++++++++++++++++
instrument/control.h | 148 ++++++++++++++++++
instrument/qapi-schema.json | 26 +++
qapi-schema.json | 2
rules.mak | 3
scripts/tracetool/backend/instr_dynamic.py | 3
scripts/tracetool/backend/instr_static.py | 3
scripts/tracetool/format/events_c.py | 6 +
trace/event-internal.h | 5 +
13 files changed, 473 insertions(+)
create mode 100644 instrument/control-internal.h
create mode 100644 instrument/control.c
create mode 100644 instrument/control.h
create mode 100644 instrument/qapi-schema.json
diff --git a/Makefile.objs b/Makefile.objs
index 5f8ea2d..4fb565b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -94,6 +94,7 @@ common-obj-y += disas/
# instrumentation
tools-obj-y += instrument/
+target-obj-y += instrument/
######################################################################
# guest agent
@@ -114,5 +115,6 @@ nested-vars += \
qga-obj-y \
block-obj-y \
tools-obj-y \
+ target-obj-y \
common-obj-y
dummy := $(call unnest-vars)
diff --git a/configure b/configure
index b51436f..2be915c 100755
--- a/configure
+++ b/configure
@@ -3925,7 +3925,10 @@ fi
if test "$trace_instrument" = "dynamic"; then
echo "#define QI_TYPE_CONFIG_DYNAMIC 1" >> $config_qi
echo "CONFIG_TRACE_INSTRUMENT_DYNAMIC=y" >> $config_host_mak
+ libs_qga="-ldl $libs_qga"
fi
+# code requiring it is always compiled-in
+LIBS="-ldl $LIBS"
##########################################
echo "TOOLS=$tools" >> $config_host_mak
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index cae520d..e571c71 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -60,3 +60,9 @@ $(LIBTRACE_INSTRUMENT): $(dir $(LIBTRACE_INSTRUMENT))/Makefile force
TARGET_DIR=$(TARGET_DIR)$(dir $@)/ VPATH=$(VPATH) \
SRC_PATH=$(SRC_PATH) V="$(V)" $(notdir $@))
endif
+
+
+######################################################################
+# Control code
+
+target-obj-y += control.o
diff --git a/instrument/control-internal.h b/instrument/control-internal.h
new file mode 100644
index 0000000..68fc69c
--- /dev/null
+++ b/instrument/control-internal.h
@@ -0,0 +1,40 @@
+/*
+ * Interface for controlling dynamic trace instrumentation.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef INSTRUMENT__CONTROL_INTERNAL_H
+#define INSTRUMENT__CONTROL_INTERNAL_H
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "config-host.h"
+
+
+static inline InstrType instr_type(void)
+{
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+ return INSTR_TYPE_DYNAMIC;
+#elif defined(CONFIG_TRACE_INSTRUMENT_STATE)
+ return INSTR_TYPE_STATIC;
+#else
+ return INSTR_TYPE_NONE;
+#endif
+}
+
+static inline bool instr_event_available(TraceEvent *ev)
+{
+ assert(ev != NULL);
+#if defined(CONFIG_TRACE_INSTRUMENT)
+ return ev->instr;
+#else
+ return false;
+#endif
+}
+
+#endif /* INSTRUMENT__CONTROL_INTERNAL_H */
diff --git a/instrument/control.c b/instrument/control.c
new file mode 100644
index 0000000..7921bf3
--- /dev/null
+++ b/instrument/control.c
@@ -0,0 +1,226 @@
+/*
+ * Interface for controlling dynamic trace instrumentation.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "instrument/control.h"
+
+#include <dlfcn.h>
+
+#include "qemu-common.h"
+#include "trace/control.h"
+
+
+typedef int64_t HandleID;
+
+typedef struct Handle
+{
+ HandleID id;
+ void *dlhandle;
+ void (*init)(int, const char **);
+ void (*fini)(void);
+ QSLIST_ENTRY(Handle) list;
+} Handle;
+
+HandleID handle_last_id;
+QSLIST_HEAD(, Handle) handles = QSLIST_HEAD_INITIALIZER(handles);
+
+
+static Handle *handle_get(void)
+{
+ Handle *res = g_malloc0(sizeof(Handle));
+ res->id = handle_last_id++;
+ QSLIST_INSERT_HEAD(&handles, res, list);
+ return res;
+}
+
+static bool handle_put(HandleID id)
+{
+ Handle *prev = NULL;
+ Handle *handle;
+ QSLIST_FOREACH(handle, &handles, list) {
+ if (handle->id == id) {
+ break;
+ }
+ prev = handle;
+ }
+ if (handle == NULL) {
+ return false;
+ } else {
+ if (prev == NULL) {
+ QSLIST_REMOVE_HEAD(&handles, list);
+ } else {
+ QSLIST_REMOVE_AFTER(prev, list);
+ }
+ g_free(handle);
+ return true;
+ }
+}
+
+static Handle *handle_find(HandleID id)
+{
+ Handle *handle;
+ QSLIST_FOREACH(handle, &handles, list) {
+ if (handle->id == id) {
+ return handle;
+ }
+ }
+ return NULL;
+}
+
+
+bool instr_active(void)
+{
+ switch (instr_type()) {
+ case INSTR_TYPE_NONE:
+ return false;
+ break;
+ case INSTR_TYPE_STATIC:
+ return true;
+ break;
+ case INSTR_TYPE_DYNAMIC:
+ return !QSLIST_EMPTY(&handles);
+ case INSTR_TYPE_MAX:
+ assert(false);
+ }
+ return false;
+}
+
+
+InstrLoadError instr_load(const char * path, int argc, const char ** argv,
+ int64_t *handle_id)
+{
+ /* TODO: not thread safe */
+
+ *handle_id = -1;
+ if (instr_type() != INSTR_TYPE_DYNAMIC) {
+ return INSTR_LOAD_UNAVAILABLE;
+ }
+
+ if (!QSLIST_EMPTY(&handles) > 0) {
+ /* XXX: This is in fact a hard-coded limit, but there's no reason why a
+ * real multi-library implementation should fail with something lie
+ * "too many open libraries".
+ */
+ return INSTR_LOAD_UNAVAILABLE;
+ }
+
+ Handle * handle = handle_get();
+ handle->dlhandle = dlopen(path, RTLD_NOW);
+ if (handle->dlhandle == NULL) {
+ goto err;
+ }
+
+ handle->init = dlsym(handle->dlhandle, "qi_init");
+ if (handle->init == NULL) {
+ goto err;
+ }
+ handle->fini = dlsym(handle->dlhandle, "qi_fini");
+ if (handle->fini == NULL) {
+ goto err;
+ }
+
+ handle->init(argc, argv);
+
+ *handle_id = handle->id;
+ return INSTR_LOAD_OK;
+
+err:
+ handle_put(handle->id);
+ return INSTR_LOAD_ERROR;
+}
+
+InstrUnloadError instr_unload(int64_t handle_id)
+{
+ /* TODO: not thread safe */
+
+ if (instr_type() != INSTR_TYPE_DYNAMIC) {
+ return INSTR_UNLOAD_UNAVAILABLE;
+ }
+
+ Handle *handle = handle_find(handle_id);
+ if (handle == NULL) {
+ return INSTR_UNLOAD_INVALID;
+ }
+
+ handle->fini();
+
+ TraceEvent *ev = NULL;
+ while ((ev = trace_event_pattern("*", ev)) != NULL) {
+ if (instr_event_available(ev)) {
+ instr_event_set(ev, INSTR_CB_NOP);
+ }
+ }
+
+ /* this should never fail */
+ if (dlclose(handle->dlhandle) < 0) {
+ handle_put(handle->id);
+ return INSTR_UNLOAD_ERROR;
+ }
+
+ handle_put(handle->id);
+ return INSTR_UNLOAD_OK;
+}
+
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+static Handle *get_current_handle(void)
+{
+ /* XXX: We currently have only one */
+ return handle_find(handle_last_id - 1);
+}
+
+static void *get_event_symbol(Handle *handle, TraceEvent *ev, const char *fmt)
+{
+ assert(handle != NULL);
+ assert(ev != NULL);
+
+ char name[1024];
+ assert(strlen(trace_event_get_name(ev)) + strlen(fmt) < 1024);
+ sprintf(name, fmt, trace_event_get_name(ev));
+ return dlsym(handle->dlhandle, name);
+}
+
+static void event_set(TraceEvent *ev, void *cb)
+{
+ if (ev->instr_cb == cb) {
+ return;
+ }
+ assert(instr_event_available(ev));
+ *ev->instr_cb = cb;
+}
+#endif /* defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC) */
+
+bool instr_event_set(TraceEvent *ev, void *cb)
+{
+ assert(instr_type() == INSTR_TYPE_DYNAMIC);
+ assert(ev != NULL);
+ assert(instr_event_available(ev));
+
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+ if (cb == INSTR_CB_NOP) {
+ event_set(ev, ev->instr_cb_nop);
+ return true;
+ } else if (cb == INSTR_CB_NEXT) {
+ event_set(ev, ev->instr_cb_backend);
+ return true;
+ } else if (cb == INSTR_CB_AUTO) {
+ void *ptr = get_event_symbol(get_current_handle(),
+ ev, "qi_event_%s");
+ if (ptr != NULL) {
+ event_set(ev, ptr);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ event_set(ev, cb);
+ return true;
+ }
+#else
+ assert(false);
+#endif /* defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC) */
+}
diff --git a/instrument/control.h b/instrument/control.h
new file mode 100644
index 0000000..a6a648a
--- /dev/null
+++ b/instrument/control.h
@@ -0,0 +1,148 @@
+/*
+ * Interface for controlling dynamic trace instrumentation.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef INSTRUMENT__CONTROL_H
+#define INSTRUMENT__CONTROL_H
+
+#include "qapi-types.h"
+#include "trace/generated-events.h"
+
+
+/**
+ * InstrLoadError:
+ * @INSTR_LOAD_OK: Correctly loaded.
+ * @INSTR_LOAD_UNAVAILABLE: Service not available.
+ * @INSTR_LOAD_ERROR: Error with libdl (see dlerror).
+ *
+ * Error codes for instr_load().
+ */
+typedef enum {
+ INSTR_LOAD_OK,
+ INSTR_LOAD_UNAVAILABLE,
+ INSTR_LOAD_ERROR,
+} InstrLoadError;
+
+/**
+ * InstrUnloadError:
+ * @INSTR_UNLOAD_OK: Correctly unloaded.
+ * @INSTR_UNLOAD_UNAVAILABLE: Service not available.
+ * @INSTR_UNLOAD_INVALID: Invalid handle.
+ * @INSTR_UNLOAD_ERROR: Error with libdl (see dlerror).
+ *
+ * Error codes for instr_unload().
+ */
+typedef enum {
+ INSTR_UNLOAD_OK,
+ INSTR_UNLOAD_UNAVAILABLE,
+ INSTR_UNLOAD_INVALID,
+ INSTR_UNLOAD_ERROR,
+} InstrUnloadError;
+
+/**
+ * instr_load:
+ * @path: Path to the shared library to load.
+ * @argc: Number of arguments passed to the initialization function of the library.
+ * @argv: Arguments passed to the initialization function of the library.
+ * @handle: Instrumentation library handle (undefined in case of error).
+ *
+ * Load a dynamic trace instrumentation library.
+ *
+ * Returns: Whether the library could be loaded.
+ */
+InstrLoadError instr_load(const char * path, int argc, const char ** argv,
+ int64_t *handle);
+
+/**
+ * instr_unload:
+ * @handle: Instrumentation library handle returned by instr_load().
+ *
+ * Unload the given instrumentation library.
+ *
+ * Returns: Whether the library could be unloaded.
+ */
+InstrUnloadError instr_unload(int64_t handle);
+
+
+/**
+ * instr_type:
+ *
+ * Types are defined in QAPI's "instrument/qapi-schema.json"
+ *
+ * Returns: The system's #InstrType.
+ */
+static InstrType instr_type(void);
+
+/**
+ * instr_active:
+ *
+ * Always false when instr_type() is #INSTR_TYPE_NONE; always true when
+ * instr_type() is #INSTR_TYPE_STATIC.
+ *
+ * Returns: Whether an instrumentation library is currently active.
+ */
+bool instr_active(void);
+
+/**
+ * instr_event_available:
+ *
+ * Returns: Whether the given event has the 'instrument' property.
+ */
+static bool instr_event_available(TraceEvent *ev);
+
+
+/**
+ * INSTR_CB_NOP:
+ *
+ * Set callback to no-operation.
+ * (qi_event_${name}_nop).
+ */
+#define INSTR_CB_NOP ((void*)NULL)
+
+/**
+ * INSTR_CB_NEXT:
+ *
+ * Set callback to the "next logical step"
+ * (qi_event_${name}_trace).
+ */
+#define INSTR_CB_NEXT ((void*)1)
+
+/**
+ * INSTR_CB_AUTO:
+ *
+ * Automatically set callback to proper routine.
+ *
+ * Looks for a symbol name in the instrumentation library matching the event
+ * name (qi_event_${name}).
+ */
+#define INSTR_CB_AUTO ((void*)2)
+
+/**
+ * instr_event_set:
+ * @ev: Tracing event descriptor.
+ * @cb: Pointer to instrumentation callback.
+ *
+ * Set the instrumentation callback for the given event.
+ *
+ * Argument cb can also be set to any of the INSTR_CB_* special values.
+ *
+ * A negative return value indicates that the instrumentation library does not
+ * export the appropriate symbol for the instrumentation routine.
+ *
+ * Pre-condition: instr_type() == #INSTR_TYPE_DYNAMIC
+ * Pre-condition: instr_event_available(ev) == true
+ *
+ * Returns: Whether the callback could be set (if cb == INSTR_CB_AUTO, always
+ * true otherwise).
+ */
+bool instr_event_set(TraceEvent *ev, void *cb);
+
+
+#include "instrument/control-internal.h"
+
+#endif /* INSTRUMENT__CONTROL_H */
diff --git a/instrument/qapi-schema.json b/instrument/qapi-schema.json
new file mode 100644
index 0000000..e450ddf
--- /dev/null
+++ b/instrument/qapi-schema.json
@@ -0,0 +1,26 @@
+# *-*- Mode: Python -*-*
+#
+# QAPI trace instrumentation control commands.
+#
+# Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or later.
+# See the COPYING file in the top-level directory.
+
+##
+# @InstrType
+#
+# Instrumentation type supported by the system.
+#
+# @None: No instrumentation support.
+#
+# @Static: Static instrumentation support.
+#
+# @Dynamic: Dynamic instrumentation support.
+#
+# Warning: Keep in sync with #QIType.
+#
+# Since: 1.5
+##
+{ 'enum': 'InstrType',
+ 'data': [ 'None', 'Static', 'Dynamic' ] }
diff --git a/qapi-schema.json b/qapi-schema.json
index db542f6..36e5cbf 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3513,3 +3513,5 @@
'*asl_compiler_rev': 'uint32',
'*file': 'str',
'*data': 'str' }}
+
+include("instrument/qapi-schema.json")
diff --git a/rules.mak b/rules.mak
index edc2552..e0767a9 100644
--- a/rules.mak
+++ b/rules.mak
@@ -51,6 +51,9 @@ endif
%.o: %.dtrace
$(call quiet-command,dtrace -o $@ -G -s $<, " GEN $(TARGET_DIR)$@")
+ifdef CONFIG_TRACE_INSTRUMENT_DYNAMIC
+%$(EXESUF): LDFLAGS+=-rdynamic
+endif
%$(EXESUF): %.o
$(call LINK,$^)
diff --git a/scripts/tracetool/backend/instr_dynamic.py b/scripts/tracetool/backend/instr_dynamic.py
index a07ee64..12d0503 100644
--- a/scripts/tracetool/backend/instr_dynamic.py
+++ b/scripts/tracetool/backend/instr_dynamic.py
@@ -40,6 +40,9 @@ def qemu_h(events):
def api_h(events):
out('#include <qemu-instr/visibility-internal.h>',
'',
+ 'QI_VPUBLIC void qi_init(int argc, const char **argv);',
+ 'QI_VPUBLIC void qi_fini(void);',
+ '',
)
for e in events:
diff --git a/scripts/tracetool/backend/instr_static.py b/scripts/tracetool/backend/instr_static.py
index b010596..ecebbda 100644
--- a/scripts/tracetool/backend/instr_static.py
+++ b/scripts/tracetool/backend/instr_static.py
@@ -46,6 +46,9 @@ def qemu_h(events):
def api_h(events):
out('#include "trace/generated-tracers.h"',
'',
+ 'void qi_init(int argc, const char **argv);',
+ 'void qi_fini(void);',
+ '',
)
for e in events:
diff --git a/scripts/tracetool/format/events_c.py b/scripts/tracetool/format/events_c.py
index 7531c66..d7b4f86 100644
--- a/scripts/tracetool/format/events_c.py
+++ b/scripts/tracetool/format/events_c.py
@@ -44,14 +44,19 @@ def begin(events):
out('TraceEvent trace_events[TRACE_EVENT_COUNT] = {')
for e in events:
+ instr = "false"
cb = cb_nop = cb_backend = "NULL"
if "instrument" in e.properties:
+ instr = "true"
cb = "&%s_cb" % e.api(e.QI_TRACE_INSTRUMENT)
cb_nop = e.api(e.QI_TRACE_NOP)
cb_backend = e.api(e.QI_TRACE_BACKEND)
out(' { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s, .dstate = 0,',
+ '#if !defined(CONFIG_TRACE_INSTRUMENT_NONE)',
+ ' .instr = %(instr)s,',
+ '#endif',
'#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)',
' .instr_cb = %(cb)s,',
' .instr_cb_nop = %(cb_nop)s,',
@@ -59,6 +64,7 @@ def begin(events):
'#endif',
' },',
id = "TRACE_" + e.name.upper(),
+ instr = instr,
cb = cb,
cb_nop = cb_nop,
cb_backend = cb_backend,
diff --git a/trace/event-internal.h b/trace/event-internal.h
index aed4050..7110886 100644
--- a/trace/event-internal.h
+++ b/trace/event-internal.h
@@ -20,6 +20,7 @@
* @name: Event name.
* @sstate: Static tracing state.
* @dstate: Dynamic tracing state.
+ * @instr: Whether the event is instrumentable.
* @instr_cb: Instrumentation callback pointer.
* @instr_cb_nop: Instrumentation callback pointer to no-operation.
* @instr_cb_backend: Instrumentation callback pointer to tracing backend.
@@ -32,6 +33,10 @@ typedef struct TraceEvent {
const bool sstate;
bool dstate;
+#if defined(CONFIG_TRACE_INSTRUMENT)
+ const bool instr;
+#endif
+
#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
void **instr_cb;
void *instr_cb_nop;
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 15/24] instrument: [qmp, qapi] Add control interface
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (13 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 14/24] instrument: Add internal control interface Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 16/24] instrument: [hmp] " Lluís Vilanova
` (9 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
Add QMP commands to control (un)loading of dynamic instrumentation library.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
instrument/Makefile.objs | 2 +
instrument/control.h | 4 +
instrument/qapi-schema.json | 124 +++++++++++++++++++++++++++++++++++++++++++
instrument/qmp.c | 78 +++++++++++++++++++++++++++
qmp-commands.hx | 71 +++++++++++++++++++++++++
qmp.c | 4 +
6 files changed, 283 insertions(+)
create mode 100644 instrument/qmp.c
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index e571c71..af1c96b 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -66,3 +66,5 @@ endif
# Control code
target-obj-y += control.o
+
+common-obj-$(CONFIG_SOFTMMU) += qmp.o
diff --git a/instrument/control.h b/instrument/control.h
index a6a648a..77d77ad 100644
--- a/instrument/control.h
+++ b/instrument/control.h
@@ -21,6 +21,8 @@
* @INSTR_LOAD_ERROR: Error with libdl (see dlerror).
*
* Error codes for instr_load().
+ *
+ * Warning: Keep in sync with #InstrLoadCode
*/
typedef enum {
INSTR_LOAD_OK,
@@ -36,6 +38,8 @@ typedef enum {
* @INSTR_UNLOAD_ERROR: Error with libdl (see dlerror).
*
* Error codes for instr_unload().
+ *
+ * Warning: Keep in sync with #InstrUnloadCode
*/
typedef enum {
INSTR_UNLOAD_OK,
diff --git a/instrument/qapi-schema.json b/instrument/qapi-schema.json
index e450ddf..900160b 100644
--- a/instrument/qapi-schema.json
+++ b/instrument/qapi-schema.json
@@ -24,3 +24,127 @@
##
{ 'enum': 'InstrType',
'data': [ 'None', 'Static', 'Dynamic' ] }
+
+##
+# @InstrState
+#
+# Instrumentation state.
+#
+# Instrumentation is never active if @type is #None.
+#
+# Instrumentation is always active if @type is #Static.
+#
+# @type: The system's @InstrType.
+#
+# @active: Whether an instrumentation is loaded.
+#
+# @handles: List of handles for currently loaded instrumentation libraries.
+#
+# Since: 1.5
+##
+{ 'type': 'InstrState',
+ 'data': { 'type': 'InstrType', 'active': 'bool' } }
+
+##
+# @instr-query:
+#
+# Returns the current instrumentation state.
+#
+# Since: 1.5
+##
+{ 'command': 'instr-query',
+ 'returns': 'InstrState' }
+
+
+##
+# @InstrLoadCode
+#
+# Result code of an 'instr-load' command.
+#
+# @OK: Correctly loaded.
+#
+# @Unavailable: Service not available.
+#
+# @Error: Error with libdl (see 'msg').
+#
+# Since: 1.5
+##
+{ 'enum': 'InstrLoadCode'
+ 'data': [ 'OK', 'Unavailable', 'Error' ] }
+
+##
+# @InstrLoadResult
+#
+# Result of an 'instr-load' command.
+#
+# @code: Result code.
+#
+# @msg: Additional error message.
+#
+# @handle: Instrumentation library identifier (undefined in case of error).
+#
+# Since: 1.5
+##
+{ 'type': 'InstrLoadResult'
+ 'data': { 'code': 'InstrLoadCode', 'msg': 'str', 'handle': 'int' } }
+
+##
+# @instr-load:
+#
+# Load an instrumentation library.
+#
+# @path: path to the dynamic instrumentation library
+#
+# @args: arguments to the dynamic instrumentation library
+#
+# Since: 1.5
+##
+{ 'command': 'instr-load',
+ 'data': { 'path': 'str', '*args': ['String'] },
+ 'returns': 'InstrLoadResult' }
+
+
+##
+# @InstrUnloadCode
+#
+# Result code of an 'instr-unload' command.
+#
+# @OK: Correctly unloaded.
+#
+# @Unavailable: Service not available.
+#
+# @Invalid: Invalid handle.
+#
+# @Error: Error with libdl (see 'msg').
+#
+# Since: 1.5
+##
+{ 'enum': 'InstrUnloadCode'
+ 'data': [ 'OK', 'Unavailable', 'Invalid', 'Error' ] }
+
+##
+# @InstrUnloadResult
+#
+# Result of an 'instr-unload' command.
+#
+# @code: Result code.
+#
+# @msg: Additional error message.
+#
+# Since: 1.5
+##
+{ 'type': 'InstrUnloadResult'
+ 'data': { 'code': 'InstrUnloadCode', 'msg': 'str' } }
+
+##
+# @instr-unload:
+#
+# Unload an instrumentation library.
+#
+# @handle: Instrumentation library identifier (see #InstrLoadResult).
+#
+# Since: 1.5
+##
+{ 'command': 'instr-unload',
+ 'data': { 'handle': 'int' },
+ 'returns': 'InstrUnloadResult' }
diff --git a/instrument/qmp.c b/instrument/qmp.c
new file mode 100644
index 0000000..780c06e
--- /dev/null
+++ b/instrument/qmp.c
@@ -0,0 +1,78 @@
+/*
+ * QMP interface for dynamic trace instrumentation control commands.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+#include "qapi/qmp/qerror.h"
+#include "qmp-commands.h"
+
+#include <dlfcn.h>
+
+#include "instrument/control.h"
+
+
+
+InstrState *qmp_instr_query (Error **errp)
+{
+ InstrState *res = g_malloc0(sizeof(*res));
+ res->type = instr_type();
+ res->active = instr_active();
+ return res;
+}
+
+InstrLoadResult *qmp_instr_load(const char * path,
+ bool have_args, StringList * args,
+ Error **errp)
+{
+ int argc = 0;
+ const char **argv = NULL;
+
+ StringList *entry = have_args ? args : NULL;
+ while (entry != NULL) {
+ argv = realloc(argv, sizeof(*argv) * (argc + 1));
+ argv[argc] = entry->value->str;
+ argc++;
+ entry = entry->next;
+ }
+
+ InstrLoadResult *res = g_malloc0(sizeof(*res));
+ res->code = instr_load(path, argc, argv, &res->handle);
+ switch (res->code) {
+ case INSTR_LOAD_CODE_OK:
+ case INSTR_LOAD_CODE_UNAVAILABLE:
+ break;
+ case INSTR_LOAD_CODE_ERROR:
+ res->msg = dlerror();
+ break;
+ default:
+ fprintf(stderr, "Unknown instrumentation load code: %d", res->code);
+ exit(1);
+ break;
+ }
+ return res;
+}
+
+InstrUnloadResult *qmp_instr_unload(int64_t handle, Error **errp)
+{
+ InstrUnloadResult *res = g_malloc0(sizeof(*res));
+ res->code = instr_unload(handle);
+ switch (res->code) {
+ case INSTR_UNLOAD_OK:
+ case INSTR_UNLOAD_UNAVAILABLE:
+ case INSTR_UNLOAD_INVALID:
+ break;
+ case INSTR_UNLOAD_CODE_ERROR:
+ res->msg = dlerror();
+ break;
+ default:
+ fprintf(stderr, "Unknown instrumentation unload code: %d", res->code);
+ exit(1);
+ break;
+ }
+ return res;
+}
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 1e0e11e..65873dd 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1510,6 +1510,77 @@ Notes:
o Commands that prompt the user for data (eg. 'cont' when the block
device is encrypted) don't currently work
+instr-query
+-----------
+
+Query the instrumentation state.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "instr-query" }
+<- { "return": { "type": "Dynamic", "active": "None" } }
+
+EQMP
+
+ {
+ .name = "instr-query",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_instr_query,
+ },
+
+
+SQMP
+
+instr-load
+----------
+
+Load a dynamic instrumentation library.
+
+Arguments:
+
+- path: path to the dynamic instrumentation library
+- args: arguments to the dynamic instrumentation library
+
+Example:
+
+-> { "execute": "instr-load", "arguments": { "path": "/tmp/libtrace-instrument.so" } }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "instr-load",
+ .args_type = "path:F,args:s?",
+ .mhandler.cmd_new = qmp_marshal_input_instr_load,
+ },
+
+
+SQMP
+
+instr-unload
+------------
+
+Unload the current dynamic instrumentation library.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "instr-unload" }
+<- { "return": {} }
+
+EQMP
+
+ {
+ .name = "instr-unload",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_instr_unload,
+ },
+
+
+SQMP
3. Query Commands
=================
diff --git a/qmp.c b/qmp.c
index 55b056b..72abe03 100644
--- a/qmp.c
+++ b/qmp.c
@@ -24,6 +24,10 @@
#include "hw/qdev.h"
#include "sysemu/blockdev.h"
#include "qom/qom-qobject.h"
+#if defined(TRACE_INSTRUMENT_DYNAMIC)
+#include "instrument/qi-qmp-commands.h"
+#endif
+
NameInfo *qmp_query_name(Error **errp)
{
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 16/24] instrument: [hmp] Add control interface
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (14 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 15/24] instrument: [qmp, qapi] Add " Lluís Vilanova
@ 2013-04-21 19:12 ` Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 17/24] Let makefiles add entries to the set of target architecture objects Lluís Vilanova
` (8 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:12 UTC (permalink / raw)
To: qemu-devel
Add HMP commands to control (un)loading of dynamic instrumentation library.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile.objs | 1 +
hmp-commands.hx | 42 ++++++++++++++++++++++++
instrument/Makefile.objs | 1 +
instrument/hmp.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++
instrument/hmp.h | 21 ++++++++++++
monitor.c | 1 +
6 files changed, 145 insertions(+)
create mode 100644 instrument/hmp.c
create mode 100644 instrument/hmp.h
diff --git a/Makefile.objs b/Makefile.objs
index 4fb565b..151183d 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -95,6 +95,7 @@ common-obj-y += disas/
tools-obj-y += instrument/
target-obj-y += instrument/
+common-obj-y += instrument/
######################################################################
# guest agent
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 3d98604..2e88e4b 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1653,6 +1653,48 @@ STEXI
show available trace events and their state
ETEXI
+ {
+ .name = "instr-query",
+ .args_type = "",
+ .params = "",
+ .help = "instrumentation state",
+ .mhandler.cmd = hmp_instr_query,
+ },
+
+STEXI
+@item instr-dynamic
+@findex instr-dynamic
+Whether dynamic trace instrumentation is available.
+ETEXI
+
+ {
+ .name = "instr-load",
+ .args_type = "path:F,args:s?",
+ .params = "path [args]",
+ .help = "load an instrumentation library",
+ .mhandler.cmd = hmp_instr_load,
+ },
+
+STEXI
+@item instr-load @var{path} [name=value[,...]]
+@findex instr-load
+Load an instrumentation library.
+ETEXI
+
+ {
+ .name = "instr-unload",
+ .args_type = "handle:i",
+ .params = "",
+ .help = "unload an instrumentation library",
+ .mhandler.cmd = hmp_instr_unload,
+ },
+
+STEXI
+@item instr-unload
+@findex instr-unload
+Unload an instrumentation library.
+ETEXI
+
STEXI
@end table
ETEXI
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index af1c96b..2122272 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -68,3 +68,4 @@ endif
target-obj-y += control.o
common-obj-$(CONFIG_SOFTMMU) += qmp.o
+common-obj-$(CONFIG_SOFTMMU) += hmp.o
diff --git a/instrument/hmp.c b/instrument/hmp.c
new file mode 100644
index 0000000..81b334c
--- /dev/null
+++ b/instrument/hmp.c
@@ -0,0 +1,79 @@
+/*
+ * HMP interface for dynamic trace instrumentation control commands.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "instrument/hmp.h"
+
+#include <dlfcn.h>
+
+#include "monitor/monitor.h"
+#include "qmp-commands.h"
+#include "instrument/control.h"
+
+
+void hmp_instr_query(Monitor *mon, const QDict *qdict)
+{
+ InstrState *state = qmp_instr_query(NULL);
+ monitor_printf(mon, "Type: %s\n", InstrType_lookup[state->type]);
+ monitor_printf(mon, "Active: %s\n", state->active ? "true" : "false");
+}
+
+void hmp_instr_load(Monitor *mon, const QDict *qdict)
+{
+ const char *path = qdict_get_str(qdict, "path");
+ String str;
+ str.str = (char *)qdict_get_try_str(qdict, "args");
+ StringList args;
+ args.value = str.str == NULL ? NULL : &str;
+ args.next = NULL;
+ InstrLoadResult *res = qmp_instr_load(path, args.value != NULL,
+ args.value != NULL ? &args : NULL,
+ NULL);
+ switch (res->code) {
+ case INSTR_LOAD_CODE_OK:
+ monitor_printf(mon, "Handle: %"PRId64"\n", res->handle);
+ monitor_printf(mon, "OK\n");
+ break;
+ case INSTR_LOAD_CODE_UNAVAILABLE:
+ monitor_printf(mon, "Not available\n");
+ break;
+ case INSTR_LOAD_CODE_ERROR:
+ monitor_printf(mon, "Error loading library: %s\n", res->msg);
+ break;
+ default:
+ fprintf(stderr, "Unknown instrumentation load code: %d", res->code);
+ exit(1);
+ break;
+ }
+ qapi_free_InstrLoadResult(res);
+}
+
+void hmp_instr_unload(Monitor *mon, const QDict *qdict)
+{
+ int64_t handle = qdict_get_int(qdict, "handle");
+ InstrUnloadResult *res = qmp_instr_unload(handle, NULL);
+ switch (res->code) {
+ case INSTR_UNLOAD_CODE_OK:
+ monitor_printf(mon, "OK\n");
+ break;
+ case INSTR_UNLOAD_CODE_UNAVAILABLE:
+ monitor_printf(mon, "Not available\n");
+ break;
+ case INSTR_UNLOAD_CODE_INVALID:
+ monitor_printf(mon, "Invalid handle\n");
+ break;
+ case INSTR_UNLOAD_CODE_ERROR:
+ monitor_printf(mon, "Error unloading library: %s\n", res->msg);
+ break;
+ default:
+ fprintf(stderr, "Unknown instrumentation unload code: %d", res->code);
+ exit(1);
+ break;
+ }
+ qapi_free_InstrUnloadResult(res);
+}
diff --git a/instrument/hmp.h b/instrument/hmp.h
new file mode 100644
index 0000000..f54ec0b
--- /dev/null
+++ b/instrument/hmp.h
@@ -0,0 +1,21 @@
+/*
+ * HMP interface for dynamic trace instrumentation control commands.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef INSTRUMENT__HMP_H
+#define INSTRUMENT__HMP_H
+
+#include "qemu-common.h"
+#include "qapi/qmp/qdict.h"
+
+
+void hmp_instr_query(Monitor *mon, const QDict *qdict);
+void hmp_instr_load(Monitor *mon, const QDict *qdict);
+void hmp_instr_unload(Monitor *mon, const QDict *qdict);
+
+#endif /* INSTRUMENT__HMP_H */
diff --git a/monitor.c b/monitor.c
index a8f49d9..22284cb 100644
--- a/monitor.c
+++ b/monitor.c
@@ -69,6 +69,7 @@
#include "exec/memory.h"
#include "qmp-commands.h"
#include "hmp.h"
+#include "instrument/hmp.h"
#include "qemu/thread.h"
/* for pic/irq_info */
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 17/24] Let makefiles add entries to the set of target architecture objects
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (15 preceding siblings ...)
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 16/24] instrument: [hmp] " Lluís Vilanova
@ 2013-04-21 19:13 ` Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 18/24] instrument: Add commandline options to start with an instrumentation library Lluís Vilanova
` (7 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:13 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile.target | 1 +
1 file changed, 1 insertion(+)
diff --git a/Makefile.target b/Makefile.target
index 114fc39..fe48432 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -149,6 +149,7 @@ include $(SRC_PATH)/Makefile.objs
all-obj-y = $(obj-y)
all-obj-y += $(addprefix ../, $(common-obj-y))
+all-obj-y += $(target-obj-y)
all-obj-y += $(LIBTRACE_INSTRUMENT)
ifdef QEMU_PROGW
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 18/24] instrument: Add commandline options to start with an instrumentation library
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (16 preceding siblings ...)
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 17/24] Let makefiles add entries to the set of target architecture objects Lluís Vilanova
@ 2013-04-21 19:13 ` Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 19/24] instrument: Add client-side API to enumerate events Lluís Vilanova
` (6 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:13 UTC (permalink / raw)
To: qemu-devel
Add commandline options to control initial loading of dynamic instrumentation
library.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
bsd-user/main.c | 22 +++++++++++
bsd-user/syscall.c | 5 +++
instrument/Makefile.objs | 2 +
instrument/cmdline.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++
instrument/cmdline.h | 52 ++++++++++++++++++++++++++
linux-user/main.c | 31 ++++++++++++++++
linux-user/syscall.c | 4 ++
qemu-options.hx | 18 +++++++++
vl.c | 41 +++++++++++++++++++++
9 files changed, 266 insertions(+)
create mode 100644 instrument/cmdline.c
create mode 100644 instrument/cmdline.h
diff --git a/bsd-user/main.c b/bsd-user/main.c
index cc84981..2393be9 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -33,6 +33,9 @@
#include "tcg.h"
#include "qemu/timer.h"
#include "qemu/envlist.h"
+#include "instrument/cmdline.h"
+#include "instrument/control.h"
+
int singlestep;
#if defined(CONFIG_USE_GUEST_BASE)
@@ -688,6 +691,15 @@ static void usage(void)
#endif
"-bsd type select emulated BSD type FreeBSD/NetBSD/OpenBSD (default)\n"
"\n"
+#if defined(CONFIG_TRACE_INSTRUMENT)
+ "Tracing options:\n"
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+ "-instr path load a dynamic trace instrumentation library\n"
+#endif
+ "-instr-arg string\n"
+ " argument to trace instrumentation library (can be given multiple times)\n"
+ "\n"
+#endif
"Debug options:\n"
"-d item1[,...] enable logging of specified items\n"
" (use '-d help' for a list of log items)\n"
@@ -743,6 +755,9 @@ int main(int argc, char **argv)
char **target_environ, **wrk;
envlist_t *envlist = NULL;
bsd_type = target_openbsd;
+ char *instrument_path = NULL;
+ int instrument_argc = 0;
+ char **instrument_argv = NULL;
if (argc <= 1)
usage();
@@ -852,6 +867,10 @@ int main(int argc, char **argv)
singlestep = 1;
} else if (!strcmp(r, "strace")) {
do_strace = 1;
+ } else if (instr_type() == INSTR_TYPE_DYNAMIC && !strcmp(r, "instr")) {
+ instrument_path = argv[optind++];
+ } else if (instr_type() != INSTR_TYPE_NONE && !strcmp(r, "instr-arg")) {
+ instr_parse_args(argv[optind++], &instrument_argc, &instrument_argv);
} else
{
usage();
@@ -1135,6 +1154,9 @@ int main(int argc, char **argv)
gdbserver_start (gdbstub_port);
gdb_handlesig(env, 0);
}
+
+ instr_init(instrument_path, instrument_argc, instrument_argv);
+
cpu_loop(env);
/* never exits */
return 0;
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 18b43f1..dbb6816 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -35,6 +35,8 @@
#include "qemu.h"
#include "qemu-common.h"
+#include "instrument/cmdline.h"
+
//#define DEBUG
@@ -334,6 +336,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
_mcleanup();
#endif
gdb_exit(cpu_env, arg1);
+ instr_fini();
/* XXX: should free thread stack and CPU env */
_exit(arg1);
ret = 0; /* avoid warning */
@@ -429,6 +432,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
_mcleanup();
#endif
gdb_exit(cpu_env, arg1);
+ instr_fini();
/* XXX: should free thread stack and CPU env */
_exit(arg1);
ret = 0; /* avoid warning */
@@ -501,6 +505,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
_mcleanup();
#endif
gdb_exit(cpu_env, arg1);
+ instr_fini();
/* XXX: should free thread stack and CPU env */
_exit(arg1);
ret = 0; /* avoid warning */
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 2122272..3116520 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -65,6 +65,8 @@ endif
######################################################################
# Control code
+target-obj-y += cmdline.o
+
target-obj-y += control.o
common-obj-$(CONFIG_SOFTMMU) += qmp.o
diff --git a/instrument/cmdline.c b/instrument/cmdline.c
new file mode 100644
index 0000000..add9c63
--- /dev/null
+++ b/instrument/cmdline.c
@@ -0,0 +1,91 @@
+/*
+ * Control dynamic trace instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "instrument/cmdline.h"
+
+#include <dlfcn.h>
+
+#include "qemu-common.h"
+#include "instrument/control.h"
+
+#if defined(CONFIG_TRACE_INSTRUMENT_STATIC)
+#include "instrument/qemu-instr/events.h"
+#endif
+
+
+static int64_t handle = -1;
+
+
+void instr_parse_args(const char *args, int *argc, const char ***argv)
+{
+ *argv = realloc(*argv, sizeof(**argv) * (*argc + 1));
+ (*argv)[*argc] = args;
+ (*argc)++;
+}
+
+void instr_init(const char *path, int argc, const char **argv)
+{
+ if (atexit(instr_fini) != 0) {
+ fprintf(stderr, "error: atexit: %s\n", strerror(errno));
+ abort();
+ }
+
+ if (path == NULL) {
+#if defined(CONFIG_TRACE_INSTRUMENT_STATIC)
+ handle = 0;
+ qi_init(argc, argv);
+#endif
+ return;
+ }
+
+ InstrLoadError err = instr_load(path, argc, argv, &handle);
+ switch (err) {
+ case INSTR_LOAD_OK:
+ return;
+ case INSTR_LOAD_UNAVAILABLE:
+ fprintf(stderr, "error: instrument: not available\n");
+ break;
+ case INSTR_LOAD_ERROR:
+ assert(instr_type() == INSTR_TYPE_DYNAMIC);
+ fprintf(stderr, "error: instrument: error loading library: %s\n", dlerror());
+ break;
+ }
+
+ exit(1);
+}
+
+void instr_fini(void)
+{
+ if (handle >= 0) {
+ return;
+ }
+
+#if defined(CONFIG_TRACE_INSTRUMENT_STATIC)
+ qi_fini();
+ return;
+#endif
+
+ InstrUnloadError err = instr_unload(handle);
+ switch (err) {
+ case INSTR_UNLOAD_OK:
+ return;
+ case INSTR_UNLOAD_UNAVAILABLE:
+ fprintf(stderr, "error: not available\n");
+ break;
+ case INSTR_UNLOAD_INVALID:
+ /* the user might have already unloaded it */
+ return;
+ case INSTR_UNLOAD_ERROR:
+ assert(instr_type() == INSTR_TYPE_DYNAMIC);
+ fprintf(stderr, "error: error unloading library: %s\n", dlerror());
+ break;
+ }
+
+ exit(1);
+}
diff --git a/instrument/cmdline.h b/instrument/cmdline.h
new file mode 100644
index 0000000..b096793
--- /dev/null
+++ b/instrument/cmdline.h
@@ -0,0 +1,52 @@
+/*
+ * Control dynamic trace instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef INSTRUMENT__CMDLINE_H
+#define INSTRUMENT__CMDLINE_H
+
+/**
+ * instr_parse_args:
+ * @args: Input arguments.
+ * @argc: Output argument count.
+ * @argv: Output argument array.
+ *
+ * Adds element @args into the argument array.
+ */
+void instr_parse_args(const char *args, int *argc, const char ***argv);
+
+/**
+ * instr_init:
+ * @path: Path to dynamic trace instrumentation library.
+ * @argc: Number of arguments to the library's #qi_init routine.
+ * @argv: Arguments to the library's #qi_init routine.
+ *
+ * Load and initialize the given instrumentation library.
+ *
+ * Automatically installs #instr_fini as an atexit callback.
+ *
+ * If path is %NULL and we're running with static instrumentation, the library
+ * is not loaded but just initialized.
+ *
+ * Pre-condition: There is no library already loaded.
+ */
+void instr_init(const char *path, int argc, const char **argv);
+
+/**
+ * instr_fini:
+ *
+ * Deinitialize and unload the current instrumentation library.
+ *
+ * If we're running with static instrumentation, the library is not unloaded but
+ * just deinitialized.
+ *
+ * Pre-condition: There is an already loaded library.
+ */
+void instr_fini(void);
+
+#endif /* INSTRUMENT__CMDLINE_H */
diff --git a/linux-user/main.c b/linux-user/main.c
index 4e92a0b..d6f4720 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -34,6 +34,9 @@
#include "qemu/timer.h"
#include "qemu/envlist.h"
#include "elf.h"
+#include "instrument/cmdline.h"
+#include "instrument/control.h"
+
char *exec_path;
@@ -3327,6 +3330,23 @@ static void handle_arg_reserved_va(const char *arg)
}
#endif
+static const char *instrument_path;
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+static void handle_arg_instrument(const char *arg)
+{
+ instrument_path = arg;
+}
+#endif
+
+static int instrument_argc = 0;
+static const char **instrument_argv = NULL;
+#if defined(CONFIG_TRACE_INSTRUMENT)
+static void handle_arg_instrument_arg(const char *arg)
+{
+ instr_parse_args(arg, &instrument_argc, &instrument_argv);
+}
+#endif
+
static void handle_arg_singlestep(const char *arg)
{
singlestep = 1;
@@ -3378,6 +3398,14 @@ static const struct qemu_argument arg_table[] = {
{"R", "QEMU_RESERVED_VA", true, handle_arg_reserved_va,
"size", "reserve 'size' bytes for guest virtual address space"},
#endif
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+ {"instr", "QEMU_INSTR", true, handle_arg_instrument,
+ "path", "load a dynamic trace instrumentation library"},
+#endif
+#if defined(CONFIG_TRACE_INSTRUMENT)
+ {"instr-arg", "QEMU_INSTR_ARGS", true, handle_arg_instrument_arg,
+ "string", "argument to trace instrumentation library (can be given multiple times)"},
+#endif
{"d", "QEMU_LOG", true, handle_arg_log,
"item[,...]", "enable logging of specified items "
"(use '-d help' for a list of items)"},
@@ -4071,6 +4099,9 @@ int main(int argc, char **argv, char **envp)
}
gdb_handlesig(env, 0);
}
+
+ instr_init(instrument_path, instrument_argc, instrument_argv);
+
cpu_loop(env);
/* never exits */
return 0;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 1f07621..d55af6c 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -109,6 +109,8 @@ int __clone2(int (*fn)(void *), void *child_stack_base,
#include "cpu-uname.h"
#include "qemu.h"
+#include "instrument/cmdline.h"
+
#if defined(CONFIG_USE_NPTL)
#define CLONE_NPTL_FLAGS2 (CLONE_SETTLS | \
@@ -5248,6 +5250,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
_mcleanup();
#endif
gdb_exit(cpu_env, arg1);
+ instr_fini();
_exit(arg1);
ret = 0; /* avoid warning */
break;
@@ -7028,6 +7031,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
_mcleanup();
#endif
gdb_exit(cpu_env, arg1);
+ instr_fini();
ret = get_errno(exit_group(arg1));
break;
#endif
diff --git a/qemu-options.hx b/qemu-options.hx
index 7cd6002..0f36c1c 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3021,6 +3021,24 @@ the @var{simple} tracing backend.
@end table
ETEXI
+DEF("instr", HAS_ARG, QEMU_OPTION_instr,
+ "-instr file=<file>[,arg=<string>]\n"
+ " load an instrumentation library\n",
+ QEMU_ARCH_ALL)
+STEXI
+@item -instr file=@var{file}[,arg=@var{string}]
+@findex -instr
+
+Load a dynamic trace instrumentation library.
+
+@table @option
+@item file=@var{file}
+Load the given dynamic trace instrumentation library.
+@item arg=@var{string}
+String argument passed as to the library's @code{qi_init} routine (can be given multiple times).
+@end table
+ETEXI
+
HXCOMM Internal use
DEF("qtest", HAS_ARG, QEMU_OPTION_qtest, "", QEMU_ARCH_ALL)
DEF("qtest-log", HAS_ARG, QEMU_OPTION_qtest_log, "", QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index d694a90..e773bb4 100644
--- a/vl.c
+++ b/vl.c
@@ -163,6 +163,7 @@ int main(int argc, char **argv)
#include "trace.h"
#include "trace/control.h"
+#include "instrument/cmdline.h"
#include "qemu/queue.h"
#include "sysemu/cpus.h"
#include "sysemu/arch_init.h"
@@ -352,6 +353,22 @@ static QemuOptsList qemu_trace_opts = {
},
};
+static QemuOptsList qemu_instr_opts = {
+ .name = "instr",
+ .implied_opt_name = "instr",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_instr_opts.head),
+ .desc = {
+ {
+ .name = "file",
+ .type = QEMU_OPT_STRING,
+ },{
+ .name = "arg",
+ .type = QEMU_OPT_STRING,
+ },
+ { /* end of list */ }
+ },
+};
+
static QemuOptsList qemu_option_rom_opts = {
.name = "option-rom",
.implied_opt_name = "romfile",
@@ -2883,6 +2900,9 @@ int main(int argc, char **argv, char **envp)
};
const char *trace_events = NULL;
const char *trace_file = NULL;
+ const char *instrument_path = NULL;
+ int instrument_argc = 0;
+ const char **instrument_argv = NULL;
atexit(qemu_run_exit_notifiers);
error_set_progname(argv[0]);
@@ -2908,6 +2928,7 @@ int main(int argc, char **argv, char **envp)
qemu_add_opts(&qemu_global_opts);
qemu_add_opts(&qemu_mon_opts);
qemu_add_opts(&qemu_trace_opts);
+ qemu_add_opts(&qemu_instr_opts);
qemu_add_opts(&qemu_option_rom_opts);
qemu_add_opts(&qemu_machine_opts);
qemu_add_opts(&qemu_boot_opts);
@@ -3820,6 +3841,24 @@ int main(int argc, char **argv, char **envp)
trace_file = qemu_opt_get(opts, "file");
break;
}
+ case QEMU_OPTION_instr:
+ {
+ olist = qemu_find_opts("instr");
+ if (!olist) {
+ exit(1);
+ }
+ opts = qemu_opts_parse(olist, optarg, 0);
+ if (!opts) {
+ exit(1);
+ }
+ const char * path = qemu_opt_get(opts, "file");
+ if (path != NULL) {
+ instrument_path = path;
+ }
+ instr_parse_args(qemu_opt_get(opts, "arg"),
+ &instrument_argc, &instrument_argv);
+ break;
+ }
case QEMU_OPTION_readconfig:
{
int ret = qemu_read_config_file(optarg);
@@ -4414,6 +4453,8 @@ int main(int argc, char **argv, char **envp)
}
}
+ instr_init(instrument_path, instrument_argc, instrument_argv);
+
if (incoming) {
Error *local_err = NULL;
qemu_start_incoming_migration(incoming, &local_err);
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 19/24] instrument: Add client-side API to enumerate events
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (17 preceding siblings ...)
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 18/24] instrument: Add commandline options to start with an instrumentation library Lluís Vilanova
@ 2013-04-21 19:13 ` Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 20/24] instrument: Add client-side API to control tracing state of events Lluís Vilanova
` (5 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:13 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
.gitignore | 1
Makefile | 1
configure | 1
instrument/Makefile.objs | 13 +++
instrument/api-control.c | 14 +++
instrument/qemu-instr/control-internal.h | 53 ++++++++++++
instrument/qemu-instr/control.h | 124 +++++++++++++++++++++++++++
instrument/qemu-instr/visibility-internal.h | 94 ++++++++++++++++++++
scripts/tracetool/backend/instr_dynamic.py | 3 +
scripts/tracetool/backend/instr_none.py | 3 +
scripts/tracetool/backend/instr_static.py | 3 +
scripts/tracetool/format/api_events_h.py | 56 ++++++++++++
12 files changed, 366 insertions(+)
create mode 100644 instrument/api-control.c
create mode 100644 instrument/qemu-instr/control-internal.h
create mode 100644 instrument/qemu-instr/control.h
create mode 100644 instrument/qemu-instr/visibility-internal.h
create mode 100644 scripts/tracetool/format/api_events_h.py
diff --git a/.gitignore b/.gitignore
index 2a0ea2f..59acb2a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@ libcacard/trace/generated-tracers.c
instrument/generated-tracers.h
instrument/generated-tracers.c
instrument/qemu-instr/events.h
+instrument/qemu-instr/events-list.h
*-timestamp
*-softmmu
*-darwin-user
diff --git a/Makefile b/Makefile
index 8280273..7916152 100644
--- a/Makefile
+++ b/Makefile
@@ -40,6 +40,7 @@ ifdef CONFIG_TRACE_INSTRUMENT_DYNAMIC
GENERATED_SOURCES += instrument/generated-tracers.c
endif
GENERATED_HEADERS += instrument/qemu-instr/events.h
+GENERATED_HEADERS += instrument/qemu-instr/events-list.h
GENERATED_HEADERS += trace/generated-events.h
GENERATED_SOURCES += trace/generated-events.c
diff --git a/configure b/configure
index 2be915c..5cc97b7 100755
--- a/configure
+++ b/configure
@@ -301,6 +301,7 @@ QEMU_CFLAGS="-fno-strict-aliasing $QEMU_CFLAGS"
QEMU_CFLAGS="-Wall -Wundef -Wwrite-strings -Wmissing-prototypes $QEMU_CFLAGS"
QEMU_CFLAGS="-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS"
QEMU_CFLAGS="-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE $QEMU_CFLAGS"
+QEMU_CFLAGS="-DBUILDING_QEMU $QEMU_CFLAGS"
QEMU_INCLUDES="-I. -I\$(SRC_PATH) -I\$(SRC_PATH)/include"
if test "$debug_info" = "yes"; then
CFLAGS="-g $CFLAGS"
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 3116520..1fcf77e 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -41,6 +41,15 @@ $(obj)/qemu-instr/events.h-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.m
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+$(obj)/qemu-instr/events-list.h: $(obj)/qemu-instr/events-list.h-timestamp
+$(obj)/qemu-instr/events-list.h-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.mak
+ $(call quiet-command,$(TRACETOOL) \
+ --format=api-events-h \
+ --backend=$(TRACE_INSTRUMENT_BACKEND) \
+ $(TRACETOOL_INSTR_STATIC) \
+ < $< > $@," GEN $(patsubst %-timestamp,%,$@)")
+ @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
+
######################################################################
# User code (static instrumentation)
@@ -71,3 +80,7 @@ target-obj-y += control.o
common-obj-$(CONFIG_SOFTMMU) += qmp.o
common-obj-$(CONFIG_SOFTMMU) += hmp.o
+
+target-obj-y += api-control.o
+
+QEMU_CFLAGS += -I$(BUILD_DIR)/instrument -I$(SRC_PATH)/instrument
diff --git a/instrument/api-control.c b/instrument/api-control.c
new file mode 100644
index 0000000..6193208
--- /dev/null
+++ b/instrument/api-control.c
@@ -0,0 +1,14 @@
+/*
+ * Interface for controlling the state of events.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "instrument/qemu-instr/control.h"
+
+#if defined(QI_TYPE_CONFIG_DYNAMIC)
+#include "instrument/qemu-instr/control-internal.h"
+#endif
diff --git a/instrument/qemu-instr/control-internal.h b/instrument/qemu-instr/control-internal.h
new file mode 100644
index 0000000..6e419e7
--- /dev/null
+++ b/instrument/qemu-instr/control-internal.h
@@ -0,0 +1,53 @@
+/*
+ * Interface for controlling the state of events.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QI__CONTROL_INTERNAL_H
+#define QI__CONTROL_INTERNAL_H
+
+#include "trace/control.h"
+
+
+QI_IDEF QIEvent* qi_ctrl_event_id(QIEventID id)
+{
+ return (QIEvent*)trace_event_id(id);
+}
+
+QI_IDEF QIEvent* qi_ctrl_event_name(const char *name)
+{
+ return (QIEvent*)trace_event_name(name);
+}
+
+QI_IDEF QIEvent* qi_ctrl_event_pattern(const char *pat, QIEvent *ev)
+{
+ return (QIEvent*)trace_event_pattern(pat, (TraceEvent*)ev);
+}
+
+QI_IDEF bool qi_ctrl_event_is_pattern(const char *str)
+{
+ return trace_event_is_pattern(str);
+}
+
+QI_IDEF QIEventID qi_ctrl_event_count(void)
+{
+ return (QIEventID)trace_event_count();
+}
+
+
+
+QI_IDEF QIEventID qi_ctrl_event_get_id(QIEvent *ev)
+{
+ return (QIEventID)trace_event_get_id((TraceEvent*)ev);
+}
+
+QI_IDEF const char * qi_ctrl_event_get_name(QIEvent *ev)
+{
+ return trace_event_get_name((TraceEvent*)ev);
+}
+
+#endif /* QI__CONTROL_INTERNAL_H */
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
new file mode 100644
index 0000000..8687b1d
--- /dev/null
+++ b/instrument/qemu-instr/control.h
@@ -0,0 +1,124 @@
+/*
+ * Interface for controlling the state of events.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QI__CONTROL_H
+#define QI__CONTROL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
+#include <qemu-instr/config.h>
+#include <qemu-instr/visibility-internal.h>
+#include <qemu-instr/events-list.h>
+
+
+/**
+ * SECTION:control
+ * @section_id: qi-control
+ * @title: QEMU instrumentation event control interface
+ */
+
+/**
+ * QIEvent:
+ *
+ * Opaque structure defining an instrumentation event.
+ */
+struct QIEvent;
+typedef struct QIEvent QIEvent;
+
+/**
+ * QIEventID:
+ *
+ * Unique instrumentation event identifier.
+ *
+ * These are named as 'QI_EVENT_${EVENT}'.
+ *
+ * See also: qemu-instr/events-list.h
+ */
+
+/**
+ * qi_ctrl_event_id:
+ * @id: Event identifier.
+ *
+ * Get an event by its identifier.
+ *
+ * This routine has a constant cost, as opposed to qi_ctrl_event_name() and
+ * qi_ctrl_event_pattern().
+ *
+ * Pre-conditions: @id is valid.
+ *
+ * Returns: Pointer to selected #QIEvent.
+ *
+ */
+QI_IDECL QIEvent* qi_ctrl_event_id(QIEventID id);
+
+/**
+ * qi_ctrl_event_name:
+ * @id: Event name.
+ *
+ * Search an event by its name.
+ *
+ * Returns: Pointer to #QIEvent or #NULL if not found.
+ */
+QI_IDECL QIEvent* qi_ctrl_event_name(const char *name);
+
+/**
+ * qi_ctrl_event_pattern:
+ * @pat: Event name pattern.
+ * @ev: Event to start searching from (not included).
+ *
+ * Iteratively get all events with a given name pattern.
+ *
+ * Returns: pointer to #TraceEvent or #NULL if not found.
+ */
+QI_IDECL QIEvent* qi_ctrl_event_pattern(const char *pat, QIEvent *ev);
+
+/**
+ * qi_ctrl_event_is_pattern:
+ *
+ * Whether the given string is an event name pattern.
+ */
+QI_IDECL bool qi_ctrl_event_is_pattern(const char *str);
+
+/**
+ * qi_ctrl_event_count:
+ *
+ * Return the number of events.
+ */
+QI_IDECL QIEventID qi_ctrl_event_count(void);
+
+
+
+/**
+ * qi_ctrl_event_get_id:
+ *
+ * Get the identifier of an event.
+ */
+QI_IDECL QIEventID qi_ctrl_event_get_id(QIEvent *ev);
+
+/**
+ * qi_ctrl_event_get_name:
+ *
+ * Get the name of an event.
+ */
+QI_IDECL const char * qi_ctrl_event_get_name(QIEvent *ev);
+
+
+#if !defined(QI_TYPE_CONFIG_DYNAMIC)
+#include "instrument/qemu-instr/control-internal.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QI__CONTROL_H */
diff --git a/instrument/qemu-instr/visibility-internal.h b/instrument/qemu-instr/visibility-internal.h
new file mode 100644
index 0000000..7726af7
--- /dev/null
+++ b/instrument/qemu-instr/visibility-internal.h
@@ -0,0 +1,94 @@
+/*
+ * Macros for symbol visibility.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory of QEMU.
+ */
+
+#ifndef QI__VISIBILITY_INTERNAL_H
+#define QI__VISIBILITY_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <qemu-instr/config.h>
+
+
+/**
+ * SECTION:visibility
+ * @section_id: qi-visibility
+ * @title: Symbol visibility
+ *
+ * This code is taken from http://gcc.gnu.org/wiki/Visibility.
+ */
+
+/**
+ * QI_VPUBLIC:
+ *
+ * Make an element public to third-party code.
+ */
+
+/**
+ * QI_VLOCAL:
+ *
+ * Make an element not visible to third-party code.
+ */
+
+#if defined _WIN32 || defined __CYGWIN__
+ #ifdef BUILDING_QEMU
+ #ifdef __GNUC__
+ #define QI_VPUBLIC __attribute__ ((dllexport))
+ #else
+ #define QI_VPUBLIC __declspec(dllexport)
+ #endif
+ #else
+ #ifdef __GNUC__
+ #define QI_VPUBLIC __attribute__ ((dllimport))
+ #else
+ #define QI_VPUBLIC __declspec(dllimport)
+ #endif
+ #endif
+ #define QI_VLOCAL
+#else
+ #if __GNUC__ >= 4
+ #define QI_VPUBLIC __attribute__ ((visibility ("default")))
+ #define QI_VLOCAL __attribute__ ((visibility ("hidden")))
+ #else
+ #define QI_VPUBLIC
+ #define QI_VLOCAL
+ #endif
+#endif
+
+/**
+ * QI_IDECL:
+ *
+ * Instrumentation-type dependant declaration attribute for inlined routines.
+ */
+
+#if defined(QI_TYPE_CONFIG_DYNAMIC)
+#define QI_IDECL QI_VPUBLIC
+#else
+#define QI_IDECL static
+#endif
+
+/**
+ * QI_IDEF:
+ *
+ * Instrumentation-type dependant definition attribute for inlined routines.
+ */
+
+#if defined(QI_TYPE_CONFIG_DYNAMIC)
+#define QI_IDEF
+#else
+#define QI_IDEF static inline
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QI__VISIBILITY_INTERNAL_H */
diff --git a/scripts/tracetool/backend/instr_dynamic.py b/scripts/tracetool/backend/instr_dynamic.py
index 12d0503..013893a 100644
--- a/scripts/tracetool/backend/instr_dynamic.py
+++ b/scripts/tracetool/backend/instr_dynamic.py
@@ -88,3 +88,6 @@ def api_c(events):
args = e.args,
argnames = ", ".join(e.args.names()),
)
+
+def api_events_h(events):
+ pass
diff --git a/scripts/tracetool/backend/instr_none.py b/scripts/tracetool/backend/instr_none.py
index a1327c0..2c2fe68 100644
--- a/scripts/tracetool/backend/instr_none.py
+++ b/scripts/tracetool/backend/instr_none.py
@@ -39,3 +39,6 @@ def api_h(events):
qemu_backend = e.api(e.QEMU_TRACE_BACKEND),
argnames = ", ".join(e.args.names()),
)
+
+def api_events_h(events):
+ pass
diff --git a/scripts/tracetool/backend/instr_static.py b/scripts/tracetool/backend/instr_static.py
index ecebbda..df99656 100644
--- a/scripts/tracetool/backend/instr_static.py
+++ b/scripts/tracetool/backend/instr_static.py
@@ -77,3 +77,6 @@ def api_h(events):
argnames = ", ".join(e.args.names()),
upper_name = e.name.upper(),
)
+
+def api_events_h(events):
+ pass
diff --git a/scripts/tracetool/format/api_events_h.py b/scripts/tracetool/format/api_events_h.py
new file mode 100644
index 0000000..95a4e93
--- /dev/null
+++ b/scripts/tracetool/format/api_events_h.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .h with event description for trace instrumentation clients.
+"""
+
+__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "stefanha@linux.vnet.ibm.com"
+
+
+from tracetool import out
+
+
+def begin(events):
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ '#ifndef QI__EVENTS_LIST_H',
+ '#define QI__EVENTS_LIST_H',
+ '',
+ '#ifdef __cplusplus',
+ 'extern "C" {',
+ '#endif',
+ '',
+ )
+
+ # event identifiers
+ out('typedef enum {')
+
+ for e in events:
+ out(' QI_EVENT_%s,' % e.name.upper())
+
+ out(' QI_EVENT_COUNT',
+ '} QIEventID;',
+ '',
+ )
+
+ # static state
+ for e in events:
+ if 'disable' in e.properties:
+ enabled = 0
+ else:
+ enabled = 1
+ out('#define QI_EVENT_%s_ENABLED %d' % (e.name.upper(), enabled))
+
+ out('#ifdef __cplusplus',
+ '}',
+ '#endif',
+ '',
+ '#endif /* QI__EVENTS_LIST_H */',
+ '',
+ )
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 20/24] instrument: Add client-side API to control tracing state of events
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (18 preceding siblings ...)
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 19/24] instrument: Add client-side API to enumerate events Lluís Vilanova
@ 2013-04-21 19:13 ` Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 21/24] instrument: Add client-side API to control event instrumentation Lluís Vilanova
` (4 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:13 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
instrument/Makefile.objs | 1
instrument/api-trace.c | 14 +++++
instrument/qemu-instr/trace-internal.h | 32 +++++++++++
instrument/qemu-instr/trace.h | 91 ++++++++++++++++++++++++++++++++
4 files changed, 138 insertions(+)
create mode 100644 instrument/api-trace.c
create mode 100644 instrument/qemu-instr/trace-internal.h
create mode 100644 instrument/qemu-instr/trace.h
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 1fcf77e..cd55f6f 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -82,5 +82,6 @@ common-obj-$(CONFIG_SOFTMMU) += qmp.o
common-obj-$(CONFIG_SOFTMMU) += hmp.o
target-obj-y += api-control.o
+target-obj-y += api-trace.o
QEMU_CFLAGS += -I$(BUILD_DIR)/instrument -I$(SRC_PATH)/instrument
diff --git a/instrument/api-trace.c b/instrument/api-trace.c
new file mode 100644
index 0000000..97e135a
--- /dev/null
+++ b/instrument/api-trace.c
@@ -0,0 +1,14 @@
+/*
+ * Interface for controlling the tracing state of events.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "instrument/qemu-instr/trace.h"
+
+#if defined(QI_TYPE_CONFIG_DYNAMIC)
+#include "instrument/qemu-instr/trace-internal.h"
+#endif
diff --git a/instrument/qemu-instr/trace-internal.h b/instrument/qemu-instr/trace-internal.h
new file mode 100644
index 0000000..2d6eec4
--- /dev/null
+++ b/instrument/qemu-instr/trace-internal.h
@@ -0,0 +1,32 @@
+/*
+ * Interface for controlling the tracing state of events.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QI__TRACE_INTERNAL_H
+#define QI__TRACE_INTERNAL_H
+
+#include "trace/control.h"
+
+
+QI_IDEF bool qi_trace_event_get_state_static(QIEvent *ev)
+{
+ return trace_event_get_state_static((TraceEvent*)ev);
+}
+
+QI_IDEF bool qi_trace_event_get_state_dynamic(QIEvent *ev)
+{
+ return trace_event_get_state_dynamic((TraceEvent*)ev);
+}
+
+QI_IDEF void qi_trace_event_set_state_dynamic(QIEvent *ev, bool state)
+{
+ assert(qi_trace_event_get_state_static(ev));
+ return trace_event_set_state_dynamic((TraceEvent*)ev, state);
+}
+
+#endif /* QI__TRACE_INTERNAL_H */
diff --git a/instrument/qemu-instr/trace.h b/instrument/qemu-instr/trace.h
new file mode 100644
index 0000000..fd9172a
--- /dev/null
+++ b/instrument/qemu-instr/trace.h
@@ -0,0 +1,91 @@
+/*
+ * Interface for controlling the tracing state of events.
+ *
+ * Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef QI__TRACE_H
+#define QI__TRACE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+
+#include <qemu-instr/control.h>
+
+
+/**
+ * SECTION: trace
+ * @section_id: qi-trace
+ * @title: QEMU tracing event control interface
+ */
+
+/**
+ * qi_trace_event_get_state:
+ * @id: Event identifier.
+ *
+ * Get the tracing state of an event (both static and dynamic).
+ *
+ * If the event has the disabled property, the check will have no performance
+ * impact.
+ *
+ * As a down side, you must always use an immediate #QIEventID value.
+ */
+#define qi_trace_event_get_state(id) \
+ ((id ##_ENABLED) && qi_trace_event_get_state_dynamic(qi_ctrl_event_id(id)))
+
+/**
+ * qi_trace_event_get_state_static:
+ * @id: Event identifier.
+ *
+ * Get the static tracing state of an event.
+ *
+ * Use the define 'QI_EVENT_${EVENT}_ENABLED' for compile-time checks (it will
+ * be set to 1 or 0 according to the presence of the disabled property).
+ */
+QI_IDECL bool qi_trace_event_get_state_static(QIEvent *ev);
+
+/**
+ * qi_trace_event_get_state_dynamic:
+ *
+ * Get the dynamic tracing state of an event.
+ */
+QI_IDECL bool qi_trace_event_get_state_dynamic(QIEvent *ev);
+
+/**
+ * qi_trace_event_set_state:
+ *
+ * Set the tracing state of an event.
+ */
+#define qi_trace_event_set_state(id, state) \
+ do { \
+ if ((id ##_ENABLED)) { \
+ QIEvent *_e = qi_ctrl_event_id(id); \
+ qi_trace_event_set_state_dynamic(_e, state); \
+ } \
+ } while (0)
+
+/**
+ * qi_trace_event_set_state_dynamic:
+ *
+ * Set the dynamic tracing state of an event.
+ *
+ * Pre-condition: qi_trace_event_get_state_static(ev) == true
+ */
+QI_IDECL void qi_trace_event_set_state_dynamic(QIEvent *ev, bool state);
+
+
+#if !defined(QI_TYPE_CONFIG_DYNAMIC)
+#include "instrument/qemu-instr/trace-internal.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QI__TRACE_H */
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 21/24] instrument: Add client-side API to control event instrumentation
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (19 preceding siblings ...)
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 20/24] instrument: Add client-side API to control tracing state of events Lluís Vilanova
@ 2013-04-21 19:13 ` Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 22/24] build: Fix installation of target-dependant files Lluís Vilanova
` (3 subsequent siblings)
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:13 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
instrument/qemu-instr/control-internal.h | 16 ++++++
instrument/qemu-instr/control.h | 75 ++++++++++++++++++++++++++++++
2 files changed, 91 insertions(+)
diff --git a/instrument/qemu-instr/control-internal.h b/instrument/qemu-instr/control-internal.h
index 6e419e7..953f2d1 100644
--- a/instrument/qemu-instr/control-internal.h
+++ b/instrument/qemu-instr/control-internal.h
@@ -11,6 +11,7 @@
#define QI__CONTROL_INTERNAL_H
#include "trace/control.h"
+#include "instrument/control.h"
QI_IDEF QIEvent* qi_ctrl_event_id(QIEventID id)
@@ -38,6 +39,16 @@ QI_IDEF QIEventID qi_ctrl_event_count(void)
return (QIEventID)trace_event_count();
}
+QI_IDEF QIType qi_ctrl_type(void)
+{
+ return instr_type();
+}
+
+QI_IDEF bool qi_ctrl_event_is_available(QIEvent *ev)
+{
+ return instr_event_available((TraceEvent*)ev);
+}
+
QI_IDEF QIEventID qi_ctrl_event_get_id(QIEvent *ev)
@@ -50,4 +61,9 @@ QI_IDEF const char * qi_ctrl_event_get_name(QIEvent *ev)
return trace_event_get_name((TraceEvent*)ev);
}
+QI_IDEF bool qi_ctrl_event_set(QIEvent *ev, void *cb)
+{
+ return instr_event_set((TraceEvent*)ev, cb);
+}
+
#endif /* QI__CONTROL_INTERNAL_H */
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
index 8687b1d..037897b 100644
--- a/instrument/qemu-instr/control.h
+++ b/instrument/qemu-instr/control.h
@@ -96,6 +96,27 @@ QI_IDECL bool qi_ctrl_event_is_pattern(const char *str);
*/
QI_IDECL QIEventID qi_ctrl_event_count(void);
+/**
+ * QIType:
+ * @QI_TYPE_NONE: No instrumentation support.
+ * @QI_TYPE_STATIC: Static instrumentation support.
+ * @QI_TYPE_DYNAMIC: Dynamic instrumentation support.
+ *
+ * Instrumentation type supported by the system.
+ */
+typedef enum {
+ QI_TYPE_NONE,
+ QI_TYPE_STATIC,
+ QI_TYPE_DYNAMIC,
+} QIType;
+
+/**
+ * qi_ctrl_type:
+ *
+ * Returns: Instrumentation type supported by the system.
+ */
+QI_IDECL QIType qi_ctrl_type(void);
+
/**
@@ -112,6 +133,60 @@ QI_IDECL QIEventID qi_ctrl_event_get_id(QIEvent *ev);
*/
QI_IDECL const char * qi_ctrl_event_get_name(QIEvent *ev);
+/**
+ * qi_ctrl_event_is_available:
+ *
+ * Returns: Whether the given event has the 'instrument' property.
+ */
+QI_IDECL bool qi_ctrl_event_is_available(QIEvent *ev);
+
+
+/**
+ * QI_CTRL_INSTR_NOP:
+ *
+ * Set instrumentation callback to no-operation.
+ * (qi_event_${name}_nop).
+ */
+#define QI_CTRL_INSTR_NOP ((void*)NULL)
+
+/**
+ * QI_CTRL_INSTR_NEXT:
+ *
+ * Set instrumentation callback to the "next logical step"
+ * (qi_event_${name}_trace).
+ */
+#define QI_CTRL_INSTR_NEXT ((void*)1)
+
+/**
+ * QI_CTRL_INSTR_AUTO:
+ *
+ * Automatically set callback to proper routine.
+ *
+ * Looks for a symbol name in the instrumentation library matching the event
+ * name (qi_event_${name}).
+ */
+#define QI_CTRL_INSTR_AUTO ((void*)2)
+
+/**
+ * qi_ctrl_event_set:
+ * @ev: Event descriptor.
+ * @cb: Pointer to instrumentation callback.
+ *
+ * Set the instrumentation callback for the given event.
+ *
+ * @cb can also be set to any of the QI_CTRL_INSTR_* special values.
+ *
+ * #false indicates that the instrumentation library does not export the
+ * appropriate symbol for the instrumentation routine.
+ *
+ * Pre-condition: qi_ctrl_dynamic() == true
+ * Pre-condition: qi_ctrl_event_is_available(ev) == true
+ *
+ * Returns: Whether the callback could be set (if @cb was QI_CTRL_INSTR_AUTO,
+ * otherwise always #true).
+ */
+QI_IDECL bool qi_ctrl_event_set(QIEvent *ev, void *cb);
+
#if !defined(QI_TYPE_CONFIG_DYNAMIC)
#include "instrument/qemu-instr/control-internal.h"
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 22/24] build: Fix installation of target-dependant files
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (20 preceding siblings ...)
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 21/24] instrument: Add client-side API to control event instrumentation Lluís Vilanova
@ 2013-04-21 19:13 ` Lluís Vilanova
2013-04-26 15:24 ` Paolo Bonzini
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 23/24] instrument: Install headers for dynamic instrumentation clients Lluís Vilanova
` (2 subsequent siblings)
24 siblings, 1 reply; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:13 UTC (permalink / raw)
To: qemu-devel
Pass all the relevant sub-directory make variables.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Cc: Anthony Liguori <aliguori@us.ibm.com>
Cc: Paul Brook <paul@codesourcery.com>
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 7916152..ccf6760 100644
--- a/Makefile
+++ b/Makefile
@@ -346,7 +346,7 @@ endif
$(INSTALL_DATA) $(SRC_PATH)/pc-bios/keymaps/$$x "$(DESTDIR)$(qemu_datadir)/keymaps"; \
done
for d in $(TARGET_DIRS); do \
- $(MAKE) -C $$d $@ || exit 1 ; \
+ $(MAKE) $(SUBDIR_MAKEFLAGS) TARGET_DIR=$$d/ -C $$d $@ || exit 1 ; \
done
# various test targets
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 23/24] instrument: Install headers for dynamic instrumentation clients
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (21 preceding siblings ...)
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 22/24] build: Fix installation of target-dependant files Lluís Vilanova
@ 2013-04-21 19:13 ` Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 24/24] trace: Do not use the word 'new' in event arguments Lluís Vilanova
2013-04-24 11:17 ` [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Stefan Hajnoczi
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:13 UTC (permalink / raw)
To: qemu-devel
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index ccf6760..3fc5fb6 100644
--- a/Makefile
+++ b/Makefile
@@ -324,7 +324,29 @@ install-confdir:
install-sysconfig: install-datadir install-confdir
$(INSTALL_DATA) $(SRC_PATH)/sysconfigs/target/target-x86_64.conf "$(DESTDIR)$(qemu_confdir)"
-install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig install-datadir
+install_instrument_find=$(shell find $(1)/instrument/qemu-instr -type f -name \*.h)
+
+install-instrument: INSTALL_FILES =$(call install_instrument_find,$(SRC_PATH))
+install-instrument: INSTALL_FILES+=$(call install_instrument_find,$(BUILD_DIR))
+install-instrument: INSTALL_DIRS:=$(dir $(INSTALL_FILES))
+install-instrument: INSTALL_DIRS:=$(patsubst $(SRC_PATH)/instrument/%,$(DESTDIR)$(includedir)/%,$(INSTALL_DIRS))
+install-instrument: INSTALL_DIRS:=$(patsubst $(BUILD_DIR)/instrument/%,$(DESTDIR)$(includedir)/%,$(INSTALL_DIRS))
+install-instrument: INSTALL_DIRS:=$(sort $(INSTALL_DIRS))
+install-instrument:
+ @for d in $(INSTALL_DIRS); do \
+ echo "$(INSTALL_DIR) \"$$d\""; \
+ $(INSTALL_DIR) "$$d"; \
+ done
+ @for f in $(INSTALL_FILES); do \
+ echo "$(INSTALL_DATA) \"$$f\" \"$(DESTDIR)$(includedir)/qemu-instr/$${f##*qemu-instr/}\""; \
+ $(INSTALL_DATA) "$$f" "$(DESTDIR)$(includedir)/qemu-instr/$${f##*qemu-instr/}"; \
+ done
+
+ifdef CONFIG_TRACE_INSTRUMENT_DYNAMIC
+INSTALL_INSTRUMENT=install-instrument
+endif
+
+install: all $(if $(BUILD_DOCS),install-doc) install-sysconfig install-datadir $(INSTALL_INSTRUMENT)
$(INSTALL_DIR) "$(DESTDIR)$(bindir)"
ifneq ($(TOOLS),)
$(INSTALL_PROG) $(STRIP_OPT) $(TOOLS) "$(DESTDIR)$(bindir)"
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [Qemu-devel] [PATCH v3 24/24] trace: Do not use the word 'new' in event arguments
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (22 preceding siblings ...)
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 23/24] instrument: Install headers for dynamic instrumentation clients Lluís Vilanova
@ 2013-04-21 19:13 ` Lluís Vilanova
2013-04-24 11:17 ` [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Stefan Hajnoczi
24 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-21 19:13 UTC (permalink / raw)
To: qemu-devel
This lets instrumentation clients in C++ use the auto-generated headers.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/tracetool/__init__.py | 16 +++++++++++++++-
trace-events | 8 ++++----
2 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 7624982..851be4d 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -40,6 +40,14 @@ def out(*lines, **kwargs):
sys.stdout.writelines("\n".join(lines) + "\n")
+FORBIDDEN = [ "new" ]
+
+class ForbiddenArgumentError (Exception):
+ def __init__ (self, name):
+ self.name = name
+ def __str__ (self):
+ return "Cannot use forbidden argument name: %s" % self.name
+
class Arguments:
"""Event arguments description."""
@@ -74,6 +82,9 @@ class Arguments:
else:
arg_type, identifier = arg.rsplit(None, 1)
+ if identifier in FORBIDDEN:
+ raise ForbiddenArgumentError(identifier)
+
res.append((arg_type, identifier))
return Arguments(res)
@@ -165,7 +176,10 @@ class Event(object):
name = groups["name"]
props = groups["props"].split()
fmt = groups["fmt"]
- args = Arguments.build(groups["args"])
+ try:
+ args = Arguments.build(groups["args"])
+ except ForbiddenArgumentError as e:
+ error("Error: event '%s' uses forbidden argument name '%s'" % (name, e.name))
return Event(name, props, fmt, args)
diff --git a/trace-events b/trace-events
index 412f7e4..eb7dd93 100644
--- a/trace-events
+++ b/trace-events
@@ -187,7 +187,7 @@ hd_geometry_guess(void *bs, uint32_t cyls, uint32_t heads, uint32_t secs, int tr
# hw/jazz-led.c
jazz_led_read(uint64_t addr, uint8_t val) "read addr=0x%"PRIx64": 0x%x"
-jazz_led_write(uint64_t addr, uint8_t new) "write addr=0x%"PRIx64": 0x%x"
+jazz_led_write(uint64_t addr, uint8_t new_) "write addr=0x%"PRIx64": 0x%x"
# hw/lance.c
lance_mem_readw(uint64_t addr, uint32_t ret) "addr=%"PRIx64"val=0x%04x"
@@ -285,10 +285,10 @@ usb_port_release(int bus, const char *port) "bus %d, port %s"
usb_ehci_reset(void) "=== RESET ==="
usb_ehci_opreg_read(uint32_t addr, const char *str, uint32_t val) "rd mmio %04x [%s] = %x"
usb_ehci_opreg_write(uint32_t addr, const char *str, uint32_t val) "wr mmio %04x [%s] = %x"
-usb_ehci_opreg_change(uint32_t addr, const char *str, uint32_t new, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
+usb_ehci_opreg_change(uint32_t addr, const char *str, uint32_t new_, uint32_t old) "ch mmio %04x [%s] = %x (old: %x)"
usb_ehci_portsc_read(uint32_t addr, uint32_t port, uint32_t val) "rd mmio %04x [port %d] = %x"
usb_ehci_portsc_write(uint32_t addr, uint32_t port, uint32_t val) "wr mmio %04x [port %d] = %x"
-usb_ehci_portsc_change(uint32_t addr, uint32_t port, uint32_t new, uint32_t old) "ch mmio %04x [port %d] = %x (old: %x)"
+usb_ehci_portsc_change(uint32_t addr, uint32_t port, uint32_t new_, uint32_t old) "ch mmio %04x [port %d] = %x (old: %x)"
usb_ehci_usbsts(const char *sts, int state) "usbsts %s %d"
usb_ehci_state(const char *schedule, const char *state) "%s schedule %s"
usb_ehci_qh_ptrs(void *q, uint32_t addr, uint32_t nxt, uint32_t c_qtd, uint32_t n_qtd, uint32_t a_qtd) "q %p - QH @ %08x: next %08x qtds %08x,%08x,%08x"
@@ -530,7 +530,7 @@ qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s
# hw/g364fb.c
g364fb_read(uint64_t addr, uint32_t val) "read addr=0x%"PRIx64": 0x%x"
-g364fb_write(uint64_t addr, uint32_t new) "write addr=0x%"PRIx64": 0x%x"
+g364fb_write(uint64_t addr, uint32_t val) "write addr=0x%"PRIx64": 0x%x"
# hw/grlib_gptimer.c
grlib_gptimer_enable(int id, uint32_t count) "timer:%d set count 0x%x and run"
^ permalink raw reply related [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
` (23 preceding siblings ...)
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 24/24] trace: Do not use the word 'new' in event arguments Lluís Vilanova
@ 2013-04-24 11:17 ` Stefan Hajnoczi
2013-04-24 12:17 ` Lluís Vilanova
24 siblings, 1 reply; 43+ messages in thread
From: Stefan Hajnoczi @ 2013-04-24 11:17 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: qemu-devel
On Sun, Apr 21, 2013 at 09:11:30PM +0200, Lluís Vilanova wrote:
> TODO: Operations 'instr_load' and 'instr_unload' are not thread safe.
> (qemu_cpu_kick?)
>
> TODO: Do cmdline actions have to be implemented on top of QMP routines?
>
> TODO: HMP and QMP interfaces only accept one argument to "instr-load".
>
> TODO: Replace programmatic 'InstrLoadError' in favour of QAPI's 'InstrLoadCode'?
> (harder to find using code navigation tools, as it's auto-generated; but
> provides a single point to manage the enumeration values, which is less
> error-prone)
>
>
> The whole set of patch series is available at:
> https://projects.gso.ac.upc.edu/projects/qemu-dbi
>
> Adds the "instrument" event property to declare which tracing events in QEMU
> must be instrumentable. Still, in case the user only wants to wrap around the
> tracing events, the original tracing implementation is accessible through the
> appropriate routines.
>
> The instrumentation can be performed either through a dynamically-loaded library
> or through user-provided code that is compiled into QEMU itself (useful when
> instrumenting high-frequency events, as the fast-path of the instrumentation can
> be inlined into QEMU).
>
> As a side-effect this series adds an API for the instrumentation code to have
> some basic interaction with QEMU.
>
> See the documentation added in the first patch for more information.
>
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
If I understand correctly this series allows trace events to be exported
as a shared library API. It can be used with instrumentation libraries
(shared objects), which avoids rebuilding QEMU for each instrumentation
set.
I'm skeptical of the effort required to do this (and maintain it) when
it's easy to keep several git branches - one for each instrumentation
set - and rebuild.
Trace events are not an API. They are not stable. Therefore these
dynamic instrumentation libraries would be broken when QEMU changes.
Maybe I don't understand the application well enough to see the benefit?
Stefan
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines
2013-04-24 11:17 ` [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Stefan Hajnoczi
@ 2013-04-24 12:17 ` Lluís Vilanova
2013-04-25 12:39 ` Stefan Hajnoczi
0 siblings, 1 reply; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-24 12:17 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: qemu-devel
Stefan Hajnoczi writes:
> On Sun, Apr 21, 2013 at 09:11:30PM +0200, Lluís Vilanova wrote:
>> TODO: Operations 'instr_load' and 'instr_unload' are not thread safe.
>> (qemu_cpu_kick?)
>>
>> TODO: Do cmdline actions have to be implemented on top of QMP routines?
>>
>> TODO: HMP and QMP interfaces only accept one argument to "instr-load".
>>
>> TODO: Replace programmatic 'InstrLoadError' in favour of QAPI's 'InstrLoadCode'?
>> (harder to find using code navigation tools, as it's auto-generated; but
>> provides a single point to manage the enumeration values, which is less
>> error-prone)
>>
>>
>> The whole set of patch series is available at:
>> https://projects.gso.ac.upc.edu/projects/qemu-dbi
>>
>> Adds the "instrument" event property to declare which tracing events in QEMU
>> must be instrumentable. Still, in case the user only wants to wrap around the
>> tracing events, the original tracing implementation is accessible through the
>> appropriate routines.
>>
>> The instrumentation can be performed either through a dynamically-loaded library
>> or through user-provided code that is compiled into QEMU itself (useful when
>> instrumenting high-frequency events, as the fast-path of the instrumentation can
>> be inlined into QEMU).
>>
>> As a side-effect this series adds an API for the instrumentation code to have
>> some basic interaction with QEMU.
>>
>> See the documentation added in the first patch for more information.
>>
>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
>> ---
> If I understand correctly this series allows trace events to be exported
> as a shared library API. It can be used with instrumentation libraries
> (shared objects), which avoids rebuilding QEMU for each instrumentation
> set.
> I'm skeptical of the effort required to do this (and maintain it) when
> it's easy to keep several git branches - one for each instrumentation
> set - and rebuild.
> Trace events are not an API. They are not stable. Therefore these
> dynamic instrumentation libraries would be broken when QEMU changes.
> Maybe I don't understand the application well enough to see the benefit?
True, changing QEMU's tracing events will break the instrumentation libraries,
and the user should be completely aware of that, given that the library is
actually instrumenting specific tracing events (not just some well-established
API). You can think of this as yet another tracing backend, with the ability to
interact with QEMU.
The actually interesting part is in the following series (which are also
publicly available on the url of the cover), which adds some generic tracing
events that should not change between versions, and can thus be safely assumed.
Such events are related to the guest code, including (but not limited to) guest
memory accesses or instruction execution. As we discussed in some very old try
at this, what all of this provides is the ability to instrument guest code for
all architectures supported by QEMU.
In fact, the ability to instrument all tracing events could be seen as just a
side-effect of the implementation; but one that can come in handy in certain
cases when developing ad-hoc trace analyses.
Does this make more sense now?
Lluis
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines
2013-04-24 12:17 ` Lluís Vilanova
@ 2013-04-25 12:39 ` Stefan Hajnoczi
2013-04-26 12:15 ` Lluís Vilanova
0 siblings, 1 reply; 43+ messages in thread
From: Stefan Hajnoczi @ 2013-04-25 12:39 UTC (permalink / raw)
To: qemu-devel
On Wed, Apr 24, 2013 at 02:17:22PM +0200, Lluís Vilanova wrote:
> Stefan Hajnoczi writes:
>
> > On Sun, Apr 21, 2013 at 09:11:30PM +0200, Lluís Vilanova wrote:
> >> TODO: Operations 'instr_load' and 'instr_unload' are not thread safe.
> >> (qemu_cpu_kick?)
> >>
> >> TODO: Do cmdline actions have to be implemented on top of QMP routines?
> >>
> >> TODO: HMP and QMP interfaces only accept one argument to "instr-load".
> >>
> >> TODO: Replace programmatic 'InstrLoadError' in favour of QAPI's 'InstrLoadCode'?
> >> (harder to find using code navigation tools, as it's auto-generated; but
> >> provides a single point to manage the enumeration values, which is less
> >> error-prone)
> >>
> >>
> >> The whole set of patch series is available at:
> >> https://projects.gso.ac.upc.edu/projects/qemu-dbi
> >>
> >> Adds the "instrument" event property to declare which tracing events in QEMU
> >> must be instrumentable. Still, in case the user only wants to wrap around the
> >> tracing events, the original tracing implementation is accessible through the
> >> appropriate routines.
> >>
> >> The instrumentation can be performed either through a dynamically-loaded library
> >> or through user-provided code that is compiled into QEMU itself (useful when
> >> instrumenting high-frequency events, as the fast-path of the instrumentation can
> >> be inlined into QEMU).
> >>
> >> As a side-effect this series adds an API for the instrumentation code to have
> >> some basic interaction with QEMU.
> >>
> >> See the documentation added in the first patch for more information.
> >>
> >> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> >> ---
>
> > If I understand correctly this series allows trace events to be exported
> > as a shared library API. It can be used with instrumentation libraries
> > (shared objects), which avoids rebuilding QEMU for each instrumentation
> > set.
>
> > I'm skeptical of the effort required to do this (and maintain it) when
> > it's easy to keep several git branches - one for each instrumentation
> > set - and rebuild.
>
> > Trace events are not an API. They are not stable. Therefore these
> > dynamic instrumentation libraries would be broken when QEMU changes.
>
> > Maybe I don't understand the application well enough to see the benefit?
>
> True, changing QEMU's tracing events will break the instrumentation libraries,
> and the user should be completely aware of that, given that the library is
> actually instrumenting specific tracing events (not just some well-established
> API). You can think of this as yet another tracing backend, with the ability to
> interact with QEMU.
>
> The actually interesting part is in the following series (which are also
> publicly available on the url of the cover), which adds some generic tracing
> events that should not change between versions, and can thus be safely assumed.
> Such events are related to the guest code, including (but not limited to) guest
> memory accesses or instruction execution. As we discussed in some very old try
> at this, what all of this provides is the ability to instrument guest code for
> all architectures supported by QEMU.
>
> In fact, the ability to instrument all tracing events could be seen as just a
> side-effect of the implementation; but one that can come in handy in certain
> cases when developing ad-hoc trace analyses.
>
> Does this make more sense now?
Thanks for explaining.
People doing this level of instrumentation probably need to do QEMU
hacking anyway for deep analysis, perhaps pausing and resuming the
guest, checking other guest RAM locations, grabbing device state, maybe
snapshotting the guest.
Is it worth building and maintain a stable API? It means that folks
working on TCG, for example, do not have the freedom to change/delete
trace events. They are now stuck maintaining trace event semantics no
matter how TCG will evolve in the future.
It would be nice to make TCG multi-threaded soon. How will
instrumentation libraries handle this? Existing ones probably won't,
they'll break unless QEMU restricts itself back to single-threaded mode.
Given that the group of users for this feature is so small while the
burden of supporting this is rather large, it seems like writing
instrumentation code straight in a QEMU source tree is the most powerful
and viable solution.
Basically I think putting a stable API in place here isn't going to fly.
In terms of the tracing subsystem I don't mind, but I think it's a
question for the larger QEMU community.
Stefan
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines
2013-04-25 12:39 ` Stefan Hajnoczi
@ 2013-04-26 12:15 ` Lluís Vilanova
2013-04-26 15:10 ` Stefan Hajnoczi
0 siblings, 1 reply; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-26 12:15 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: qemu-devel
Stefan Hajnoczi writes:
> On Wed, Apr 24, 2013 at 02:17:22PM +0200, Lluís Vilanova wrote:
> Thanks for explaining.
> People doing this level of instrumentation probably need to do QEMU
> hacking anyway for deep analysis, perhaps pausing and resuming the
> guest, checking other guest RAM locations, grabbing device state, maybe
> snapshotting the guest.
Some of these are already (or could easily be) available through QAPI, so
there's no need to "re-expose" them.
> Is it worth building and maintain a stable API? It means that folks
> working on TCG, for example, do not have the freedom to change/delete
> trace events. They are now stuck maintaining trace event semantics no
> matter how TCG will evolve in the future.
Well, the events added in future series (this one just adds the infrastructure)
are generic enough that TCG should just care about signalling, for example, when
an instruction/bbl starts. As this is in no way tied to the actual TCG
primitives, the internals are free to change.
What's probably less appropriate is exposing functions to generate TCG code to
the instrumentation libraries. This is what I added in one of my series, as it
allows the writing of highly-perfomant instrumentation routines, but I
understand it is undesirable (still, the library can just say "call this
function I wrote when the event happens", aka call a helper).
> It would be nice to make TCG multi-threaded soon. How will
> instrumentation libraries handle this? Existing ones probably won't,
> they'll break unless QEMU restricts itself back to single-threaded mode.
The only problem here is changing the dynamic callback of an event and flushing
the generated TCG code when a library is unloaded. That's the reason of one of
my TODO's at the top of this series, as I didn't dive enough into QEMU to handle
that.
> Given that the group of users for this feature is so small while the
> burden of supporting this is rather large, it seems like writing
> instrumentation code straight in a QEMU source tree is the most powerful
> and viable solution.
Well, the tracing event instrumentation support itself is quite generic and
should be maintainable, and can enormously simplify the task for others to use
it in the future.
>From my repository, the first three series (including this one) handle the
infrastructure, which is mostly based on providing tracetool backends.
The 4th one adds some very generic events (vbbl_{before,after},
vinst_{before,after}, vmem) that should have no ties to the TCG implementation.
The 5th one adds the backdoor we discussed long ago, which lets the guest code
interact with the instrumentation library, so that they can coordinate (AFAIR,
Blue said that could come in handy during tests, for example).
The next ones probably are more controversial, as they start adding new
interfaces available to the instrumentation libraries (as well as some extra
events).
> Basically I think putting a stable API in place here isn't going to fly.
> In terms of the tracing subsystem I don't mind, but I think it's a
> question for the larger QEMU community.
What are you referring to as an API? The tracing events and their signatures?
Lluis
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH v3 14/24] instrument: Add internal control interface
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 14/24] instrument: Add internal control interface Lluís Vilanova
@ 2013-04-26 14:08 ` Eric Blake
2013-04-26 15:11 ` Paolo Bonzini
1 sibling, 0 replies; 43+ messages in thread
From: Eric Blake @ 2013-04-26 14:08 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 2042 bytes --]
On 04/21/2013 01:12 PM, Lluís Vilanova wrote:
> This interface provides two sets of operations:
>
> * Loading/unloading a trace instrumentation library.
>
> * Controls the instrumentation callbacks of the tracing events.
>
> Note that in the case of static instrumentation, the library is not
> loaded/unloaded, but is still properly (de)initialized when QEMU starts and
> exits.
I don't know if the series in general will be accepted, but if so,
here's some interface things to think about:
> +++ b/instrument/qapi-schema.json
> @@ -0,0 +1,26 @@
> +# *-*- Mode: Python -*-*
> +#
> +# QAPI trace instrumentation control commands.
> +#
> +# Copyright (C) 2012-2013 Lluís Vilanova <vilanova@ac.upc.edu>
> +#
> +# This work is licensed under the terms of the GNU GPL, version 2 or later.
> +# See the COPYING file in the top-level directory.
> +
> +##
> +# @InstrType
> +#
> +# Instrumentation type supported by the system.
> +#
> +# @None: No instrumentation support.
> +#
> +# @Static: Static instrumentation support.
> +#
> +# @Dynamic: Dynamic instrumentation support.
Generally, QMP enums are lower case (s/None/none/, and so forth).
> +#
> +# Warning: Keep in sync with #QIType.
If we had the hypothetical tool that converted .json into end-user
documentation, this sort of comment does not belong in the end-user
document. Do we need to invent a syntax for development-only comments
within .json files for things that are useful during qemu development?
Or is it just better to move the comment to instead be in the C file
that declares the enum, reminding any developer that modifies the enum
to also modify the QMP type that reflects it? (We went with the latter
approach in the recent query-command-line-options, putting the reminder
comment to keep QMP and C in sync only in the C file.)
> +#
> +# Since: 1.5
This missed 1.5; it will need to be 1.6 now.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 621 bytes --]
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines
2013-04-26 12:15 ` Lluís Vilanova
@ 2013-04-26 15:10 ` Stefan Hajnoczi
2013-04-28 19:25 ` Lluís Vilanova
0 siblings, 1 reply; 43+ messages in thread
From: Stefan Hajnoczi @ 2013-04-26 15:10 UTC (permalink / raw)
To: qemu-devel
On Fri, Apr 26, 2013 at 02:15:46PM +0200, Lluís Vilanova wrote:
> Stefan Hajnoczi writes:
>
> > On Wed, Apr 24, 2013 at 02:17:22PM +0200, Lluís Vilanova wrote:
> > Given that the group of users for this feature is so small while the
> > burden of supporting this is rather large, it seems like writing
> > instrumentation code straight in a QEMU source tree is the most powerful
> > and viable solution.
>
> Well, the tracing event instrumentation support itself is quite generic and
> should be maintainable, and can enormously simplify the task for others to use
> it in the future.
>
> From my repository, the first three series (including this one) handle the
> infrastructure, which is mostly based on providing tracetool backends.
>
> The 4th one adds some very generic events (vbbl_{before,after},
> vinst_{before,after}, vmem) that should have no ties to the TCG implementation.
They would be affected by things like real TCG vcpu threads (parallel
translation and execution) because now trace events will be invoked
simultaneously from multiple threads. Or heterogenous cores in QEMU
(ARM + DSP) where previously you could assume there is one target
architecture.
> The 5th one adds the backdoor we discussed long ago, which lets the guest code
> interact with the instrumentation library, so that they can coordinate (AFAIR,
> Blue said that could come in handy during tests, for example).
>
> The next ones probably are more controversial, as they start adding new
> interfaces available to the instrumentation libraries (as well as some extra
> events).
I don't think this effort is maintainable.
The API would be great if QEMU was heavily focussed on instrumentation
and simulation research. It allows interesting analysis without diving
into the internals of QEMU.
The problem is it touches everything in QEMU because you should be able
to instrument everything. Who is going to maintain an API of this
scope?
The QEMU community has two large groups: TCG for emulation and KVM for
virtualization. The API doesn't offer them anything so they will not
keep it in mind when making changes.
This is why I think it makes more sense to focus on specific tools that
don't try to introduce stable APIs. i.e. a tool for instruction tracing
in TCG.
Advanced users will have to modify the QEMU source.
> > Basically I think putting a stable API in place here isn't going to fly.
> > In terms of the tracing subsystem I don't mind, but I think it's a
> > question for the larger QEMU community.
>
> What are you referring to as an API? The tracing events and their signatures?
The interface that dynamic instrumentation libraries use to interact
with QEMU. That means "stable" tracing events plus any operations that
libraries can perform (stop/stop vcpu, peek/poke memory, dirty bitmaps,
MMU, interrupts, etc).
Stefan
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH v3 14/24] instrument: Add internal control interface
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 14/24] instrument: Add internal control interface Lluís Vilanova
2013-04-26 14:08 ` Eric Blake
@ 2013-04-26 15:11 ` Paolo Bonzini
2013-04-26 15:25 ` Lluís Vilanova
1 sibling, 1 reply; 43+ messages in thread
From: Paolo Bonzini @ 2013-04-26 15:11 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: qemu-devel
Il 21/04/2013 21:12, Lluís Vilanova ha scritto:
> diff --git a/Makefile.objs b/Makefile.objs
> index 5f8ea2d..4fb565b 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -94,6 +94,7 @@ common-obj-y += disas/
> # instrumentation
>
> tools-obj-y += instrument/
> +target-obj-y += instrument/
>
Why does instrument/ have to be compiled once per target?
If you can compile it just once, then libqemuutil.a and util-obj-y will do.
Paolo
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH v3 07/24] system: [linux] Use absolute include path for linux-headers
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 07/24] system: [linux] Use absolute include path for linux-headers Lluís Vilanova
@ 2013-04-26 15:17 ` Paolo Bonzini
0 siblings, 0 replies; 43+ messages in thread
From: Paolo Bonzini @ 2013-04-26 15:17 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: qemu-devel
Il 21/04/2013 21:12, Lluís Vilanova ha scritto:
> Lets the include directive work regardless of the current directory.
>
> This is needed for code compiled in directories deeper than one level from the
> build root.
>
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
> Makefile.target | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Makefile.target b/Makefile.target
> index f382559..2f9675a 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -7,7 +7,7 @@ include $(SRC_PATH)/rules.mak
>
> $(call set-vpath, $(SRC_PATH))
> ifdef CONFIG_LINUX
> -QEMU_CFLAGS += -I../linux-headers
> +QEMU_CFLAGS += -I$(BUILD_DIR)/linux-headers
> endif
> QEMU_CFLAGS += -I.. -I$(SRC_PATH)/target-$(TARGET_BASE_ARCH) -DNEED_CPU_H
I am not sure why this is needed. The .. here is the path from
foo-softmmu/ to the build root. QEMU's build system is only one-level
recursive, something like foo-softmmu/hw/virtio/virtio.c is compiled
from foo-softmmu/ (whose Makefile is Makefile.target) and thus the path
needs to be relative from foo-softmmu/. It need not be relative to
foo-softmmu/hw/virtio.
Paolo
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH v3 03/24] trace: Let the user specify her own trace-events file
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 03/24] trace: Let the user specify her own trace-events file Lluís Vilanova
@ 2013-04-26 15:21 ` Paolo Bonzini
2013-04-26 18:28 ` Lluís Vilanova
0 siblings, 1 reply; 43+ messages in thread
From: Paolo Bonzini @ 2013-04-26 15:21 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: qemu-devel
Il 21/04/2013 21:11, Lluís Vilanova ha scritto:
> With this option the user can perform multiple builds of QEMU with different
> tracing event properties.
I don't understand why this is useful? If it is just to add/remove
"disable" here and there, surely the user should be using git and
different branches?
Paolo
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
> Makefile.target | 2 +-
> configure | 19 +++++++++++++++++++
> trace/Makefile.objs | 10 +++++-----
> 3 files changed, 25 insertions(+), 6 deletions(-)
>
> diff --git a/Makefile.target b/Makefile.target
> index 2bd6d14..f382559 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -47,7 +47,7 @@ else
> TARGET_TYPE=system
> endif
>
> -$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
> +$(QEMU_PROG).stp: $(TRACE_EVENTS)
> $(call quiet-command,$(TRACETOOL) \
> --format=stap \
> --backend=$(TRACE_BACKEND) \
> diff --git a/configure b/configure
> index 73df181..a3bd336 100755
> --- a/configure
> +++ b/configure
> @@ -221,6 +221,7 @@ blobs="yes"
> pkgversion=""
> pie=""
> zero_malloc=""
> +trace_events=`dirname $0`/trace-events
> trace_backend="nop"
> trace_file="trace"
> spice=""
> @@ -639,6 +640,8 @@ for opt do
> ;;
> --target-list=*) target_list="$optarg"
> ;;
> + --with-trace-events=*) trace_events="$optarg"
> + ;;
> --enable-trace-backend=*) trace_backend="$optarg"
> ;;
> --with-trace-file=*) trace_file="$optarg"
> @@ -1158,6 +1161,7 @@ echo " --enable-docs enable documentation build"
> echo " --disable-docs disable documentation build"
> echo " --disable-vhost-net disable vhost-net acceleration support"
> echo " --enable-vhost-net enable vhost-net acceleration support"
> +echo " --with-trace-events=PATH file with tracing events description (default: $trace_events)"
> echo " --enable-trace-backend=B Set trace backend"
> echo " Available backends:" $($python "$source_path"/scripts/tracetool.py --list-backends)
> echo " --with-trace-file=NAME Full PATH,NAME of file to store traces"
> @@ -3009,6 +3013,18 @@ if compile_prog "" "" ; then
> fi
>
> ##########################################
> +# check if trace-events file exists
> +
> +if test ! -f "$trace_events"; then
> + echo
> + echo "Error: the given trace-events file does not exist"
> + echo
> + exit 1
> +else
> + trace_events=`readlink -f "$trace_events"`
> +fi
> +
> +##########################################
> # check if trace backend exists
>
> $python "$source_path/scripts/tracetool.py" "--backend=$trace_backend" --check-backend > /dev/null 2> /dev/null
> @@ -3418,6 +3434,7 @@ echo "sigev_thread_id $sigev_thread_id"
> echo "uuid support $uuid"
> echo "libcap-ng support $cap_ng"
> echo "vhost-net support $vhost_net"
> +echo "Trace events $trace_events"
> echo "Trace backend $trace_backend"
> echo "Trace output file $trace_file-<pid>"
> echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
> @@ -3810,6 +3827,8 @@ bsd)
> ;;
> esac
>
> +echo "TRACE_EVENTS=$trace_events" >> $config_host_mak
> +
> # use default implementation for tracing backend-specific routines
> trace_default=yes
> echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak
> diff --git a/trace/Makefile.objs b/trace/Makefile.objs
> index a043072..bf0a965 100644
> --- a/trace/Makefile.objs
> +++ b/trace/Makefile.objs
> @@ -4,7 +4,7 @@
> # Auto-generated event descriptions
>
> $(obj)/generated-events.h: $(obj)/generated-events.h-timestamp
> -$(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events
> +$(obj)/generated-events.h-timestamp: $(TRACE_EVENTS)
> $(call quiet-command,$(TRACETOOL) \
> --format=events-h \
> --backend=events \
> @@ -12,7 +12,7 @@ $(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events
> @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
>
> $(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/config-host.mak
> -$(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events
> +$(obj)/generated-events.c-timestamp: $(TRACE_EVENTS)
> $(call quiet-command,$(TRACETOOL) \
> --format=events-c \
> --backend=events \
> @@ -27,7 +27,7 @@ util-obj-y += generated-events.o
>
> $(obj)/generated-tracers.h: $(obj)/generated-tracers.h-timestamp
> @cmp -s $< $@ || cp $< $@
> -$(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
> +$(obj)/generated-tracers.h-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.mak
> $(call quiet-command,$(TRACETOOL) \
> --format=h \
> --backend=$(TRACE_BACKEND) \
> @@ -39,7 +39,7 @@ $(obj)/generated-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/conf
> ifneq ($(TRACE_BACKEND),dtrace)
> $(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp
> @cmp -s $< $@ || cp $< $@
> -$(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
> +$(obj)/generated-tracers.c-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.mak
> $(call quiet-command,$(TRACETOOL) \
> --format=c \
> --backend=$(TRACE_BACKEND) \
> @@ -57,7 +57,7 @@ endif
> # rule file. So we use '.dtrace' instead
> ifeq ($(TRACE_BACKEND),dtrace)
> $(obj)/generated-tracers.dtrace: $(obj)/generated-tracers.dtrace-timestamp
> -$(obj)/generated-tracers.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
> +$(obj)/generated-tracers.dtrace-timestamp: $(TRACE_EVENTS) $(BUILD_DIR)/config-host.mak
> $(call quiet-command,$(TRACETOOL) \
> --format=d \
> --backend=$(TRACE_BACKEND) \
>
>
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH v3 05/24] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 05/24] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops Lluís Vilanova
@ 2013-04-26 15:23 ` Paolo Bonzini
0 siblings, 0 replies; 43+ messages in thread
From: Paolo Bonzini @ 2013-04-26 15:23 UTC (permalink / raw)
To: Lluís Vilanova, qemu-devel, Stefan Hajnoczi
Il 21/04/2013 21:11, Lluís Vilanova ha scritto:
> This problem arises in the following patches.
Removing inclusions of qemu-common.h from .h files is definitely useful.
However, the TRACE__CONTROL__USE__TRACE_PRINT_EVENTS is really hideous.
:) Just make inclusion of qemu-common.h mandatory before inclusion of
trace/control.h.
Paolo
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
> hw/virtio/virtio.c | 1 +
> monitor.c | 4 +++-
> scripts/tracetool/format/h.py | 9 ++++++++-
> trace/control-internal.h | 4 +++-
> trace/control.c | 4 +++-
> trace/control.h | 9 +++++++--
> trace/default.c | 4 +++-
> trace/simple.c | 4 +++-
> trace/simple.h | 1 +
> trace/stderr.c | 4 +++-
> 10 files changed, 35 insertions(+), 9 deletions(-)
>
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 1c2282c..a3dda2c 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -14,6 +14,7 @@
> #include <inttypes.h>
>
> #include "trace.h"
> +#include "qemu-common.h"
> #include "qemu/error-report.h"
> #include "hw/virtio/virtio.h"
> #include "qemu/atomic.h"
> diff --git a/monitor.c b/monitor.c
> index c897e80..a8f49d9 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -22,6 +22,9 @@
> * THE SOFTWARE.
> */
> #include <dirent.h>
> +#define TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
> +#include "trace/control.h"
> +#undef TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
> #include "hw/hw.h"
> #include "monitor/qdev.h"
> #include "hw/usb.h"
> @@ -59,7 +62,6 @@
> #include "qemu/osdep.h"
> #include "cpu.h"
> #include "trace.h"
> -#include "trace/control.h"
> #ifdef CONFIG_TRACE_SIMPLE
> #include "trace/simple.h"
> #endif
> diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
> index ed7c8a5..c98aebd 100644
> --- a/scripts/tracetool/format/h.py
> +++ b/scripts/tracetool/format/h.py
> @@ -22,7 +22,14 @@ def begin(events):
> '#ifndef TRACE__GENERATED_TRACERS_H',
> '#define TRACE__GENERATED_TRACERS_H',
> '',
> - '#include "qemu-common.h"')
> + '/* Do not directly include "qemu-common.h" to avoid circular dependencies */',
> + '#include <stdint.h>',
> + '#include <inttypes.h>',
> + '#include <stdbool.h>',
> + '#include <stddef.h>',
> + '#include <unistd.h>',
> + '',
> + )
>
> def end(events):
> out('#endif /* TRACE__GENERATED_TRACERS_H */')
> diff --git a/trace/control-internal.h b/trace/control-internal.h
> index cce2da4..a15a994 100644
> --- a/trace/control-internal.h
> +++ b/trace/control-internal.h
> @@ -1,7 +1,7 @@
> /*
> * Interface for configuring and controlling the state of tracing events.
> *
> - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu>
> + * Copyright (C) 2011-2013 Lluís Vilanova <vilanova@ac.upc.edu>
> *
> * This work is licensed under the terms of the GNU GPL, version 2 or later.
> * See the COPYING file in the top-level directory.
> @@ -11,6 +11,8 @@
> #define TRACE__CONTROL_INTERNAL_H
>
> #include <string.h>
> +#include <assert.h>
> +#include <stddef.h>
>
>
> extern TraceEvent trace_events[];
> diff --git a/trace/control.c b/trace/control.c
> index 49f61e1..dd7b260 100644
> --- a/trace/control.c
> +++ b/trace/control.c
> @@ -1,7 +1,7 @@
> /*
> * Interface for configuring and controlling the state of tracing events.
> *
> - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu>
> + * Copyright (C) 2011-2013 Lluís Vilanova <vilanova@ac.upc.edu>
> *
> * This work is licensed under the terms of the GNU GPL, version 2 or later.
> * See the COPYING file in the top-level directory.
> @@ -9,6 +9,8 @@
>
> #include "trace/control.h"
>
> +#include "qemu-common.h"
> +
>
> TraceEvent *trace_event_name(const char *name)
> {
> diff --git a/trace/control.h b/trace/control.h
> index cde8260..29ff9c1 100644
> --- a/trace/control.h
> +++ b/trace/control.h
> @@ -1,7 +1,7 @@
> /*
> * Interface for configuring and controlling the state of tracing events.
> *
> - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu>
> + * Copyright (C) 2011-2013 Lluís Vilanova <vilanova@ac.upc.edu>
> *
> * This work is licensed under the terms of the GNU GPL, version 2 or later.
> * See the COPYING file in the top-level directory.
> @@ -10,7 +10,6 @@
> #ifndef TRACE__CONTROL_H
> #define TRACE__CONTROL_H
>
> -#include "qemu-common.h"
> #include "trace/generated-events.h"
>
>
> @@ -155,6 +154,10 @@ void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state);
>
>
>
> +#if defined(TRACE__CONTROL__USE__TRACE_PRINT_EVENTS)
> +/* Minimize inclusions of "qemu-common.h" to avoid circular dependencies */
> +#include "qemu-common.h"
Can you just include this from the C files instead?
> /**
> * trace_print_events:
> *
> @@ -164,6 +167,8 @@ void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state);
> */
> void trace_print_events(FILE *stream, fprintf_function stream_printf);
>
> +#endif /* defined(TRACE__CONTROL__USE__TRACE_PRINT_EVENTS) */
> +
> /**
> * trace_backend_init:
> * @events: Name of file with events to be enabled at startup; may be NULL.
> diff --git a/trace/default.c b/trace/default.c
> index 6e07a47..4dbaf11 100644
> --- a/trace/default.c
> +++ b/trace/default.c
> @@ -1,13 +1,15 @@
> /*
> * Default implementation for backend initialization from commandline.
> *
> - * Copyright (C) 2011-2012 Lluís Vilanova <vilanova@ac.upc.edu>
> + * Copyright (C) 2011-2013 Lluís Vilanova <vilanova@ac.upc.edu>
> *
> * This work is licensed under the terms of the GNU GPL, version 2. See
> * the COPYING file in the top-level directory.
> */
>
> +#define TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
> #include "trace/control.h"
> +#undef TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
>
>
> void trace_print_events(FILE *stream, fprintf_function stream_printf)
> diff --git a/trace/simple.c b/trace/simple.c
> index 8b59760..cb4361f 100644
> --- a/trace/simple.c
> +++ b/trace/simple.c
> @@ -19,8 +19,10 @@
> #include <pthread.h>
> #endif
> #include "qemu/timer.h"
> -#include "trace.h"
> +#define TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
> #include "trace/control.h"
> +#undef TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
> +#include "trace.h"
>
> /** Trace file header event ID */
> #define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */
> diff --git a/trace/simple.h b/trace/simple.h
> index 5260d9a..1541ea0 100644
> --- a/trace/simple.h
> +++ b/trace/simple.h
> @@ -16,6 +16,7 @@
> #include <stdio.h>
>
> #include "trace/generated-events.h"
> +#include "qemu-common.h"
>
>
> void st_print_trace_file_status(FILE *stream, fprintf_function stream_printf);
> diff --git a/trace/stderr.c b/trace/stderr.c
> index e212efd..3a6f4bd 100644
> --- a/trace/stderr.c
> +++ b/trace/stderr.c
> @@ -1,5 +1,7 @@
> -#include "trace.h"
> +#define TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
> #include "trace/control.h"
> +#undef TRACE__CONTROL__USE__TRACE_PRINT_EVENTS
> +#include "trace.h"
>
>
> void trace_print_events(FILE *stream, fprintf_function stream_printf)
>
>
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH v3 22/24] build: Fix installation of target-dependant files
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 22/24] build: Fix installation of target-dependant files Lluís Vilanova
@ 2013-04-26 15:24 ` Paolo Bonzini
2013-04-26 15:27 ` Peter Maydell
0 siblings, 1 reply; 43+ messages in thread
From: Paolo Bonzini @ 2013-04-26 15:24 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: qemu-devel
Il 21/04/2013 21:13, Lluís Vilanova ha scritto:
> Pass all the relevant sub-directory make variables.
>
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
> Cc: Anthony Liguori <aliguori@us.ibm.com>
> Cc: Paul Brook <paul@codesourcery.com>
> ---
> Makefile | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/Makefile b/Makefile
> index 7916152..ccf6760 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -346,7 +346,7 @@ endif
> $(INSTALL_DATA) $(SRC_PATH)/pc-bios/keymaps/$$x "$(DESTDIR)$(qemu_datadir)/keymaps"; \
> done
> for d in $(TARGET_DIRS); do \
> - $(MAKE) -C $$d $@ || exit 1 ; \
> + $(MAKE) $(SUBDIR_MAKEFLAGS) TARGET_DIR=$$d/ -C $$d $@ || exit 1 ; \
> done
>
> # various test targets
>
>
>
Please resubmit this separately too, it is a worthwhile cleanup.
Paolo
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH v3 14/24] instrument: Add internal control interface
2013-04-26 15:11 ` Paolo Bonzini
@ 2013-04-26 15:25 ` Lluís Vilanova
2013-04-26 15:27 ` Paolo Bonzini
0 siblings, 1 reply; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-26 15:25 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
Paolo Bonzini writes:
> Il 21/04/2013 21:12, Lluís Vilanova ha scritto:
>> diff --git a/Makefile.objs b/Makefile.objs
>> index 5f8ea2d..4fb565b 100644
>> --- a/Makefile.objs
>> +++ b/Makefile.objs
>> @@ -94,6 +94,7 @@ common-obj-y += disas/
>> # instrumentation
>>
>> tools-obj-y += instrument/
>> +target-obj-y += instrument/
>>
> Why does instrument/ have to be compiled once per target?
> If you can compile it just once, then libqemuutil.a and util-obj-y will do.
It looks like that after some re-merges, the patch was placed too early in the
series. This is necessary later for files like instrument/cmdline.c and
instrument/api-control.c (patch 18).
Lluis
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH v3 22/24] build: Fix installation of target-dependant files
2013-04-26 15:24 ` Paolo Bonzini
@ 2013-04-26 15:27 ` Peter Maydell
0 siblings, 0 replies; 43+ messages in thread
From: Peter Maydell @ 2013-04-26 15:27 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Lluís Vilanova, qemu-devel
On 26 April 2013 16:24, Paolo Bonzini <pbonzini@redhat.com> wrote:
> Il 21/04/2013 21:13, Lluís Vilanova ha scritto:
>> Pass all the relevant sub-directory make variables.
>>
>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> Please resubmit this separately too, it is a worthwhile cleanup.
...if you're going to resubmit anyway, you might fix the
typo in the commit message: "dependent" ends -ent.
thanks
-- PMM
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH v3 14/24] instrument: Add internal control interface
2013-04-26 15:25 ` Lluís Vilanova
@ 2013-04-26 15:27 ` Paolo Bonzini
0 siblings, 0 replies; 43+ messages in thread
From: Paolo Bonzini @ 2013-04-26 15:27 UTC (permalink / raw)
To: qemu-devel
Il 26/04/2013 17:25, Lluís Vilanova ha scritto:
> Paolo Bonzini writes:
>
>> Il 21/04/2013 21:12, Lluís Vilanova ha scritto:
>>> diff --git a/Makefile.objs b/Makefile.objs
>>> index 5f8ea2d..4fb565b 100644
>>> --- a/Makefile.objs
>>> +++ b/Makefile.objs
>>> @@ -94,6 +94,7 @@ common-obj-y += disas/
>>> # instrumentation
>>>
>>> tools-obj-y += instrument/
>>> +target-obj-y += instrument/
>>>
>
>> Why does instrument/ have to be compiled once per target?
>
>> If you can compile it just once, then libqemuutil.a and util-obj-y will do.
>
> It looks like that after some re-merges, the patch was placed too early in the
> series. This is necessary later for files like instrument/cmdline.c and
> instrument/api-control.c (patch 18).
The point of using a static library is exactly to leave out files
automatically if they are not used. Just put it into libqemuutil.a, and
tools will not pick it up.
Paolo
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [PATCH v3 03/24] trace: Let the user specify her own trace-events file
2013-04-26 15:21 ` Paolo Bonzini
@ 2013-04-26 18:28 ` Lluís Vilanova
0 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-26 18:28 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
Paolo Bonzini writes:
> Il 21/04/2013 21:11, Lluís Vilanova ha scritto:
>> With this option the user can perform multiple builds of QEMU with different
>> tracing event properties.
> I don't understand why this is useful? If it is just to add/remove
> "disable" here and there, surely the user should be using git and
> different branches?
Well, you can create multiple build directories that use a different
trace-events file. As you have to explicitly add the "instrument" keyword on
events, I found it handy to have builds with different sorts of events.
Lluis
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines
2013-04-26 15:10 ` Stefan Hajnoczi
@ 2013-04-28 19:25 ` Lluís Vilanova
2013-05-01 11:54 ` Stefan Hajnoczi
0 siblings, 1 reply; 43+ messages in thread
From: Lluís Vilanova @ 2013-04-28 19:25 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: qemu-devel
Stefan Hajnoczi writes:
> On Fri, Apr 26, 2013 at 02:15:46PM +0200, Lluís Vilanova wrote:
>> Stefan Hajnoczi writes:
>>
>> > On Wed, Apr 24, 2013 at 02:17:22PM +0200, Lluís Vilanova wrote:
>> > Given that the group of users for this feature is so small while the
>> > burden of supporting this is rather large, it seems like writing
>> > instrumentation code straight in a QEMU source tree is the most powerful
>> > and viable solution.
>>
>> Well, the tracing event instrumentation support itself is quite generic and
>> should be maintainable, and can enormously simplify the task for others to use
>> it in the future.
>>
>> From my repository, the first three series (including this one) handle the
>> infrastructure, which is mostly based on providing tracetool backends.
>>
>> The 4th one adds some very generic events (vbbl_{before,after},
>> vinst_{before,after}, vmem) that should have no ties to the TCG implementation.
> They would be affected by things like real TCG vcpu threads (parallel
> translation and execution) because now trace events will be invoked
> simultaneously from multiple threads. Or heterogenous cores in QEMU
> (ARM + DSP) where previously you could assume there is one target
> architecture.
Yes, my assumption was that the library is invoked on the vCPU's thread, so
everything is performed on its context. For other non-guest tracing events, you
need to know what's going on in QEMU, and that's why events are not
instrumentable by default.
What I didn't yet get to implement is to safely unload an instrumentation
library or change the callback for an event (e.g., ensure it is performed
exclusively).
As for the heterogeneous case, I thought it was still far, so I didn't give it
much thought. Most of the code in the base infrastructure is oblivious to the
target. Once you need that, the affected target-specific routines would need to
be defined using something similar to the current function pointers in CPUState
when having a heterogeneous QEMU.
>> The 5th one adds the backdoor we discussed long ago, which lets the guest code
>> interact with the instrumentation library, so that they can coordinate (AFAIR,
>> Blue said that could come in handy during tests, for example).
>>
>> The next ones probably are more controversial, as they start adding new
>> interfaces available to the instrumentation libraries (as well as some extra
>> events).
> I don't think this effort is maintainable.
> The API would be great if QEMU was heavily focussed on instrumentation
> and simulation research. It allows interesting analysis without diving
> into the internals of QEMU.
> The problem is it touches everything in QEMU because you should be able
> to instrument everything. Who is going to maintain an API of this
> scope?
> The QEMU community has two large groups: TCG for emulation and KVM for
> virtualization. The API doesn't offer them anything so they will not
> keep it in mind when making changes.
Ok, my bad. After the initial discussions that took place long ago I understood
there actually was some interest in having such functionality, although not with
all the public APIs I added.
I have no problem in maintaining a separate branch for certain events and
interfaces (some of which are currently quite crude and hackish in the final
series), as long as the bases are upstream (e.g., instrumentation
infrastructure, and the most basic abstract guest events).
> This is why I think it makes more sense to focus on specific tools that
> don't try to introduce stable APIs. i.e. a tool for instruction tracing
> in TCG.
I'm not sure what you mean by such a tool. What some patches do is, for example,
call "trace_vbbl_begin" at the beginning of the main loop of
"gen_intermediate_code_internal" of each target. The user does not instrument
calls to actual TCG routines (which know near to nothing about the guest
semantics), but only the "vbbl_begin" event.
In fact, while looking at all the targets I thought about unifying code by
merging code generation of all targets using a single common header implementing
the main loop, with callbacks to target-specific code. But I thought that would
be too invasive to the project.
I agree that all the public API could become a burden for a project only
interested in functional emulation and virtualization, but as I said I think the
most basic parts of it could be landed, already providing a powerful
infrastructure where further extension is up to the user.
> Advanced users will have to modify the QEMU source.
>> > Basically I think putting a stable API in place here isn't going to fly.
>> > In terms of the tracing subsystem I don't mind, but I think it's a
>> > question for the larger QEMU community.
>>
>> What are you referring to as an API? The tracing events and their signatures?
> The interface that dynamic instrumentation libraries use to interact
> with QEMU. That means "stable" tracing events plus any operations that
> libraries can perform (stop/stop vcpu, peek/poke memory, dirty bitmaps,
> MMU, interrupts, etc).
Not all events require being "stable", just a few that I established as
"abstract" and relate to some very generic guest state (which in their most
basic form can be boiled down to 5). As for the rest of the API and more
controversial events, as I said I have no problem in maintaining a separate
branch.
Thanks,
Lluis
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines
2013-04-28 19:25 ` Lluís Vilanova
@ 2013-05-01 11:54 ` Stefan Hajnoczi
2013-05-01 14:34 ` Lluís Vilanova
0 siblings, 1 reply; 43+ messages in thread
From: Stefan Hajnoczi @ 2013-05-01 11:54 UTC (permalink / raw)
To: qemu-devel
On Sun, Apr 28, 2013 at 09:25:15PM +0200, Lluís Vilanova wrote:
> Stefan Hajnoczi writes:
>
> > On Fri, Apr 26, 2013 at 02:15:46PM +0200, Lluís Vilanova wrote:
> > Advanced users will have to modify the QEMU source.
>
> >> > Basically I think putting a stable API in place here isn't going to fly.
> >> > In terms of the tracing subsystem I don't mind, but I think it's a
> >> > question for the larger QEMU community.
> >>
> >> What are you referring to as an API? The tracing events and their signatures?
>
> > The interface that dynamic instrumentation libraries use to interact
> > with QEMU. That means "stable" tracing events plus any operations that
> > libraries can perform (stop/stop vcpu, peek/poke memory, dirty bitmaps,
> > MMU, interrupts, etc).
>
> Not all events require being "stable", just a few that I established as
> "abstract" and relate to some very generic guest state (which in their most
> basic form can be boiled down to 5). As for the rest of the API and more
> controversial events, as I said I have no problem in maintaining a separate
> branch.
Can you split the work into two patch series:
1. Target-independent TCG events (e.g. vbbl_begin)
2. "custom" trace backend that links custom C trace event handler
functions - but without dynamic libraries or stable API.
It loses the dynamic library and stable API features but would be easy
to merge.
Stefan
^ permalink raw reply [flat|nested] 43+ messages in thread
* Re: [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines
2013-05-01 11:54 ` Stefan Hajnoczi
@ 2013-05-01 14:34 ` Lluís Vilanova
0 siblings, 0 replies; 43+ messages in thread
From: Lluís Vilanova @ 2013-05-01 14:34 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: qemu-devel
Stefan Hajnoczi writes:
> On Sun, Apr 28, 2013 at 09:25:15PM +0200, Lluís Vilanova wrote:
>> Stefan Hajnoczi writes:
>>
>> > On Fri, Apr 26, 2013 at 02:15:46PM +0200, Lluís Vilanova wrote:
>> > Advanced users will have to modify the QEMU source.
>>
>> >> > Basically I think putting a stable API in place here isn't going to fly.
>> >> > In terms of the tracing subsystem I don't mind, but I think it's a
>> >> > question for the larger QEMU community.
>> >>
>> >> What are you referring to as an API? The tracing events and their signatures?
>>
>> > The interface that dynamic instrumentation libraries use to interact
>> > with QEMU. That means "stable" tracing events plus any operations that
>> > libraries can perform (stop/stop vcpu, peek/poke memory, dirty bitmaps,
>> > MMU, interrupts, etc).
>>
>> Not all events require being "stable", just a few that I established as
>> "abstract" and relate to some very generic guest state (which in their most
>> basic form can be boiled down to 5). As for the rest of the API and more
>> controversial events, as I said I have no problem in maintaining a separate
>> branch.
> Can you split the work into two patch series:
> 1. Target-independent TCG events (e.g. vbbl_begin)
> 2. "custom" trace backend that links custom C trace event handler
> functions - but without dynamic libraries or stable API.
> It loses the dynamic library and stable API features but would be easy
> to merge.
Yes, I was thinking about sending a mail along those lines too. This basically
entails two series (2nd and 4th in my current branch):
* Support for tracing events at TCG code generation time (basically
auto-generating per-event TCG helpers - trace_<event>_tcg -, which call the
actual tracing event - trace_<event> -).
* The events themselves (calls to trace_<event>_tcg).
I can then maintain instrumentation support and its public API on a separate
branch.
Still, I'm not sure when I'll have time for this, as it will require moving a
few patches among the series I have now (and readjusting their contents).
Thanks,
Lluis
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply [flat|nested] 43+ messages in thread
end of thread, other threads:[~2013-05-01 14:34 UTC | newest]
Thread overview: 43+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-21 19:11 [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 01/24] instrument: Add documentation Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 02/24] trace: [simple] Do not include "trace/simple.h" in generated tracer headers Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 03/24] trace: Let the user specify her own trace-events file Lluís Vilanova
2013-04-26 15:21 ` Paolo Bonzini
2013-04-26 18:28 ` Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 04/24] tracetool: Use method 'Event.api' to get the name of public routines Lluís Vilanova
2013-04-21 19:11 ` [Qemu-devel] [PATCH v3 05/24] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops Lluís Vilanova
2013-04-26 15:23 ` Paolo Bonzini
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 06/24] instrument: [none] Add null instrumentation Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 07/24] system: [linux] Use absolute include path for linux-headers Lluís Vilanova
2013-04-26 15:17 ` Paolo Bonzini
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 08/24] instrument: [static] Call statically linked user-provided routines Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 09/24] build: Add variable 'tools-obj-y' for tool-only files Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 10/24] instrument: [dynamic] Call dynamically linked user-provided routines Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 11/24] qapi: Add a primitive to include other files from a QAPI schema file Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 12/24] qapi: [trivial] Set the input root directory when parsing QAPI files Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 13/24] qapi: [trivial] Allow user to use 'args' as an argument name Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 14/24] instrument: Add internal control interface Lluís Vilanova
2013-04-26 14:08 ` Eric Blake
2013-04-26 15:11 ` Paolo Bonzini
2013-04-26 15:25 ` Lluís Vilanova
2013-04-26 15:27 ` Paolo Bonzini
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 15/24] instrument: [qmp, qapi] Add " Lluís Vilanova
2013-04-21 19:12 ` [Qemu-devel] [PATCH v3 16/24] instrument: [hmp] " Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 17/24] Let makefiles add entries to the set of target architecture objects Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 18/24] instrument: Add commandline options to start with an instrumentation library Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 19/24] instrument: Add client-side API to enumerate events Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 20/24] instrument: Add client-side API to control tracing state of events Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 21/24] instrument: Add client-side API to control event instrumentation Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 22/24] build: Fix installation of target-dependant files Lluís Vilanova
2013-04-26 15:24 ` Paolo Bonzini
2013-04-26 15:27 ` Peter Maydell
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 23/24] instrument: Install headers for dynamic instrumentation clients Lluís Vilanova
2013-04-21 19:13 ` [Qemu-devel] [PATCH v3 24/24] trace: Do not use the word 'new' in event arguments Lluís Vilanova
2013-04-24 11:17 ` [Qemu-devel] [RFC][PATCH v3 00/24] instrument: Let the user wrap/override specific event tracing routines Stefan Hajnoczi
2013-04-24 12:17 ` Lluís Vilanova
2013-04-25 12:39 ` Stefan Hajnoczi
2013-04-26 12:15 ` Lluís Vilanova
2013-04-26 15:10 ` Stefan Hajnoczi
2013-04-28 19:25 ` Lluís Vilanova
2013-05-01 11:54 ` Stefan Hajnoczi
2013-05-01 14:34 ` Lluís Vilanova
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).