All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines
@ 2013-03-26 14:00 Lluís Vilanova
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 01/22] instrument: Add documentation Lluís Vilanova
                   ` (22 more replies)
  0 siblings, 23 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:00 UTC (permalink / raw)
  To: qemu-devel

NOTE: Applies on top of the "trace: Generic event state description" series
      (already in the tracing tree), and is based on revision a4bcea3 from
      master.

TODO: Make sure no TCG code is executing during 'instr_unload' (qemu_cpu_kick?
      tb_lock?)

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>
---

Lluís Vilanova (22):
      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
      linux-user: Use absolute include path
      instrument: [static] Call statically linked user-provided routines
      instrument: [dynamic] Call dynamically linked user-provided routines
      instrument: Add internal control interface
      instrument: [hmp] Add control interface
      qapi: Add a primitive to include other files from a QAPI schema file
      [trivial] Set the input root directory when parsing QAPI files
      instrument: [qmp, qapi] 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                                    |   46 ++-
 Makefile.objs                               |    8 
 Makefile.target                             |    7 
 bsd-user/main.c                             |   24 +
 bsd-user/syscall.c                          |    5 
 configure                                   |   96 +++++
 docs/instrumentation.txt                    |  481 +++++++++++++++++++++++++++
 docs/tracing.txt                            |    9 +
 hmp-commands.hx                             |   42 ++
 hw/virtio.c                                 |    1 
 include/qapi/qmp/qerror.h                   |    9 +
 include/trace.h                             |    2 
 instrument/Makefile.objs                    |   86 +++++
 instrument/api-control.c                    |   14 +
 instrument/api-trace.c                      |   14 +
 instrument/cmdline.c                        |   94 +++++
 instrument/cmdline.h                        |   41 ++
 instrument/control-internal.h               |   33 ++
 instrument/control.c                        |  139 ++++++++
 instrument/control.h                        |  133 +++++++
 instrument/hmp.c                            |   65 ++++
 instrument/hmp.h                            |   21 +
 instrument/qapi-schema.json                 |   33 ++
 instrument/qemu-instr/control-internal.h    |   64 ++++
 instrument/qemu-instr/control.h             |  185 ++++++++++
 instrument/qemu-instr/trace-internal.h      |   27 ++
 instrument/qemu-instr/trace.h               |   91 +++++
 instrument/qemu-instr/visibility-internal.h |   94 +++++
 instrument/qmp.c                            |   59 +++
 libcacard/Makefile                          |    2 
 linux-user/main.c                           |   29 ++
 linux-user/syscall.c                        |    4 
 monitor.c                                   |    5 
 qapi-schema.json                            |    2 
 qemu-options.hx                             |   18 +
 qmp-commands.hx                             |   72 ++++
 qmp.c                                       |    4 
 rules.mak                                   |    3 
 scripts/qapi-commands.py                    |   10 -
 scripts/qapi-types.py                       |   10 -
 scripts/qapi-visit.py                       |   10 -
 scripts/qapi.py                             |   12 +
 scripts/tracetool.py                        |   12 +
 scripts/tracetool/__init__.py               |   26 +
 scripts/tracetool/backend/dtrace.py         |    4 
 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         |   11 -
 scripts/tracetool/backend/stderr.py         |    3 
 scripts/tracetool/backend/ust.py            |    6 
 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        |   40 ++
 scripts/tracetool/format/h.py               |   13 +
 scripts/tracetool/format/qemu_h.py          |   68 ++++
 trace-events                                |    8 
 trace/Makefile.objs                         |   10 -
 trace/control-internal.h                    |    2 
 trace/control.c                             |    2 
 trace/control.h                             |    7 
 trace/default.c                             |    2 
 trace/event-internal.h                      |   15 +
 trace/simple.c                              |    6 
 trace/simple.h                              |    1 
 trace/stderr.c                              |    4 
 vl.c                                        |   36 ++
 69 files changed, 2670 insertions(+), 52 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

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 01/22] instrument: Add documentation
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
@ 2013-03-26 14:00 ` Lluís Vilanova
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 02/22] trace: [simple] Do not include "trace/simple.h" in generated tracer headers Lluís Vilanova
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:00 UTC (permalink / raw)
  To: qemu-devel

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 docs/instrumentation.txt |  481 ++++++++++++++++++++++++++++++++++++++++++++++
 docs/tracing.txt         |    9 +
 2 files changed, 490 insertions(+)
 create mode 100644 docs/instrumentation.txt

