[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 10/23] instrument: [dynamic] Call dynamically lin
From: |
Lluís Vilanova |
Subject: |
[Qemu-devel] [PATCH v2 10/23] instrument: [dynamic] Call dynamically linked user-provided routines |
Date: |
Tue, 16 Apr 2013 15:50:47 +0200 |
User-agent: |
StGit/0.16 |
Provides a mechanism to dynamically change the routine invoked by 'trace_*'.
Signed-off-by: Lluís Vilanova <address@hidden>
---
.gitignore | 1
Makefile | 4 +
Makefile.objs | 6 ++
configure | 8 ++-
instrument/Makefile.objs | 11 ++++
libcacard/Makefile | 2 -
scripts/tracetool/__init__.py | 1
scripts/tracetool/backend/instr_dynamic.py | 87 ++++++++++++++++++++++++++++
scripts/tracetool/format/api_c.py | 24 ++++++++
scripts/tracetool/format/events_c.py | 36 +++++++++++-
trace/event-internal.h | 12 ++++
11 files changed, 186 insertions(+), 6 deletions(-)
create mode 100644 scripts/tracetool/backend/instr_dynamic.py
create mode 100644 scripts/tracetool/format/api_c.py
diff --git a/.gitignore b/.gitignore
index 2c9695c..2a0ea2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@ trace/generated-events.h
trace/generated-events.c
libcacard/trace/generated-tracers.c
instrument/generated-tracers.h
+instrument/generated-tracers.c
instrument/qemu-instr/events.h
*-timestamp
*-softmmu
diff --git a/Makefile b/Makefile
index 2d3431a..cf938be 100644
--- a/Makefile
+++ b/Makefile
@@ -36,6 +36,9 @@ GENERATED_HEADERS += qmp-commands.h qapi-types.h qapi-visit.h
GENERATED_SOURCES += qmp-marshal.c qapi-types.c qapi-visit.c
GENERATED_HEADERS += instrument/generated-tracers.h
+ifdef CONFIG_TRACE_INSTRUMENT_DYNAMIC
+GENERATED_SOURCES += instrument/generated-tracers.c
+endif
GENERATED_HEADERS += instrument/qemu-instr/events.h
GENERATED_HEADERS += trace/generated-events.h
@@ -234,6 +237,7 @@ clean:
@# May not be present in GENERATED_HEADERS
rm -f trace/generated-tracers-dtrace.dtrace*
rm -f trace/generated-tracers-dtrace.h*
+ rm -f instrument/generated-tracers.c*
rm -f $(foreach f,$(GENERATED_HEADERS),$(f) $(f)-timestamp)
rm -f $(foreach f,$(GENERATED_SOURCES),$(f) $(f)-timestamp)
rm -rf qapi-generated
diff --git a/Makefile.objs b/Makefile.objs
index e568c01..5f8ea2d 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -91,6 +91,11 @@ common-obj-y += qom/
common-obj-y += disas/
######################################################################
+# instrumentation
+
+tools-obj-y += instrument/
+
+######################################################################
# guest agent
# FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed
@@ -108,5 +113,6 @@ nested-vars += \
util-obj-y \
qga-obj-y \
block-obj-y \
+ tools-obj-y \
common-obj-y
dummy := $(call unnest-vars)
diff --git a/configure b/configure
index 94b9491..41089cc 100755
--- a/configure
+++ b/configure
@@ -1173,7 +1173,7 @@ echo " Available backends:"
$($python "$source_path"/s
echo " --with-trace-file=NAME Full PATH,NAME of file to store traces"
echo " Default:trace-<pid>"
echo " --with-trace-instrument=TYPE"
-echo " Trace instrumentation type (none static;
default: $trace_instrument)"
+echo " Trace instrumentation type (none static
dynamic; default: $trace_instrument)"
echo " --with-trace-instrument-path=PATH"
echo " Directory to build user-provided static trace
event instrumentation library"
echo " --disable-spice disable spice"
@@ -3074,7 +3074,7 @@ fi
##########################################
# Check instrumentation type
case "$trace_instrument" in
-none|static) ;;
+none|static|dynamic) ;;
*) echo "Error: invalid trace instrumentation type: $trace_instrument"
exit 1
;;
@@ -3922,6 +3922,10 @@ if test "$trace_instrument" = "static"; then
echo "TRACETOOL_INSTR_STATIC=--instr-static-path
\"\$(TRACE_INSTRUMENT_PATH)\"" >> $config_host_mak
QEMU_CFLAGS="-I\"$trace_instrument_path\" $QEMU_CFLAGS"
fi
+if test "$trace_instrument" = "dynamic"; then
+ echo "#define QI_TYPE_DYNAMIC 1" >> $config_qi
+ echo "CONFIG_TRACE_INSTRUMENT_DYNAMIC=y" >> $config_host_mak
+fi
##########################################
echo "TOOLS=$tools" >> $config_host_mak
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 4102b59..cae520d 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -17,6 +17,17 @@ ifdef CONFIG_TRACE_INSTRUMENT_STATIC
.PHONY: $(obj)/generated-tracers.h-timestamp
endif
+$(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp
+$(obj)/generated-tracers.c-timestamp: $(TRACE_EVENTS)
$(BUILD_DIR)/config-host.mak
+ $(call quiet-command,$(TRACETOOL) \
+ --format=api-c \
+ --backend=$(TRACE_INSTRUMENT_BACKEND) \
+ < $< > $@," GEN $(patsubst %-timestamp,%,$@)")
+ @cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst
%-timestamp,%,$@)
+
+tools-obj-$(CONFIG_TRACE_INSTRUMENT_DYNAMIC) += generated-tracers.o
+target-obj-$(CONFIG_TRACE_INSTRUMENT_DYNAMIC) += generated-tracers.o
+
######################################################################
# User interface
diff --git a/libcacard/Makefile b/libcacard/Makefile
index c0a5d66..f3f9f28 100644
--- a/libcacard/Makefile
+++ b/libcacard/Makefile
@@ -7,7 +7,7 @@ libcacard-obj-y = $(stub-obj-y) $(libcacard-y)
libcacard-obj-y += util/osdep.o util/cutils.o util/qemu-timer-common.o
util/error.o
libcacard-obj-$(CONFIG_WIN32) += util/oslib-win32.o util/qemu-thread-win32.o
libcacard-obj-$(CONFIG_POSIX) += util/oslib-posix.o util/qemu-thread-posix.o
-libcacard-obj-y += $(filter trace/%, $(util-obj-y))
+libcacard-obj-y += $(filter trace/%, $(util-obj-y)) $(filter instrument/%,
$(util-obj-y))
libcacard-lobj-y=$(patsubst %.o,%.lo,$(libcacard-obj-y))
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 5406a2b..7624982 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -182,6 +182,7 @@ class Event(object):
QI_TRACE_INSTRUMENT = "qi_event_%(name)s"
QI_TRACE_NOP = "qi_event_%(name)s_nop"
QI_TRACE_BACKEND = "qi_event_%(name)s_trace"
+ QI_TRACE_CB = QI_TRACE_NOP
def api(self, fmt = None):
if fmt is None:
diff --git a/scripts/tracetool/backend/instr_dynamic.py
b/scripts/tracetool/backend/instr_dynamic.py
new file mode 100644
index 0000000..a07ee64
--- /dev/null
+++ b/scripts/tracetool/backend/instr_dynamic.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Dynamic instrumentation proxy.
+"""
+
+__author__ = "Lluís Vilanova <address@hidden>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <address@hidden>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "address@hidden"
+
+
+from tracetool import out
+import tracetool.format.qemu_h
+
+
+def qemu_h(events):
+ for e in events:
+ if "instrument" not in e.properties:
+ continue
+
+ out('extern void * %(qi)s_cb;',
+ 'static inline void %(qi)s(%(args)s)',
+ '{',
+ ' ((void (*)(%(argtypes)s))%(qi)s_cb)(%(argnames)s);',
+ '}',
+ qi = e.api(e.QI_TRACE_INSTRUMENT),
+ args = e.args,
+ argnames = ", ".join(e.args.names()),
+ argtypes = ", ".join(e.args.types()),
+ )
+
+ tracetool.format.qemu_h.process_common(events)
+
+
+
+def api_h(events):
+ out('#include <qemu-instr/visibility-internal.h>',
+ '',
+ )
+
+ for e in events:
+ if "instrument" not in e.properties:
+ continue
+
+ out('QI_VPUBLIC void %(qi)s(%(args)s);',
+ 'void %(qi_nop)s(%(args)s);',
+ 'void %(qi_backend)s(%(args)s);',
+ qi = e.api(e.QI_TRACE_INSTRUMENT),
+ qi_nop = e.api(e.QI_TRACE_NOP),
+ qi_backend = e.api(e.QI_TRACE_BACKEND),
+ args = e.args,
+ )
+
+def api_c(events):
+ out('#include "instrument/qemu-instr/events.h"',
+ '',
+ '#include "trace/generated-events.h"',
+ '#include "trace/generated-tracers.h"',
+ '',
+ )
+
+ for e in events:
+ if "instrument" not in e.properties:
+ continue
+
+ out('void %(qi_nop)s(%(args)s)',
+ '{',
+ '}',
+ '',
+ 'void %(qi_backend)s(%(args)s)',
+ '{',
+ ' %(qemu_backend)s(%(argnames)s);',
+ '}',
+ '',
+ 'void * %(qi)s_cb = %(qi_cb)s;',
+ qi = e.api(e.QI_TRACE_INSTRUMENT),
+ qi_nop = e.api(e.QI_TRACE_NOP),
+ qi_backend = e.api(e.QI_TRACE_BACKEND),
+ qi_cb = e.api(e.QI_TRACE_CB),
+ qemu_backend = e.api(e.QEMU_TRACE_BACKEND),
+ args = e.args,
+ argnames = ", ".join(e.args.names()),
+ )
diff --git a/scripts/tracetool/format/api_c.py
b/scripts/tracetool/format/api_c.py
new file mode 100644
index 0000000..3787f5d
--- /dev/null
+++ b/scripts/tracetool/format/api_c.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Generate .c for trace instrumentation clients.
+"""
+
+__author__ = "Lluís Vilanova <address@hidden>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <address@hidden>"
+__license__ = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__ = "address@hidden"
+
+
+from tracetool import out
+
+
+def begin(events):
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '',
+ '#include <stdlib.h>',
+ '',
+ )
diff --git a/scripts/tracetool/format/events_c.py
b/scripts/tracetool/format/events_c.py
index d670ec8..7531c66 100644
--- a/scripts/tracetool/format/events_c.py
+++ b/scripts/tracetool/format/events_c.py
@@ -6,7 +6,7 @@ Generate .c for event description.
"""
__author__ = "Lluís Vilanova <address@hidden>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <address@hidden>"
+__copyright__ = "Copyright 2012-2013, Lluís Vilanova <address@hidden>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -19,17 +19,49 @@ from tracetool import out
def begin(events):
out('/* This file is autogenerated by tracetool, do not edit. */',
'',
+ '#include "config-host.h"',
'#include "trace.h"',
'#include "trace/generated-events.h"',
'#include "trace/control.h"',
'',
)
+ # declarations
+ out('#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)')
+ for e in events:
+ if "instrument" in e.properties:
+ out('void %(nop)s(%(args)s);',
+ 'void %(backend)s(%(args)s);',
+ nop = e.api(e.QI_TRACE_NOP),
+ backend = e.api(e.QI_TRACE_BACKEND),
+ args = e.args,
+ )
+ out('#endif',
+ '',
+ )
+
+ # event state
out('TraceEvent trace_events[TRACE_EVENT_COUNT] = {')
for e in events:
- out(' { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s,
.dstate = 0 },',
+ cb = cb_nop = cb_backend = "NULL"
+
+ if "instrument" in e.properties:
+ cb = "&%s_cb" % e.api(e.QI_TRACE_INSTRUMENT)
+ cb_nop = e.api(e.QI_TRACE_NOP)
+ cb_backend = e.api(e.QI_TRACE_BACKEND)
+
+ out(' { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s,
.dstate = 0,',
+ '#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)',
+ ' .instr_cb = %(cb)s,',
+ ' .instr_cb_nop = %(cb_nop)s,',
+ ' .instr_cb_backend = %(cb_backend)s,',
+ '#endif',
+ ' },',
id = "TRACE_" + e.name.upper(),
+ cb = cb,
+ cb_nop = cb_nop,
+ cb_backend = cb_backend,
name = e.name,
sstate = "TRACE_%s_ENABLED" % e.name.upper(),
)
diff --git a/trace/event-internal.h b/trace/event-internal.h
index b2310d9..aed4050 100644
--- a/trace/event-internal.h
+++ b/trace/event-internal.h
@@ -1,7 +1,7 @@
/*
* Interface for configuring and controlling the state of tracing events.
*
- * Copyright (C) 2012 Lluís Vilanova <address@hidden>
+ * Copyright (C) 2012-2013 Lluís Vilanova <address@hidden>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
@@ -11,6 +11,7 @@
#define TRACE__EVENT_INTERNAL_H
#include "trace/generated-events.h"
+#include "config-host.h"
/**
@@ -19,6 +20,9 @@
* @name: Event name.
* @sstate: Static tracing state.
* @dstate: Dynamic tracing state.
+ * @instr_cb: Instrumentation callback pointer.
+ * @instr_cb_nop: Instrumentation callback pointer to no-operation.
+ * @instr_cb_backend: Instrumentation callback pointer to tracing backend.
*
* Opaque generic description of a tracing event.
*/
@@ -27,6 +31,12 @@ typedef struct TraceEvent {
const char * name;
const bool sstate;
bool dstate;
+
+#if defined(CONFIG_TRACE_INSTRUMENT_DYNAMIC)
+ void **instr_cb;
+ void *instr_cb_nop;
+ void *instr_cb_backend;
+#endif
} TraceEvent;
- [Qemu-devel] [PATCH v2 09/23] build: Add variable 'tools-obj-y' for tool-only files, (continued)
- [Qemu-devel] [PATCH v2 09/23] build: Add variable 'tools-obj-y' for tool-only files, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 08/23] instrument: [static] Call statically linked user-provided routines, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 07/23] system: [linux] Use absolute include path for linux-headers, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 06/23] instrument: [none] Add null instrumentation, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 13/23] qapi: Add a primitive to include other files from a QAPI schema file, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 02/23] trace: [simple] Do not include "trace/simple.h" in generated tracer headers, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 04/23] tracetool: Use method 'Event.api' to get the name of public routines, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 14/23] [trivial] Set the input root directory when parsing QAPI files, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 10/23] instrument: [dynamic] Call dynamically linked user-provided routines,
Lluís Vilanova <=
- [Qemu-devel] [PATCH v2 16/23] Let makefiles add entries to the set of target architecture objects, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 01/23] instrument: Add documentation, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 15/23] instrument: [qmp, qapi] Add control interface, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 03/23] trace: Let the user specify her own trace-events file, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 11/23] instrument: Add internal control interface, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 05/23] trace: Minimize inclusions of "qemu-common.h" to avoid inclusion loops, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 12/23] instrument: [hmp] Add control interface, Lluís Vilanova, 2013/04/16
- [Qemu-devel] [PATCH v2 23/23] trace: Do not use the word 'new' in event arguments, Lluís Vilanova, 2013/04/16