diff --git a/docs/instrumentation.txt b/docs/instrumentation.txt
new file mode 100644
index 0000000..2f5ec3b
--- /dev/null
+++ b/docs/instrumentation.txt
@@ -0,0 +1,481 @@
+= 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(const char *args)
+    {
+        fprintf(stderr, "init!\n");
+        fprintf(stderr, "    args :: %s\n", args);
+    
+        /* 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(void)
+    {
+        fprintf(stderr, "init!\n");
+        fprintf(stderr, "    args :: %s\n", args);
+    
+        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_STATIC (QI_TYPE_DYNAMIC) will be available and set to 1 if
+  QEMU has been compiled with static (dynamic) instrumentation.
+
+* "qemu-instr/control.h"
+
+  Routine 'qi_ctrl_dynamic' 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_DYNAMIC)
+    #include "events-post.h"
+    #endif
+    
+    void qi_init(void)
+    {
+        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_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_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] 31+ messages in thread

* [Qemu-devel] [PATCH 02/22] trace: [simple] Do not include "trace/simple.h" in generated tracer headers
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 01/22] instrument: Add documentation Lluís Vilanova
@ 2013-03-26 14:00 ` Lluís Vilanova
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 03/22] trace: Let the user specify her own trace-events file Lluís Vilanova
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:00 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 |    3 ---
 trace/simple.c                      |    2 ++
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py
index 37ef599..30faac9 100644
--- a/scripts/tracetool/backend/simple.py
+++ b/scripts/tracetool/backend/simple.py
@@ -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] 31+ messages in thread

* [Qemu-devel] [PATCH 03/22] trace: Let the user specify her own trace-events file
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 01/22] instrument: Add documentation Lluís Vilanova
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 02/22] trace: [simple] Do not include "trace/simple.h" in generated tracer headers Lluís Vilanova
@ 2013-03-26 14:00 ` Lluís Vilanova
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 04/22] tracetool: Use method 'Event.api' to get the name of public routines Lluís Vilanova
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:00 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 ca657b3..310471b 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 19738ac..a75af67 100755
--- a/configure
+++ b/configure
@@ -211,6 +211,7 @@ blobs="yes"
 pkgversion=""
 pie=""
 zero_malloc=""
+trace_events=`dirname $0`/trace-events
 trace_backend="nop"
 trace_file="trace"
 spice=""
@@ -624,6 +625,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"
@@ -1133,6 +1136,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"
@@ -2998,6 +3002,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
@@ -3393,6 +3409,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)"
@@ -3788,6 +3805,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 156aa25..db573f4 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
-$(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] 31+ messages in thread

* [Qemu-devel] [PATCH 04/22] tracetool: Use method 'Event.api' to get the name of public routines
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (2 preceding siblings ...)
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 03/22] trace: Let the user specify her own trace-events file Lluís Vilanova
@ 2013-03-26 14:00 ` Lluís Vilanova
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 05/22] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops Lluís Vilanova
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:00 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       |    8 ++++++++
 scripts/tracetool/backend/dtrace.py |    4 ++--
 scripts/tracetool/backend/simple.py |    8 ++++----
 scripts/tracetool/backend/stderr.py |    3 ++-
 scripts/tracetool/backend/ust.py    |    6 ++++--
 scripts/tracetool/format/h.py       |    4 ++--
 6 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 175df08..a0579a8 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -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..5fad33e 100644
--- a/scripts/tracetool/backend/dtrace.py
+++ b/scripts/tracetool/backend/dtrace.py
@@ -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 30faac9..279551a 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..70cb27d 100644
--- a/scripts/tracetool/backend/stderr.py
+++ b/scripts/tracetool/backend/stderr.py
@@ -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..e9a49b4 100644
--- a/scripts/tracetool/backend/ust.py
+++ b/scripts/tracetool/backend/ust.py
@@ -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..575d2f1 100644
--- a/scripts/tracetool/format/h.py
+++ b/scripts/tracetool/format/h.py
@@ -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] 31+ messages in thread

* [Qemu-devel] [PATCH 05/22] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (3 preceding siblings ...)
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 04/22] tracetool: Use method 'Event.api' to get the name of public routines Lluís Vilanova
@ 2013-03-26 14:00 ` Lluís Vilanova
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 06/22] instrument: [none] Add null instrumentation Lluís Vilanova
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:00 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.c                   |    1 +
 monitor.c                     |    4 +++-
 scripts/tracetool/format/h.py |    9 ++++++++-
 trace/control-internal.h      |    2 ++
 trace/control.c               |    2 ++
 trace/control.h               |    7 ++++++-
 trace/default.c               |    2 ++
 trace/simple.c                |    4 +++-
 trace/simple.h                |    1 +
 trace/stderr.c                |    4 +++-
 10 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/hw/virtio.c b/hw/virtio.c
index e259348..1f26a55 100644
--- a/hw/virtio.c
+++ b/hw/virtio.c
@@ -14,6 +14,7 @@
 #include <inttypes.h>
 
 #include "trace.h"
+#include "qemu-common.h"
 #include "qemu/error-report.h"
 #include "virtio.h"
 #include "qemu/atomic.h"
diff --git a/monitor.c b/monitor.c
index e287c06..2fff049 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 "hw/qdev.h"
 #include "hw/usb.h"
@@ -58,7 +61,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 575d2f1..7c5b401 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..ed4ccf7 100644
--- a/trace/control-internal.h
+++ b/trace/control-internal.h
@@ -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..6d6cbea 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -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..a125098 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -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..adb8693 100644
--- a/trace/default.c
+++ b/trace/default.c
@@ -7,7 +7,9 @@
  * 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] 31+ messages in thread

* [Qemu-devel] [PATCH 06/22] instrument: [none] Add null instrumentation
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (4 preceding siblings ...)
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 05/22] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops Lluís Vilanova
@ 2013-03-26 14:00 ` Lluís Vilanova
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 07/22] linux-user: Use absolute include path Lluís Vilanova
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:00 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 27ad002..3c7d1a7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,8 @@ trace/generated-tracers.c
 trace/generated-tracers-dtrace.h
 trace/generated-tracers-dtrace.dtrace
 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 9a240fb..ba313bd 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 a75af67..0041f2f 100755
--- a/configure
+++ b/configure
@@ -214,6 +214,7 @@ zero_malloc=""
 trace_events=`dirname $0`/trace-events
 trace_backend="nop"
 trace_file="trace"
+trace_instrument="none"
 spice=""
 rbd=""
 smartcard_nss=""
@@ -631,6 +632,8 @@ for opt do
   ;;
   --with-trace-file=*) trace_file="$optarg"
   ;;
+  --with-trace-instrument=*) trace_instrument="$optarg"
+  ;;
   --enable-gprof) gprof="yes"
   ;;
   --enable-gcov) gcov="yes"
@@ -1141,6 +1144,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)"
@@ -3060,6 +3065,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
@@ -3412,6 +3426,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"
@@ -3837,6 +3852,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_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 a0579a8..4b3b571 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..93e57f9
--- /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, 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..2277e94
--- /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, 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..fb81d66
--- /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, 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] 31+ messages in thread

* [Qemu-devel] [PATCH 07/22] linux-user: Use absolute include path
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (5 preceding siblings ...)
  2013-03-26 14:00 ` [Qemu-devel] [PATCH 06/22] instrument: [none] Add null instrumentation Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:06   ` Peter Maydell
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 08/22] instrument: [static] Call statically linked user-provided routines Lluís Vilanova
                   ` (15 subsequent siblings)
  22 siblings, 1 reply; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 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 310471b..af299a0 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] 31+ messages in thread

* [Qemu-devel] [PATCH 08/22] instrument: [static] Call statically linked user-provided routines
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (6 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 07/22] linux-user: Use absolute include path Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 09/22] instrument: [dynamic] Call dynamically " Lluís Vilanova
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 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                      |   12 ++++-
 scripts/tracetool/__init__.py             |   10 +++-
 scripts/tracetool/backend/instr_static.py |   76 +++++++++++++++++++++++++++++
 6 files changed, 164 insertions(+), 5 deletions(-)
 create mode 100644 scripts/tracetool/backend/instr_static.py

diff --git a/Makefile.target b/Makefile.target
index af299a0..a26f2ca 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -148,6 +148,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 0041f2f..b57b28e 100755
--- a/configure
+++ b/configure
@@ -215,6 +215,7 @@ trace_events=`dirname $0`/trace-events
 trace_backend="nop"
 trace_file="trace"
 trace_instrument="none"
+trace_instrument_path=""
 spice=""
 rbd=""
 smartcard_nss=""
@@ -634,6 +635,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"
@@ -1145,7 +1148,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)"
@@ -3067,13 +3072,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
@@ -3427,6 +3451,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"
@@ -3866,6 +3893,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_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
@@ -4136,6 +4170,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..7da91b3 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -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 4b3b571..b98a0af 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..5a067b8
--- /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, 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] 31+ messages in thread

* [Qemu-devel] [PATCH 09/22] instrument: [dynamic] Call dynamically linked user-provided routines
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (7 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 08/22] instrument: [static] Call statically linked user-provided routines Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 10/22] instrument: Add internal control interface Lluís Vilanova
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 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                              |    5 ++
 configure                                  |    8 ++-
 instrument/Makefile.objs                   |   10 +++
 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       |   34 +++++++++++
 trace/event-internal.h                     |   10 +++
 11 files changed, 182 insertions(+), 4 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 3c7d1a7..a46e490 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,6 +9,7 @@ trace/generated-tracers-dtrace.h
 trace/generated-tracers-dtrace.dtrace
 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 ba313bd..6d49378 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
@@ -227,6 +230,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 a68cdac..12b67bf 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -98,6 +98,11 @@ common-obj-y += qom/
 common-obj-y += disas/
 
 ######################################################################
+# instrumentation
+
+util-obj-y += instrument/
+
+######################################################################
 # guest agent
 
 # FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed
diff --git a/configure b/configure
index b57b28e..55c2fcc 100755
--- a/configure
+++ b/configure
@@ -1148,7 +1148,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"
@@ -3072,7 +3072,7 @@ fi
 ##########################################
 # Check instrumentation type
 case "$trace_instrument" in
-none|static) ;;
+none|static|dynamic) ;;
 *)       echo "Error: invalid trace instrumentation type: $trace_instrument"
          exit 1
          ;;
@@ -3900,6 +3900,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_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..ce6cfe5 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -17,6 +17,16 @@ 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,%,$@)
+
+util-obj-$(CONFIG_TRACE_INSTRUMENT_DYNAMIC) += generated-tracers.o
+
 
 ######################################################################
 # User interface
diff --git a/libcacard/Makefile b/libcacard/Makefile
index 47827a0..4d91c3c 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 b98a0af..eb6a8a9 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..e8de5a6
--- /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, 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..49db0fc
--- /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, 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..73b080d 100644
--- a/scripts/tracetool/format/events_c.py
+++ b/scripts/tracetool/format/events_c.py
@@ -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..fb5629b 100644
--- a/trace/event-internal.h
+++ b/trace/event-internal.h
@@ -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] 31+ messages in thread

* [Qemu-devel] [PATCH 10/22] instrument: Add internal control interface
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (8 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 09/22] instrument: [dynamic] Call dynamically " Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 11/22] instrument: [hmp] Add " Lluís Vilanova
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 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              |   33 +++++++
 instrument/control.c                       |  139 ++++++++++++++++++++++++++++
 instrument/control.h                       |  133 +++++++++++++++++++++++++++
 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 +
 11 files changed, 336 insertions(+)
 create mode 100644 instrument/control-internal.h
 create mode 100644 instrument/control.c
 create mode 100644 instrument/control.h

diff --git a/Makefile.objs b/Makefile.objs
index 12b67bf..fd6779e 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -101,6 +101,7 @@ common-obj-y += disas/
 # instrumentation
 
 util-obj-y += instrument/
+target-obj-y += instrument/
 
 ######################################################################
 # guest agent
@@ -120,5 +121,6 @@ nested-vars += \
 	util-obj-y \
 	qga-obj-y \
 	block-obj-y \
+	target-obj-y \
 	common-obj-y
 dummy := $(call unnest-vars)
diff --git a/configure b/configure
index 55c2fcc..e1ac5ff 100755
--- a/configure
+++ b/configure
@@ -3903,7 +3903,10 @@ fi
 if test "$trace_instrument" = "dynamic"; then
     echo "#define QI_TYPE_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 ce6cfe5..0d3b70b 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -59,3 +59,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..742f67a
--- /dev/null
+++ b/instrument/control-internal.h
@@ -0,0 +1,33 @@
+/*
+ * Interface for controlling dynamic trace instrumentation.
+ *
+ * Copyright (C) 2012 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 <assert.h>
+#include <stdlib.h>
+
+#include "config-host.h"
+
+
+static inline bool instr_dynamic(void)
+{
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+    return true;
+#else
+    return false;
+#endif
+}
+
+static inline bool instr_event_available(TraceEvent *ev)
+{
+    assert(ev != NULL);
+#if defined(CONFIG_TRACE_INSTRUMENT_NONE)
+    return false;
+#else
+    return ev->instr;
+#endif
+}
diff --git a/instrument/control.c b/instrument/control.c
new file mode 100644
index 0000000..43f76f1
--- /dev/null
+++ b/instrument/control.c
@@ -0,0 +1,139 @@
+/*
+ * Interface for controlling dynamic trace instrumentation.
+ *
+ * Copyright (C) 2012 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"
+
+
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+static void *handle = NULL;
+#endif
+
+
+InstrLoadError instr_load(const char * path, const char * args)
+{
+    if (!instr_dynamic()) {
+        return INSTR_LOAD_UNAVAILABLE;
+    }
+
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+    if (handle != NULL) {
+        return INSTR_LOAD_LOADED;
+    }
+
+    handle = dlopen(path, RTLD_NOW);
+
+    if (handle == NULL) {
+        return INSTR_LOAD_DL;
+    }
+
+    void (*init)(const char *) = dlsym(handle, "qi_init");
+    if (init == NULL) {
+        return INSTR_LOAD_DL;
+    }
+    void (*fini)(void) = dlsym(handle, "qi_fini");
+    if (fini == NULL) {
+        return INSTR_LOAD_DL;
+    }
+
+    if (init != NULL) {
+        init(args);
+    }
+#endif
+
+    return INSTR_LOAD_OK;
+}
+
+InstrUnloadError instr_unload(void)
+{
+    if (!instr_dynamic()) {
+        return INSTR_UNLOAD_UNAVAILABLE;
+    }
+
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+    if (handle == NULL)  {
+        return INSTR_UNLOAD_UNLOADED;
+    }
+
+    void (*fini)(void) = dlsym(handle, "qi_fini");
+    assert(fini != NULL);
+    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) < 0) {
+        return INSTR_UNLOAD_DL;
+    }
+
+    handle = NULL;
+#endif
+
+    return INSTR_UNLOAD_OK;
+}
+
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+static void *get_event_symbol(TraceEvent *ev, const char *fmt)
+{
+    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, 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
+
+bool instr_event_set(TraceEvent *ev, void *cb)
+{
+    assert(instr_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(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
+}
diff --git a/instrument/control.h b/instrument/control.h
new file mode 100644
index 0000000..c917eb1
--- /dev/null
+++ b/instrument/control.h
@@ -0,0 +1,133 @@
+/*
+ * Interface for controlling dynamic trace instrumentation.
+ *
+ * Copyright (C) 2012 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 "trace/generated-events.h"
+
+
+/**
+ * InstrLoadError:
+ * @INSTR_LOAD_OK: Correctly loaded.
+ * @INSTR_LOAD_UNAVAILABLE: Service not available.
+ * @INSTR_LOAD_LOADED: Already loaded.
+ * @INSTR_LOAD_DL: Error with libdl (see dlerror).
+ *
+ * Error codes for instr_load().
+ */
+typedef enum {
+    INSTR_LOAD_OK,
+    INSTR_LOAD_UNAVAILABLE,
+    INSTR_LOAD_LOADED,
+    INSTR_LOAD_DL,
+} InstrLoadError;
+
+/**
+ * InstrUnloadError:
+ * @INSTR_UNLOAD_OK: Correctly unloaded.
+ * @INSTR_UNLOAD_UNAVAILABLE: Service not available.
+ * @INSTR_UNLOAD_UNLOADED: Already unloaded.
+ * @INSTR_UNLOAD_DL: Error with libdl (see dlerror).
+ *
+ * Error codes for instr_unload().
+ */
+typedef enum {
+    INSTR_UNLOAD_OK,                   /*< Correctly unloaded             */
+    INSTR_UNLOAD_UNAVAILABLE,          /*< Service not available          */
+    INSTR_UNLOAD_UNLOADED,             /*< Already unloaded               */
+    INSTR_UNLOAD_DL,                   /*< Error with libdl (see dlerror) */
+} InstrUnloadError;
+
+/**
+ * instr_load:
+ * @path: Path to the shared library to load.
+ * @args: String passed to the initialization function of the library.
+ *
+ * Load a dynamic trace instrumentation library.
+ *
+ * Returns: Whether the library could be loaded.
+ */
+InstrLoadError instr_load(const char * path, const char * args);
+
+/**
+ * instr_unload:
+ *
+ * Unload the currently loaded instrumentation library.
+ *
+ * Returns: Whether the library could be unloaded.
+ */
+InstrUnloadError instr_unload(void);
+
+
+/**
+ * instr_dynamic:
+ *
+ * Returns: Whether dynamic trace instrumentation is available.
+ */
+static bool instr_dynamic(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_dynamic() == true
+ * 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/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 e8de5a6..5125a16 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(const char *args);',
+        '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 5a067b8..1f5520f 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(const char *args);',
+        '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 73b080d..ea23dce 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 fb5629b..813f692 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_NONE)
+    const bool instr;
+#endif
+
 #if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
     void **instr_cb;
     void *instr_cb_nop;

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 11/22] instrument: [hmp] Add control interface
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (9 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 10/22] instrument: Add internal control interface Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 12/22] qapi: Add a primitive to include other files from a QAPI schema file Lluís Vilanova
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 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 |    2 +
 instrument/hmp.c         |   65 ++++++++++++++++++++++++++++++++++++++++++++++
 instrument/hmp.h         |   21 +++++++++++++++
 monitor.c                |    1 +
 6 files changed, 132 insertions(+)
 create mode 100644 instrument/hmp.c
 create mode 100644 instrument/hmp.h

diff --git a/Makefile.objs b/Makefile.objs
index fd6779e..cc4f43e 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -102,6 +102,7 @@ common-obj-y += disas/
 
 util-obj-y += instrument/
 target-obj-y += instrument/
+common-obj-y += instrument/
 
 ######################################################################
 # guest agent
diff --git a/hmp-commands.hx b/hmp-commands.hx
index cef7708..6cce724 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1650,6 +1650,48 @@ STEXI
 show available trace events and their state
 ETEXI
 
+    {
+        .name       = "instr-dynamic",
+        .args_type  = "",
+        .params     = "",
+        .help       = "whether dynamic trace instrumentation is available",
+        .mhandler.cmd = hmp_instr_dynamic,
+    },
+
+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 a dynamic instrumentation library",
+        .mhandler.cmd = hmp_instr_load,
+    },
+
+STEXI
+@item instr-load @var{path} [name=value[,...]]
+@findex instr-load
+Load a dynamic instrumentation library.
+ETEXI
+
+    {
+        .name       = "instr-unload",
+        .args_type  = "",
+        .params     = "",
+        .help       = "unload the current dynamic instrumentation library",
+        .mhandler.cmd = hmp_instr_unload,
+    },
+
+STEXI
+@item instr-unload
+@findex instr-unload
+Unload the current dynamic instrumentation library.
+ETEXI
+
 STEXI
 @end table
 ETEXI
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 0d3b70b..adae4a9 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -65,3 +65,5 @@ endif
 # Control code
 
 target-obj-y += control.o
+
+common-obj-$(CONFIG_SOFTMMU) += hmp.o
diff --git a/instrument/hmp.c b/instrument/hmp.c
new file mode 100644
index 0000000..82fdcd7
--- /dev/null
+++ b/instrument/hmp.c
@@ -0,0 +1,65 @@
+/*
+ * HMP interface for dynamic trace instrumentation control commands.
+ *
+ * Copyright (C) 2012 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 "instrument/control.h"
+
+
+void hmp_instr_dynamic(Monitor *mon, const QDict *qdict)
+{
+    monitor_printf(mon, instr_dynamic() ? "true\n" : "false\n");
+}
+
+void hmp_instr_load(Monitor *mon, const QDict *qdict)
+{
+    /* @todo: Unify with qerror messages? */
+
+    const char *path = qdict_get_try_str(qdict, "path");
+    const char *args = qdict_get_try_str(qdict, "args");
+    InstrLoadError err = instr_load(path, args);
+    switch (err) {
+    case INSTR_LOAD_OK:
+        monitor_printf(mon, "OK\n");
+        break;
+    case INSTR_LOAD_UNAVAILABLE:
+        monitor_printf(mon, "Not available\n");
+        break;
+    case INSTR_LOAD_LOADED:
+        monitor_printf(mon, "Already loaded\n");
+        break;
+    case INSTR_LOAD_DL:
+        monitor_printf(mon, "Error loading library: %s\n", dlerror());
+        break;
+    }
+}
+
+void hmp_instr_unload(Monitor *mon, const QDict *qdict)
+{
+    /* @todo: Unify with qerror messages? */
+
+    InstrLoadError err = instr_unload();
+    switch (err) {
+    case INSTR_UNLOAD_OK:
+        monitor_printf(mon, "OK\n");
+        break;
+    case INSTR_UNLOAD_UNAVAILABLE:
+        monitor_printf(mon, "Not available\n");
+        break;
+    case INSTR_UNLOAD_UNLOADED:
+        monitor_printf(mon, "Already unloaded\n");
+        break;
+    case INSTR_UNLOAD_DL:
+        monitor_printf(mon, "Error unloading library: %s\n", dlerror());
+        break;
+    }
+}
diff --git a/instrument/hmp.h b/instrument/hmp.h
new file mode 100644
index 0000000..b7d56dd
--- /dev/null
+++ b/instrument/hmp.h
@@ -0,0 +1,21 @@
+/*
+ * HMP interface for dynamic trace instrumentation control commands.
+ *
+ * Copyright (C) 2012 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_dynamic(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 2fff049..de4403d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -68,6 +68,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] 31+ messages in thread

* [Qemu-devel] [PATCH 12/22] qapi: Add a primitive to include other files from a QAPI schema file
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (10 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 11/22] instrument: [hmp] Add " Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 13/22] [trivial] Set the input root directory when parsing QAPI files Lluís Vilanova
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 UTC (permalink / raw)
  To: qemu-devel

Adds the "input(...)" 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..2d444d9 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
 
+input_cre = re.compile("\s*input\(\"([^\"]*)\"\)")
+
 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 = input_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] 31+ messages in thread

* [Qemu-devel] [PATCH 13/22] [trivial] Set the input root directory when parsing QAPI files
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (11 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 12/22] qapi: Add a primitive to include other files from a QAPI schema file Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 14/22] instrument: [qmp, qapi] Add control interface Lluís Vilanova
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 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 6d49378..9137b31 100644
--- a/Makefile
+++ b/Makefile
@@ -204,13 +204,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] 31+ messages in thread

* [Qemu-devel] [PATCH 14/22] instrument: [qmp, qapi] Add control interface
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (12 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 13/22] [trivial] Set the input root directory when parsing QAPI files Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:52   ` Eric Blake
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 15/22] Let makefiles add entries to the set of target architecture objects Lluís Vilanova
                   ` (8 subsequent siblings)
  22 siblings, 1 reply; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 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>
---
 include/qapi/qmp/qerror.h   |    9 +++++
 instrument/Makefile.objs    |    1 +
 instrument/qapi-schema.json |   33 ++++++++++++++++++++
 instrument/qmp.c            |   59 ++++++++++++++++++++++++++++++++++++
 qapi-schema.json            |    2 +
 qmp-commands.hx             |   71 +++++++++++++++++++++++++++++++++++++++++++
 qmp.c                       |    4 ++
 7 files changed, 179 insertions(+)
 create mode 100644 instrument/qapi-schema.json
 create mode 100644 instrument/qmp.c

diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 6c0a18d..67b4528 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -129,6 +129,15 @@ void assert_no_error(Error *err);
 #define QERR_FEATURE_DISABLED \
     ERROR_CLASS_GENERIC_ERROR, "The feature '%s' is not enabled"
 
+#define QERR_INSTR_LOAD_DL \
+    ERROR_CLASS_GENERIC_ERROR, "Error loading dynamic library: %s"
+
+#define QERR_INSTR_LOAD_LOADED \
+    ERROR_CLASS_GENERIC_ERROR, "Already loaded"
+
+#define QERR_INSTR_LOAD_UNLOADED \
+    ERROR_CLASS_GENERIC_ERROR, "Already unloaded"
+
 #define QERR_INVALID_BLOCK_FORMAT \
     ERROR_CLASS_GENERIC_ERROR, "Invalid block format '%s'"
 
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index adae4a9..ad9ca6d 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -67,3 +67,4 @@ endif
 target-obj-y += control.o
 
 common-obj-$(CONFIG_SOFTMMU) += hmp.o
+common-obj-$(CONFIG_SOFTMMU) += qmp.o
diff --git a/instrument/qapi-schema.json b/instrument/qapi-schema.json
new file mode 100644
index 0000000..bf970f6
--- /dev/null
+++ b/instrument/qapi-schema.json
@@ -0,0 +1,33 @@
+# *-*- Mode: Python -*-*
+
+##
+# @instr-dynamic:
+#
+# Whether dynamic trace instrumentation is available.
+#
+# Since: 1.4
+##
+{ 'command': 'instr-dynamic',
+  'returns': 'bool' }
+
+##
+# @instr-load:
+#
+# Load a dynamic instrumentation library.
+#
+# @path: path to the dynamic instrumentation library
+# @args: arguments to the dynamic instrumentation library
+#
+# Since: 1.4
+##
+{ 'command': 'instr-load',
+  'data':    { 'path': 'str', 'args_': 'str' } }
+
+##
+# @instr-unload:
+#
+# Unload the current dynamic instrumentation library.
+#
+# Since: 1.4
+##
+{ 'command': 'instr-unload' }
diff --git a/instrument/qmp.c b/instrument/qmp.c
new file mode 100644
index 0000000..2c369aa
--- /dev/null
+++ b/instrument/qmp.c
@@ -0,0 +1,59 @@
+/*
+ * QMP interface for dynamic trace instrumentation control commands.
+ *
+ * Copyright (C) 2012 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"
+
+
+
+bool qmp_instr_dynamic(Error **errp)
+{
+    return instr_dynamic();
+}
+
+void qmp_instr_load(const char * path, const char *args, Error **errp)
+{
+    InstrLoadError err = instr_load(path, args);
+    switch (err) {
+    case INSTR_LOAD_OK:
+        break;
+    case INSTR_LOAD_UNAVAILABLE:
+        error_set(errp, QERR_UNSUPPORTED);
+        break;
+    case INSTR_LOAD_LOADED:
+        error_set(errp, QERR_INSTR_LOAD_LOADED);
+        break;
+    case INSTR_LOAD_DL:
+        error_set(errp, QERR_INSTR_LOAD_DL, dlerror());
+        break;
+    }
+}
+
+void qmp_instr_unload(Error **errp)
+{
+    InstrLoadError err = instr_unload();
+    switch (err) {
+    case INSTR_UNLOAD_OK:
+        break;
+    case INSTR_UNLOAD_UNAVAILABLE:
+        error_set(errp, QERR_UNSUPPORTED);
+        break;
+    case INSTR_UNLOAD_UNLOADED:
+        error_set(errp, QERR_INSTR_LOAD_UNLOADED);
+        break;
+    case INSTR_UNLOAD_DL:
+        error_set(errp, QERR_INSTR_LOAD_DL, dlerror());
+        break;
+    }
+}
diff --git a/qapi-schema.json b/qapi-schema.json
index 28b070f..1c8ba7d 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -2360,6 +2360,8 @@
 ##
 { 'command': 'device_del', 'data': {'id': 'str'} }
 
+input("instrument/qapi-schema.json")
+
 ##
 # @dump-guest-memory
 #
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 799adea..f704221 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1488,6 +1488,77 @@ Notes:
     o Commands that prompt the user for data (eg. 'cont' when the block
       device is encrypted) don't currently work
 
+instr-dynamic
+-------------
+
+Whether dynamic trace instrumentation is available.
+
+Arguments: None.
+
+Example:
+
+-> { "execute": "instr-dyanmic" }
+<- { "return": true }
+
+EQMP
+
+    {
+        .name       = "instr-dynamic",
+        .args_type  = "",
+        .mhandler.cmd_new = qmp_marshal_input_instr_dynamic,
+    },
+
+
+SQMP
+
+instr-load
+----------
+
+Load a dynamic instrumentation library.
+
+Arguments:
+
+- path: path to the dynamic instrumentation library
+
+Example:
+
+-> { "execute": "instr-load", "arguments": { "path": "/tmp/libtrace-instrument.so" } }
+<- { "return": {} }
+
+EQMP
+
+    {
+        .name       = "instr-load",
+        .args_type  = "path:s",
+        .params     = "path",
+        .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] 31+ messages in thread

* [Qemu-devel] [PATCH 15/22] Let makefiles add entries to the set of target architecture objects
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (13 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 14/22] instrument: [qmp, qapi] Add control interface Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 16/22] instrument: Add commandline options to start with an instrumentation library Lluís Vilanova
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 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 a26f2ca..03c2f2a 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -148,6 +148,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] 31+ messages in thread

* [Qemu-devel] [PATCH 16/22] instrument: Add commandline options to start with an instrumentation library
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (14 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 15/22] Let makefiles add entries to the set of target architecture objects Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:59   ` Eric Blake
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 17/22] instrument: Add client-side API to enumerate events Lluís Vilanova
                   ` (6 subsequent siblings)
  22 siblings, 1 reply; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 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          |   24 ++++++++++++
 bsd-user/syscall.c       |    5 ++
 instrument/Makefile.objs |    2 +
 instrument/cmdline.c     |   94 ++++++++++++++++++++++++++++++++++++++++++++++
 instrument/cmdline.h     |   41 ++++++++++++++++++++
 linux-user/main.c        |   29 ++++++++++++++
 linux-user/syscall.c     |    4 ++
 qemu-options.hx          |   18 +++++++++
 qmp-commands.hx          |    5 +-
 vl.c                     |   36 ++++++++++++++++++
 10 files changed, 256 insertions(+), 2 deletions(-)
 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..2facee0 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -33,6 +33,8 @@
 #include "tcg.h"
 #include "qemu/timer.h"
 #include "qemu/envlist.h"
+#include "instrument/cmdline.h"
+
 
 int singlestep;
 #if defined(CONFIG_USE_GUEST_BASE)
@@ -688,6 +690,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-args string\n"
+           "                  arguments to dynamic trace instrumentation library\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 +754,8 @@ int main(int argc, char **argv)
     char **target_environ, **wrk;
     envlist_t *envlist = NULL;
     bsd_type = target_openbsd;
+    char *instrument_path = NULL;
+    char *instrument_args = NULL;
 
     if (argc <= 1)
         usage();
@@ -852,6 +865,14 @@ int main(int argc, char **argv)
             singlestep = 1;
         } else if (!strcmp(r, "strace")) {
             do_strace = 1;
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+        } else if (!strcmp(r, "instr")) {
+            instrument_path = argv[optind++];
+#endif
+#if defined(CONFIG_TRACE_INSTRUMENT)
+        } else if (!strcmp(r, "instr-args")) {
+            instrument_args = argv[optind++];
+#endif
         } else
         {
             usage();
@@ -1135,6 +1156,9 @@ int main(int argc, char **argv)
         gdbserver_start (gdbstub_port);
         gdb_handlesig(env, 0);
     }
+
+    instr_init(instrument_path, instrument_args);
+
     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 ad9ca6d..9c7ea5c 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -64,6 +64,8 @@ endif
 ######################################################################
 # Control code
 
+target-obj-y += cmdline.o
+
 target-obj-y += control.o
 
 common-obj-$(CONFIG_SOFTMMU) += hmp.o
diff --git a/instrument/cmdline.c b/instrument/cmdline.c
new file mode 100644
index 0000000..eda6b9c
--- /dev/null
+++ b/instrument/cmdline.c
@@ -0,0 +1,94 @@
+/*
+ * Control dynamic trace instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012 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 bool loaded = false;
+
+
+void instr_init(const char *path, const char *args)
+{
+    if (atexit(instr_fini) != 0) {
+        fprintf(stderr, "error: atexit: %s\n", strerror(errno));
+        abort();
+    }
+
+    if (path == NULL) {
+#if defined(CONFIG_TRACE_INSTRUMENT_STATIC)
+        loaded = true;
+        qi_init(args);
+#endif
+        return;
+    }
+
+    InstrLoadError err = instr_load(path, args);
+    switch (err) {
+    case INSTR_LOAD_OK:
+        loaded = true;
+        return;
+    case INSTR_LOAD_UNAVAILABLE:
+        fprintf(stderr, "error: instrument: not available\n");
+        break;
+    case INSTR_LOAD_LOADED:
+        fprintf(stderr, "error: instrument: already loaded\n");
+        break;
+    case INSTR_LOAD_DL:
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+        fprintf(stderr, "error: instrument: error loading library: %s\n", dlerror());
+#else
+        abort();
+#endif
+        break;
+    }
+
+    exit(-1);
+}
+
+void instr_fini(void)
+{
+    if (!loaded) {
+        return;
+    }
+
+#if defined(CONFIG_TRACE_INSTRUMENT_STATIC)
+    qi_fini();
+    return;
+#endif
+
+    InstrUnloadError err = instr_unload();
+    switch (err) {
+    case INSTR_UNLOAD_OK:
+        return;
+    case INSTR_UNLOAD_UNAVAILABLE:
+        fprintf(stderr, "error: not available\n");
+        break;
+    case INSTR_UNLOAD_UNLOADED:
+        /* the user might have already unloaded it */
+        return;
+    case INSTR_UNLOAD_DL:
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+        fprintf(stderr, "error: error unloading library: %s\n", dlerror());
+#else
+        abort();
+#endif
+        break;
+    }
+
+    exit(-1);
+}
diff --git a/instrument/cmdline.h b/instrument/cmdline.h
new file mode 100644
index 0000000..23bee5e
--- /dev/null
+++ b/instrument/cmdline.h
@@ -0,0 +1,41 @@
+/*
+ * Control dynamic trace instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012 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_init:
+ * @path: Path to dynamic trace instrumentation library.
+ * @args: Arbitrary string to pass 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, const char *args);
+
+/**
+ * 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 29845f9..5ef766e 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -34,6 +34,8 @@
 #include "qemu/timer.h"
 #include "qemu/envlist.h"
 #include "elf.h"
+#include "instrument/cmdline.h"
+
 
 char *exec_path;
 
@@ -3242,6 +3244,22 @@ static void handle_arg_reserved_va(const char *arg)
 }
 #endif
 
+static const char *instrument_path = NULL;
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+static void handle_arg_instrument(const char *arg)
+{
+    instrument_path = arg;
+}
+#endif
+
+static const char *instrument_args = NULL;
+#if defined(CONFIG_TRACE_INSTRUMENT)
+static void handle_arg_instrument_args(const char *arg)
+{
+    instrument_args = arg;
+}
+#endif
+
 static void handle_arg_singlestep(const char *arg)
 {
     singlestep = 1;
@@ -3293,6 +3311,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-args",  "QEMU_INSTR_ARGS", true,  handle_arg_instrument_args,
+     "string",     "arguments to dynamic trace instrumentation library"},
+#endif
     {"d",          "QEMU_LOG",         true,  handle_arg_log,
      "item[,...]", "enable logging of specified items "
      "(use '-d help' for a list of items)"},
@@ -3978,6 +4004,9 @@ int main(int argc, char **argv, char **envp)
         }
         gdb_handlesig(env, 0);
     }
+
+    instr_init(instrument_path, instrument_args);
+
     cpu_loop(env);
     /* never exits */
     return 0;
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 19630ea..f35d421 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -106,6 +106,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 | \
@@ -5230,6 +5232,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;
@@ -7001,6 +7004,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 797d992..7c7e35b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -2942,6 +2942,24 @@ the @var{simple} tracing backend.
 @end table
 ETEXI
 
+DEF("instr", HAS_ARG, QEMU_OPTION_instr,
+    "-instr file=<file>[,args=<string>]\n"
+    "                load an instrumentation library\n",
+    QEMU_ARCH_ALL)
+STEXI
+@item -instr file=@var{file}[,args=@var{args}]
+@findex -instr
+
+Load a dynamic trace instrumentation library.
+
+@table @option
+@item file=@var{file}
+Load the given dynamic trace instrumentation library.
+@item args=@var{string}
+An arbitrary string passed as the argument to the library's @code{qi_init} routine.
+@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/qmp-commands.hx b/qmp-commands.hx
index f704221..d86d15c 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1519,6 +1519,7 @@ Load a dynamic instrumentation library.
 Arguments:
 
 - path: path to the dynamic instrumentation library
+- args: arguments to the dynamic instrumentation library
 
 Example:
 
@@ -1529,8 +1530,8 @@ EQMP
 
     {
         .name       = "instr-load",
-        .args_type  = "path:s",
-        .params     = "path",
+        .args_type  = "path:F,args:s?",
+        .params     = "path args",
         .mhandler.cmd_new = qmp_marshal_input_instr_load,
     },
 
diff --git a/vl.c b/vl.c
index febd2ea..90a3b39 100644
--- a/vl.c
+++ b/vl.c
@@ -162,6 +162,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"
@@ -349,6 +350,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 = "args",
+            .type = QEMU_OPT_STRING,
+        },
+        { /* end of list */ }
+    },
+};
+
 static QemuOptsList qemu_option_rom_opts = {
     .name = "option-rom",
     .implied_opt_name = "romfile",
@@ -2837,6 +2854,8 @@ int main(int argc, char **argv, char **envp)
     };
     const char *trace_events = NULL;
     const char *trace_file = NULL;
+    const char *instrument_path = NULL;
+    const char *instrument_args = NULL;
 
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
@@ -2862,6 +2881,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);
@@ -3747,6 +3767,20 @@ 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);
+                }
+                instrument_path = qemu_opt_get(opts, "file");
+                instrument_args = qemu_opt_get(opts, "args");
+                break;
+            }
             case QEMU_OPTION_readconfig:
                 {
                     int ret = qemu_read_config_file(optarg);
@@ -4334,6 +4368,8 @@ int main(int argc, char **argv, char **envp)
         }
     }
 
+    instr_init(instrument_path, instrument_args);
+
     if (incoming) {
         Error *local_err = NULL;
         qemu_start_incoming_migration(incoming, &local_err);

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 17/22] instrument: Add client-side API to enumerate events
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (15 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 16/22] instrument: Add commandline options to start with an instrumentation library Lluís Vilanova
@ 2013-03-26 14:01 ` Lluís Vilanova
  2013-03-26 14:02 ` [Qemu-devel] [PATCH 18/22] instrument: Add client-side API to control tracing state of events Lluís Vilanova
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:01 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    |   48 ++++++++++
 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, 361 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 a46e490..a7c66d4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,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 9137b31..feb395c 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 e1ac5ff..624dce4 100755
--- a/configure
+++ b/configure
@@ -290,6 +290,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 9c7ea5c..40a2b81 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -40,6 +40,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)
@@ -70,3 +79,7 @@ target-obj-y += control.o
 
 common-obj-$(CONFIG_SOFTMMU) += hmp.o
 common-obj-$(CONFIG_SOFTMMU) += qmp.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..10f2b45
--- /dev/null
+++ b/instrument/api-control.c
@@ -0,0 +1,14 @@
+/*
+ * Interface for controlling the state of events.
+ *
+ * Copyright (C) 2012 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_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..5898466
--- /dev/null
+++ b/instrument/qemu-instr/control-internal.h
@@ -0,0 +1,48 @@
+/*
+ * Interface for controlling the state of events.
+ *
+ * Copyright (C) 2012 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 "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);
+}
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
new file mode 100644
index 0000000..f19b4d7
--- /dev/null
+++ b/instrument/qemu-instr/control.h
@@ -0,0 +1,124 @@
+/*
+ * Interface for controlling the state of events.
+ *
+ * Copyright (C) 2012 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_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..b68075d
--- /dev/null
+++ b/instrument/qemu-instr/visibility-internal.h
@@ -0,0 +1,94 @@
+/*
+ * Macros for symbol visibility.
+ *
+ * Copyright (C) 2012 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_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_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 5125a16..74a3565 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 93e57f9..b373992 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 1f5520f..17ce68b 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..c4fd839
--- /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, 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] 31+ messages in thread

* [Qemu-devel] [PATCH 18/22] instrument: Add client-side API to control tracing state of events
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (16 preceding siblings ...)
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 17/22] instrument: Add client-side API to enumerate events Lluís Vilanova
@ 2013-03-26 14:02 ` Lluís Vilanova
  2013-03-26 14:02 ` [Qemu-devel] [PATCH 19/22] instrument: Add client-side API to control event instrumentation Lluís Vilanova
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:02 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 |   27 +++++++++
 instrument/qemu-instr/trace.h          |   91 ++++++++++++++++++++++++++++++++
 4 files changed, 133 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 40a2b81..79b539c 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -81,5 +81,6 @@ common-obj-$(CONFIG_SOFTMMU) += hmp.o
 common-obj-$(CONFIG_SOFTMMU) += qmp.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..ec3a244
--- /dev/null
+++ b/instrument/api-trace.c
@@ -0,0 +1,14 @@
+/*
+ * Interface for controlling the tracing state of events.
+ *
+ * Copyright (C) 2012 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_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..5d23dd7
--- /dev/null
+++ b/instrument/qemu-instr/trace-internal.h
@@ -0,0 +1,27 @@
+/*
+ * Interface for controlling the tracing state of events.
+ *
+ * Copyright (C) 2012 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 "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);
+}
diff --git a/instrument/qemu-instr/trace.h b/instrument/qemu-instr/trace.h
new file mode 100644
index 0000000..1f29f77
--- /dev/null
+++ b/instrument/qemu-instr/trace.h
@@ -0,0 +1,91 @@
+/*
+ * Interface for controlling the tracing state of events.
+ *
+ * Copyright (C) 2012 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_DYNAMIC)
+#include "instrument/qemu-instr/trace-internal.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* QI__TRACE_H */

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 19/22] instrument: Add client-side API to control event instrumentation
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (17 preceding siblings ...)
  2013-03-26 14:02 ` [Qemu-devel] [PATCH 18/22] instrument: Add client-side API to control tracing state of events Lluís Vilanova
@ 2013-03-26 14:02 ` Lluís Vilanova
  2013-03-26 14:02 ` [Qemu-devel] [PATCH 20/22] build: Fix installation of target-dependant files Lluís Vilanova
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:02 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          |   61 ++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+)

diff --git a/instrument/qemu-instr/control-internal.h b/instrument/qemu-instr/control-internal.h
index 5898466..1b4cef9 100644
--- a/instrument/qemu-instr/control-internal.h
+++ b/instrument/qemu-instr/control-internal.h
@@ -8,6 +8,7 @@
  */
 
 #include "trace/control.h"
+#include "instrument/control.h"
 
 
 QI_IDEF QIEvent* qi_ctrl_event_id(QIEventID id)
@@ -35,6 +36,16 @@ QI_IDEF QIEventID qi_ctrl_event_count(void)
     return (QIEventID)trace_event_count();
 }
 
+QI_IDEF bool qi_ctrl_dynamic(void)
+{
+    return instr_dynamic();
+}
+
+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)
@@ -46,3 +57,8 @@ 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);
+}
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
index f19b4d7..eb81716 100644
--- a/instrument/qemu-instr/control.h
+++ b/instrument/qemu-instr/control.h
@@ -96,6 +96,13 @@ QI_IDECL bool qi_ctrl_event_is_pattern(const char *str);
  */
 QI_IDECL QIEventID qi_ctrl_event_count(void);
 
+/**
+ * qi_ctrl_dynamic:
+ *
+ * Returns: Whether dynamic trace instrumentation is available.
+ */
+QI_IDECL bool qi_ctrl_dynamic(void);
+
 
 
 /**
@@ -112,6 +119,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_DYNAMIC)
 #include "instrument/qemu-instr/control-internal.h"

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [Qemu-devel] [PATCH 20/22] build: Fix installation of target-dependant files
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (18 preceding siblings ...)
  2013-03-26 14:02 ` [Qemu-devel] [PATCH 19/22] instrument: Add client-side API to control event instrumentation Lluís Vilanova
@ 2013-03-26 14:02 ` Lluís Vilanova
  2013-03-26 14:02 ` [Qemu-devel] [PATCH 21/22] instrument: Install headers for dynamic instrumentation clients Lluís Vilanova
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:02 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 feb395c..8b0155d 100644
--- a/Makefile
+++ b/Makefile
@@ -339,7 +339,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] 31+ messages in thread

* [Qemu-devel] [PATCH 21/22] instrument: Install headers for dynamic instrumentation clients
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (19 preceding siblings ...)
  2013-03-26 14:02 ` [Qemu-devel] [PATCH 20/22] build: Fix installation of target-dependant files Lluís Vilanova
@ 2013-03-26 14:02 ` Lluís Vilanova
  2013-03-26 14:02 ` [Qemu-devel] [PATCH 22/22] trace: Do not use the word 'new' in event arguments Lluís Vilanova
  2013-04-11  9:07 ` [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Stefan Hajnoczi
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:02 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 8b0155d..c97b66c 100644
--- a/Makefile
+++ b/Makefile
@@ -317,7 +317,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] 31+ messages in thread

* [Qemu-devel] [PATCH 22/22] trace: Do not use the word 'new' in event arguments
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (20 preceding siblings ...)
  2013-03-26 14:02 ` [Qemu-devel] [PATCH 21/22] instrument: Install headers for dynamic instrumentation clients Lluís Vilanova
@ 2013-03-26 14:02 ` Lluís Vilanova
  2013-04-11  9:07 ` [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Stefan Hajnoczi
  22 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 14:02 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>
---
 trace-events |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/trace-events b/trace-events
index a27ae43..be71eb7 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"
@@ -524,7 +524,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] 31+ messages in thread

* Re: [Qemu-devel] [PATCH 07/22] linux-user: Use absolute include path
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 07/22] linux-user: Use absolute include path Lluís Vilanova
@ 2013-03-26 14:06   ` Peter Maydell
  2013-03-26 15:15     ` Lluís Vilanova
  0 siblings, 1 reply; 31+ messages in thread
From: Peter Maydell @ 2013-03-26 14:06 UTC (permalink / raw)
  To: Lluís Vilanova; +Cc: qemu-devel

On 26 March 2013 14:01, Lluís Vilanova <vilanova@ac.upc.edu> wrote:
> 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.

Something odd here -- linux-headers/ is not for
linux-user mode, it's only needed for system mode (and
specifically for KVM support). Possibly just an error
in the commit message? I think the code change looks OK.

-- PMM

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [PATCH 14/22] instrument: [qmp, qapi] Add control interface
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 14/22] instrument: [qmp, qapi] Add control interface Lluís Vilanova
@ 2013-03-26 14:52   ` Eric Blake
  2013-03-26 15:39     ` Lluís Vilanova
  0 siblings, 1 reply; 31+ messages in thread
From: Eric Blake @ 2013-03-26 14:52 UTC (permalink / raw)
  To: Lluís Vilanova; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 3102 bytes --]

On 03/26/2013 08:01 AM, Lluís Vilanova wrote:
> Add QMP commands to control (un)loading of dynamic instrumentation library.
> 
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
>  include/qapi/qmp/qerror.h   |    9 +++++
>  instrument/Makefile.objs    |    1 +
>  instrument/qapi-schema.json |   33 ++++++++++++++++++++
>  instrument/qmp.c            |   59 ++++++++++++++++++++++++++++++++++++
>  qapi-schema.json            |    2 +
>  qmp-commands.hx             |   71 +++++++++++++++++++++++++++++++++++++++++++
>  qmp.c                       |    4 ++
>  7 files changed, 179 insertions(+)
>  create mode 100644 instrument/qapi-schema.json
>  create mode 100644 instrument/qmp.c
> 

> +++ b/instrument/qapi-schema.json
> @@ -0,0 +1,33 @@
> +# *-*- Mode: Python -*-*
> +
> +##
> +# @instr-dynamic:
> +#
> +# Whether dynamic trace instrumentation is available.
> +#
> +# Since: 1.4

1.5

> +##
> +{ 'command': 'instr-dynamic',
> +  'returns': 'bool' }
> +
> +##
> +# @instr-load:
> +#
> +# Load a dynamic instrumentation library.
> +#
> +# @path: path to the dynamic instrumentation library
> +# @args: arguments to the dynamic instrumentation library

No trailing underscore here...

> +#
> +# Since: 1.4

1.5

> +##
> +{ 'command': 'instr-load',
> +  'data':    { 'path': 'str', 'args_': 'str' } }

...but there is one here.  Something is wrong.  Furthermore, this is
gross - how does the receiver know how to break args into chunks?  This
should be '*args':['str'], taking an optional array of args (omitting is
the same as a 0-length array).

> +##
> +# @instr-unload:
> +#
> +# Unload the current dynamic instrumentation library.
> +#
> +# Since: 1.4

1.5

> +##
> +{ 'command': 'instr-unload' }

Is it possible to load more than one library at a time?  If so, then
instr-load needs to return a handle, and instr-unload needs to take a
handle as an argument.  Also, a query-instr command might be useful for
showing which library (or libraries) are loaded.

> +++ b/instrument/qmp.c
> @@ -0,0 +1,59 @@
> +/*
> + * QMP interface for dynamic trace instrumentation control commands.
> + *
> + * Copyright (C) 2012 Lluís Vilanova <vilanova@ac.upc.edu>

It's 2013, now.

> +++ b/qapi-schema.json
> @@ -2360,6 +2360,8 @@
>  ##
>  { 'command': 'device_del', 'data': {'id': 'str'} }
>  
> +input("instrument/qapi-schema.json")
> +
>  ##
>  # @dump-guest-memory

Unusual placement, having it in the middle of the file in no particular
alphabetic ordering.  I would typically expect to see includes done at
the beginning, or maybe at the end, or at least in alphabetical order
where the 'instr-*' commands would fall (but the file is already messy,
so not entirely your fault).


> +instr-load
> +----------
> +
> +Load a dynamic instrumentation library.
> +
> +Arguments:
> +
> +- path: path to the dynamic instrumentation library

Missing out on args documentation.

-- 
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] 31+ messages in thread

* Re: [Qemu-devel] [PATCH 16/22] instrument: Add commandline options to start with an instrumentation library
  2013-03-26 14:01 ` [Qemu-devel] [PATCH 16/22] instrument: Add commandline options to start with an instrumentation library Lluís Vilanova
@ 2013-03-26 14:59   ` Eric Blake
  0 siblings, 0 replies; 31+ messages in thread
From: Eric Blake @ 2013-03-26 14:59 UTC (permalink / raw)
  To: Lluís Vilanova; +Cc: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 1502 bytes --]

On 03/26/2013 08:01 AM, Lluís Vilanova wrote:
> Add commandline options to control initial loading of dynamic instrumentation
> library.
> 
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---

> +++ b/instrument/cmdline.c
> @@ -0,0 +1,94 @@
> +/*
> + * Control dynamic trace instrumentation during program (de)initialization.
> + *
> + * Copyright (C) 2012 Lluís Vilanova <vilanova@ac.upc.edu>

It's 2013.

> +
> +static bool loaded = false;

Static variables are already 0-initialized; not all compilers can
optimize an explicit 0-initialization into bss, so it is better to omit
'= false'.


> +
> +    exit(-1);

Exiting with status 255 is unusual (twice this patch).

> +++ b/linux-user/main.c
> @@ -34,6 +34,8 @@
>  #include "qemu/timer.h"
>  #include "qemu/envlist.h"
>  #include "elf.h"
> +#include "instrument/cmdline.h"
> +
>  
>  char *exec_path;
>  
> @@ -3242,6 +3244,22 @@ static void handle_arg_reserved_va(const char *arg)
>  }
>  #endif
>  
> +static const char *instrument_path = NULL;

Another case of not needing explicit 0-initialization.

> +++ b/qmp-commands.hx
> @@ -1519,6 +1519,7 @@ Load a dynamic instrumentation library.
>  Arguments:
>  
>  - path: path to the dynamic instrumentation library
> +- args: arguments to the dynamic instrumentation library

This should have been in an earlier patch.

-- 
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] 31+ messages in thread

* Re: [Qemu-devel] [PATCH 07/22] linux-user: Use absolute include path
  2013-03-26 14:06   ` Peter Maydell
@ 2013-03-26 15:15     ` Lluís Vilanova
  0 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 15:15 UTC (permalink / raw)
  To: Peter Maydell; +Cc: qemu-devel

Peter Maydell writes:

> On 26 March 2013 14:01, Lluís Vilanova <vilanova@ac.upc.edu> wrote:
>> 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.

> Something odd here -- linux-headers/ is not for
> linux-user mode, it's only needed for system mode (and
> specifically for KVM support). Possibly just an error
> in the commit message? I think the code change looks OK.

That's right, fixed.


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] 31+ messages in thread

* Re: [Qemu-devel] [PATCH 14/22] instrument: [qmp, qapi] Add control interface
  2013-03-26 14:52   ` Eric Blake
@ 2013-03-26 15:39     ` Lluís Vilanova
  0 siblings, 0 replies; 31+ messages in thread
From: Lluís Vilanova @ 2013-03-26 15:39 UTC (permalink / raw)
  To: Eric Blake; +Cc: qemu-devel

Eric Blake writes:

> On 03/26/2013 08:01 AM, Lluís Vilanova wrote:
>> Add QMP commands to control (un)loading of dynamic instrumentation library.
>> 
>> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
>> ---
>> include/qapi/qmp/qerror.h   |    9 +++++
>> instrument/Makefile.objs    |    1 +
>> instrument/qapi-schema.json |   33 ++++++++++++++++++++
>> instrument/qmp.c            |   59 ++++++++++++++++++++++++++++++++++++
>> qapi-schema.json            |    2 +
>> qmp-commands.hx             |   71 +++++++++++++++++++++++++++++++++++++++++++
>> qmp.c                       |    4 ++
>> 7 files changed, 179 insertions(+)
>> create mode 100644 instrument/qapi-schema.json
>> create mode 100644 instrument/qmp.c
>> 

>> +++ b/instrument/qapi-schema.json
>> @@ -0,0 +1,33 @@
>> +# *-*- Mode: Python -*-*
>> +
>> +##
>> +# @instr-dynamic:
>> +#
>> +# Whether dynamic trace instrumentation is available.
>> +#
>> +# Since: 1.4

> 1.5

>> +##
>> +{ 'command': 'instr-dynamic',
>> +  'returns': 'bool' }
>> +
>> +##
>> +# @instr-load:
>> +#
>> +# Load a dynamic instrumentation library.
>> +#
>> +# @path: path to the dynamic instrumentation library
>> +# @args: arguments to the dynamic instrumentation library

> No trailing underscore here...

>> +#
>> +# Since: 1.4

> 1.5

>> +##
>> +{ 'command': 'instr-load',
>> +  'data':    { 'path': 'str', 'args_': 'str' } }

> ...but there is one here.  Something is wrong.

Maybe there was a problem with using the word "args"? I honestly do not remember
the reason for this, so I'll just remove the underscore.


>  Furthermore, this is
> gross - how does the receiver know how to break args into chunks?  This
> should be '*args':['str'], taking an optional array of args (omitting is
> the same as a 0-length array).

Ha! Looks like I was really lazy when I implemented this... I'll see if I can
find some time to properly implement it and pass an array of strings to the
instrumentation library.


>> +##
>> +# @instr-unload:
>> +#
>> +# Unload the current dynamic instrumentation library.
>> +#
>> +# Since: 1.4

> 1.5

>> +##
>> +{ 'command': 'instr-unload' }

> Is it possible to load more than one library at a time?  If so, then
> instr-load needs to return a handle, and instr-unload needs to take a
> handle as an argument.  Also, a query-instr command might be useful for
> showing which library (or libraries) are loaded.

It's not. Right now you'll get an error if that happens. The rationale behind
this is that for multiple libraries to be supported you would need to implement
an instrumentation "driver" that loops through a list of callbacks, which is
slower than just calling into a single function pointer.

I actually thought about writing an "auto-optimizing" version. The idea was to
assign the client's callback to the per-event pointer if only one library
requested that event, and otherwise assign a pointer to a per-event
auto-generated routine that loops through all assigned callbacks when multiple
clients have registered for that event. But this looked like too much trouble
for an initial implementation.

Besides, a single top-level instrumentation library could then provide an
interface to load multiple "child" libraries, if that is necessary.


>> +++ b/instrument/qmp.c
>> @@ -0,0 +1,59 @@
>> +/*
>> + * QMP interface for dynamic trace instrumentation control commands.
>> + *
>> + * Copyright (C) 2012 Lluís Vilanova <vilanova@ac.upc.edu>

> It's 2013, now.

>> +++ b/qapi-schema.json
>> @@ -2360,6 +2360,8 @@
>> ##
>> { 'command': 'device_del', 'data': {'id': 'str'} }
>> 
>> +input("instrument/qapi-schema.json")
>> +
>> ##
>> # @dump-guest-memory

> Unusual placement, having it in the middle of the file in no particular
> alphabetic ordering.  I would typically expect to see includes done at
> the beginning, or maybe at the end, or at least in alphabetical order
> where the 'instr-*' commands would fall (but the file is already messy,
> so not entirely your fault).

This is probably the result of merges, or that I just changed the
instrumentation command names and did not update the position; thanks.

BTW, I think that this "input" primitive should be used wherever possible to
split the files by subsystem and also have each part in the directory where the
implementation resides.


>> +instr-load
>> +----------
>> +
>> +Load a dynamic instrumentation library.
>> +
>> +Arguments:
>> +
>> +- path: path to the dynamic instrumentation library

> Missing out on args documentation.

Is this one also able to handle a list of strings for "args"?

If so, then I'm just missing how to expose it in the command-line (maybe as an
"accumulable" argument), and we'll be set for having proper argument support.


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] 31+ messages in thread

* Re: [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines
  2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
                   ` (21 preceding siblings ...)
  2013-03-26 14:02 ` [Qemu-devel] [PATCH 22/22] trace: Do not use the word 'new' in event arguments Lluís Vilanova
@ 2013-04-11  9:07 ` Stefan Hajnoczi
  2013-04-11 12:29   ` Lluís Vilanova
  22 siblings, 1 reply; 31+ messages in thread
From: Stefan Hajnoczi @ 2013-04-11  9:07 UTC (permalink / raw)
  To: Lluís Vilanova; +Cc: qemu-devel

On Tue, Mar 26, 2013 at 03:00:21PM +0100, Lluís Vilanova wrote:
> NOTE: Applies on top of the "trace: Generic event state description" series
>       (already in the tracing tree), and is based on revision a4bcea3 from
>       master.
> 
> TODO: Make sure no TCG code is executing during 'instr_unload' (qemu_cpu_kick?
>       tb_lock?)
> 
> 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>
> ---
> 
> Lluís Vilanova (22):
>       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
>       linux-user: Use absolute include path
>       instrument: [static] Call statically linked user-provided routines
>       instrument: [dynamic] Call dynamically linked user-provided routines
>       instrument: Add internal control interface
>       instrument: [hmp] Add control interface
>       qapi: Add a primitive to include other files from a QAPI schema file
>       [trivial] Set the input root directory when parsing QAPI files
>       instrument: [qmp, qapi] 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                                    |   46 ++-
>  Makefile.objs                               |    8 
>  Makefile.target                             |    7 
>  bsd-user/main.c                             |   24 +
>  bsd-user/syscall.c                          |    5 
>  configure                                   |   96 +++++
>  docs/instrumentation.txt                    |  481 +++++++++++++++++++++++++++
>  docs/tracing.txt                            |    9 +
>  hmp-commands.hx                             |   42 ++
>  hw/virtio.c                                 |    1 
>  include/qapi/qmp/qerror.h                   |    9 +
>  include/trace.h                             |    2 
>  instrument/Makefile.objs                    |   86 +++++
>  instrument/api-control.c                    |   14 +
>  instrument/api-trace.c                      |   14 +
>  instrument/cmdline.c                        |   94 +++++
>  instrument/cmdline.h                        |   41 ++
>  instrument/control-internal.h               |   33 ++
>  instrument/control.c                        |  139 ++++++++
>  instrument/control.h                        |  133 +++++++
>  instrument/hmp.c                            |   65 ++++
>  instrument/hmp.h                            |   21 +
>  instrument/qapi-schema.json                 |   33 ++
>  instrument/qemu-instr/control-internal.h    |   64 ++++
>  instrument/qemu-instr/control.h             |  185 ++++++++++
>  instrument/qemu-instr/trace-internal.h      |   27 ++
>  instrument/qemu-instr/trace.h               |   91 +++++
>  instrument/qemu-instr/visibility-internal.h |   94 +++++
>  instrument/qmp.c                            |   59 +++
>  libcacard/Makefile                          |    2 
>  linux-user/main.c                           |   29 ++
>  linux-user/syscall.c                        |    4 
>  monitor.c                                   |    5 
>  qapi-schema.json                            |    2 
>  qemu-options.hx                             |   18 +
>  qmp-commands.hx                             |   72 ++++
>  qmp.c                                       |    4 
>  rules.mak                                   |    3 
>  scripts/qapi-commands.py                    |   10 -
>  scripts/qapi-types.py                       |   10 -
>  scripts/qapi-visit.py                       |   10 -
>  scripts/qapi.py                             |   12 +
>  scripts/tracetool.py                        |   12 +
>  scripts/tracetool/__init__.py               |   26 +
>  scripts/tracetool/backend/dtrace.py         |    4 
>  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         |   11 -
>  scripts/tracetool/backend/stderr.py         |    3 
>  scripts/tracetool/backend/ust.py            |    6 
>  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        |   40 ++
>  scripts/tracetool/format/h.py               |   13 +
>  scripts/tracetool/format/qemu_h.py          |   68 ++++
>  trace-events                                |    8 
>  trace/Makefile.objs                         |   10 -
>  trace/control-internal.h                    |    2 
>  trace/control.c                             |    2 
>  trace/control.h                             |    7 
>  trace/default.c                             |    2 
>  trace/event-internal.h                      |   15 +
>  trace/simple.c                              |    6 
>  trace/simple.h                              |    1 
>  trace/stderr.c                              |    4 
>  vl.c                                        |   36 ++
>  69 files changed, 2670 insertions(+), 52 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

Sorry Lluís, I'm slow with review here again.  Will take a look for 1.4
soft-freeze though.

Stefan

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines
  2013-04-11  9:07 ` [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Stefan Hajnoczi
@ 2013-04-11 12:29   ` Lluís Vilanova
  2013-04-12  8:18     ` Stefan Hajnoczi
  0 siblings, 1 reply; 31+ messages in thread
From: Lluís Vilanova @ 2013-04-11 12:29 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: qemu-devel

Stefan Hajnoczi writes:
[...]
> Sorry Lluís, I'm slow with review here again.  Will take a look for 1.4
> soft-freeze though.

Dont' worry, there's a couple things I have to redo in this series:

* Properly handle qi_init arguments (aka, "qi_init (int argc, char **argv)").
* Rebase on latest master (partially done, needs placing the new changes in the
  appropriate patches).

In any case, I have an incoming deadline now, so I'm not sure how long it will
take me to fix this.

BTW, If you want me to, I can add your mail to Cc.


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] 31+ messages in thread

* Re: [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines
  2013-04-11 12:29   ` Lluís Vilanova
@ 2013-04-12  8:18     ` Stefan Hajnoczi
  0 siblings, 0 replies; 31+ messages in thread
From: Stefan Hajnoczi @ 2013-04-12  8:18 UTC (permalink / raw)
  To: Lluís Vilanova; +Cc: qemu-devel

On Thu, Apr 11, 2013 at 02:29:32PM +0200, Lluís Vilanova wrote:
> Stefan Hajnoczi writes:
> [...]
> > Sorry Lluís, I'm slow with review here again.  Will take a look for 1.4
> > soft-freeze though.
> 
> Dont' worry, there's a couple things I have to redo in this series:
> 
> * Properly handle qi_init arguments (aka, "qi_init (int argc, char **argv)").
> * Rebase on latest master (partially done, needs placing the new changes in the
>   appropriate patches).
> 
> In any case, I have an incoming deadline now, so I'm not sure how long it will
> take me to fix this.
> 
> BTW, If you want me to, I can add your mail to Cc.

Thanks, please CC me.

Stefan

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2013-04-12  8:18 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-26 14:00 [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Lluís Vilanova
2013-03-26 14:00 ` [Qemu-devel] [PATCH 01/22] instrument: Add documentation Lluís Vilanova
2013-03-26 14:00 ` [Qemu-devel] [PATCH 02/22] trace: [simple] Do not include "trace/simple.h" in generated tracer headers Lluís Vilanova
2013-03-26 14:00 ` [Qemu-devel] [PATCH 03/22] trace: Let the user specify her own trace-events file Lluís Vilanova
2013-03-26 14:00 ` [Qemu-devel] [PATCH 04/22] tracetool: Use method 'Event.api' to get the name of public routines Lluís Vilanova
2013-03-26 14:00 ` [Qemu-devel] [PATCH 05/22] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops Lluís Vilanova
2013-03-26 14:00 ` [Qemu-devel] [PATCH 06/22] instrument: [none] Add null instrumentation Lluís Vilanova
2013-03-26 14:01 ` [Qemu-devel] [PATCH 07/22] linux-user: Use absolute include path Lluís Vilanova
2013-03-26 14:06   ` Peter Maydell
2013-03-26 15:15     ` Lluís Vilanova
2013-03-26 14:01 ` [Qemu-devel] [PATCH 08/22] instrument: [static] Call statically linked user-provided routines Lluís Vilanova
2013-03-26 14:01 ` [Qemu-devel] [PATCH 09/22] instrument: [dynamic] Call dynamically " Lluís Vilanova
2013-03-26 14:01 ` [Qemu-devel] [PATCH 10/22] instrument: Add internal control interface Lluís Vilanova
2013-03-26 14:01 ` [Qemu-devel] [PATCH 11/22] instrument: [hmp] Add " Lluís Vilanova
2013-03-26 14:01 ` [Qemu-devel] [PATCH 12/22] qapi: Add a primitive to include other files from a QAPI schema file Lluís Vilanova
2013-03-26 14:01 ` [Qemu-devel] [PATCH 13/22] [trivial] Set the input root directory when parsing QAPI files Lluís Vilanova
2013-03-26 14:01 ` [Qemu-devel] [PATCH 14/22] instrument: [qmp, qapi] Add control interface Lluís Vilanova
2013-03-26 14:52   ` Eric Blake
2013-03-26 15:39     ` Lluís Vilanova
2013-03-26 14:01 ` [Qemu-devel] [PATCH 15/22] Let makefiles add entries to the set of target architecture objects Lluís Vilanova
2013-03-26 14:01 ` [Qemu-devel] [PATCH 16/22] instrument: Add commandline options to start with an instrumentation library Lluís Vilanova
2013-03-26 14:59   ` Eric Blake
2013-03-26 14:01 ` [Qemu-devel] [PATCH 17/22] instrument: Add client-side API to enumerate events Lluís Vilanova
2013-03-26 14:02 ` [Qemu-devel] [PATCH 18/22] instrument: Add client-side API to control tracing state of events Lluís Vilanova
2013-03-26 14:02 ` [Qemu-devel] [PATCH 19/22] instrument: Add client-side API to control event instrumentation Lluís Vilanova
2013-03-26 14:02 ` [Qemu-devel] [PATCH 20/22] build: Fix installation of target-dependant files Lluís Vilanova
2013-03-26 14:02 ` [Qemu-devel] [PATCH 21/22] instrument: Install headers for dynamic instrumentation clients Lluís Vilanova
2013-03-26 14:02 ` [Qemu-devel] [PATCH 22/22] trace: Do not use the word 'new' in event arguments Lluís Vilanova
2013-04-11  9:07 ` [Qemu-devel] [RFC][PATCH 00/22] instrument: Let the user wrap/override specific event tracing routines Stefan Hajnoczi
2013-04-11 12:29   ` Lluís Vilanova
2013-04-12  8:18     ` Stefan Hajnoczi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.