[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v6 09/22] instrument: Add basic control interface
From: |
Lluís Vilanova |
Subject: |
[Qemu-devel] [PATCH v6 09/22] instrument: Add basic control interface |
Date: |
Wed, 13 Sep 2017 13:30:00 +0300 |
User-agent: |
StGit/0.18 |
Signed-off-by: Lluís Vilanova <address@hidden>
---
Makefile | 4 +++
configure | 1 +
include/qemu/compiler.h | 19 ++++++++++++++++
instrument/Makefile.objs | 1 +
instrument/control.c | 28 ++++++++++++++++++++++++
instrument/control.h | 44 +++++++++++++++++++++++++++++++++++++
instrument/control.inc.h | 25 +++++++++++++++++++++
instrument/error.h | 28 ++++++++++++++++++++++++
instrument/events.h | 37 +++++++++++++++++++++++++++++++
instrument/events.inc.h | 11 +++++++++
instrument/load.c | 13 +++++++++++
instrument/qemu-instr/control.h | 46 +++++++++++++++++++++++++++++++++++++++
stubs/instrument.c | 4 +++
13 files changed, 261 insertions(+)
create mode 100644 instrument/control.c
create mode 100644 instrument/control.h
create mode 100644 instrument/control.inc.h
create mode 100644 instrument/error.h
create mode 100644 instrument/events.h
create mode 100644 instrument/events.inc.h
create mode 100644 instrument/qemu-instr/control.h
diff --git a/Makefile b/Makefile
index 3861b3f49c..c3d9a4bcd9 100644
--- a/Makefile
+++ b/Makefile
@@ -599,6 +599,10 @@ ifdef CONFIG_VIRTFS
$(INSTALL_DIR) "$(DESTDIR)$(mandir)/man1"
$(INSTALL_DATA) fsdev/virtfs-proxy-helper.1 "$(DESTDIR)$(mandir)/man1"
endif
+ifdef CONFIG_INSTRUMENT
+ $(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr/"
+ $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/control.h
"$(DESTDIR)$(includedir)/qemu-instr/"
+endif
install-datadir:
$(INSTALL_DIR) "$(DESTDIR)$(qemu_datadir)"
diff --git a/configure b/configure
index 5175151317..18810eae84 100755
--- a/configure
+++ b/configure
@@ -6030,6 +6030,7 @@ if test "$instrument" = "yes"; then
LIBS="-ldl $LIBS"
echo "CONFIG_INSTRUMENT=y" >> $config_host_mak
fi
+QEMU_INCLUDES="-I\$(SRC_PATH)/instrument $QEMU_INCLUDES"
if test "$rdma" = "yes" ; then
echo "CONFIG_RDMA=y" >> $config_host_mak
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
index 340e5fdc09..e86bd34e2c 100644
--- a/include/qemu/compiler.h
+++ b/include/qemu/compiler.h
@@ -111,4 +111,23 @@
#define GCC_FMT_ATTR(n, m)
#endif
+/*
+ * Export symbol to dlopen()'ed libraries'.
+ *
+ * This code is taken from http://gcc.gnu.org/wiki/Visibility.
+ */
+#if defined _WIN32 || defined __CYGWIN__
+ #ifdef __GNUC__
+ #define SYM_PUBLIC __attribute__ ((dllimport))
+ #else
+ #define SYM_PUBLIC __declspec(dllimport)
+ #endif
+#else
+ #if __GNUC__ >= 4
+ #define SYM_PUBLIC __attribute__ ((visibility("default")))
+ #else
+ #define SYM_PUBLIC
+ #endif
+#endif
+
#endif /* COMPILER_H */
diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs
index 7bf4e27e3c..ec76b2080b 100644
--- a/instrument/Makefile.objs
+++ b/instrument/Makefile.objs
@@ -3,3 +3,4 @@
target-obj-$(CONFIG_INSTRUMENT) += cmdline.o
target-obj-$(CONFIG_INSTRUMENT) += load.o
target-obj-$(CONFIG_INSTRUMENT) += qmp.o
+target-obj-$(CONFIG_INSTRUMENT) += control.o
diff --git a/instrument/control.c b/instrument/control.c
new file mode 100644
index 0000000000..3630d6b3be
--- /dev/null
+++ b/instrument/control.c
@@ -0,0 +1,28 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 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.
+ */
+
+#include "instrument/control.h"
+#include "instrument/error.h"
+#include "instrument/events.h"
+#include "instrument/load.h"
+#include "instrument/qemu-instr/control.h"
+#include "qemu/compiler.h"
+
+__thread InstrState instr_cur_state;
+
+
+qi_fini_fn instr_event__fini_fn;
+void *instr_event__fini_data;
+
+SYM_PUBLIC void qi_set_fini(qi_fini_fn fn, void *data)
+{
+ ERROR_IF(!instr_get_state(), "called outside instrumentation");
+ instr_set_event(fini_fn, fn);
+ instr_set_event(fini_data, data);
+}
diff --git a/instrument/control.h b/instrument/control.h
new file mode 100644
index 0000000000..f2b085f69b
--- /dev/null
+++ b/instrument/control.h
@@ -0,0 +1,44 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 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.
+ */
+
+#ifndef INSTRUMENT__CONTROL_H
+#define INSTRUMENT__CONTROL_H
+
+
+/**
+ * InstrState:
+ * @INSTR_STATE_DISABLE: Intrumentation API not available.
+ * @INSTR_STATE_ENABLE: Intrumentation API available.
+ *
+ * Instrumentation state of current host thread. Used to ensure instrumentation
+ * clients use QEMU's API only in expected points.
+ */
+typedef enum {
+ INSTR_STATE_DISABLE,
+ INSTR_STATE_ENABLE,
+} InstrState;
+
+/**
+ * instr_set_state:
+ *
+ * Set the instrumentation state of the current host thread.
+ */
+static inline void instr_set_state(InstrState state);
+
+/**
+ * instr_get_state:
+ *
+ * Get the instrumentation state of the current host thread.
+ */
+static inline InstrState instr_get_state(void);
+
+
+#include "instrument/control.inc.h"
+
+#endif /* INSTRUMENT__CONTROL_H */
diff --git a/instrument/control.inc.h b/instrument/control.inc.h
new file mode 100644
index 0000000000..0f649f4caa
--- /dev/null
+++ b/instrument/control.inc.h
@@ -0,0 +1,25 @@
+/*
+ * Control instrumentation during program (de)initialization.
+ *
+ * Copyright (C) 2012-2017 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.
+ */
+
+#include "qemu/atomic.h"
+#include "qemu/compiler.h"
+#include <stdbool.h>
+
+
+extern __thread InstrState instr_cur_state;
+
+static inline void instr_set_state(InstrState state)
+{
+ atomic_store_release(&instr_cur_state, state);
+}
+
+static inline InstrState instr_get_state(void)
+{
+ return atomic_load_acquire(&instr_cur_state);
+}
diff --git a/instrument/error.h b/instrument/error.h
new file mode 100644
index 0000000000..f8d1dd4b16
--- /dev/null
+++ b/instrument/error.h
@@ -0,0 +1,28 @@
+/*
+ * Helpers for controlling errors in instrumentation libraries.
+ *
+ * Copyright (C) 2012-2017 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.
+ */
+
+#ifndef INSTRUMENT_ERROR_H
+#define INSTRUMENT_ERROR_H
+
+#include "qemu/osdep.h"
+#include "qemu/error-report.h"
+
+
+#define _ERROR(msg, args...) \
+ do { \
+ error_report("%s:" msg, __func__, ##args); \
+ } while (0)
+
+#define ERROR_IF(cond, msg, args...) \
+ if (unlikely(cond)) { \
+ _ERROR(msg, ##args); \
+ return; \
+ }
+
+#endif /* INSTRUMENT_ERROR_H */
diff --git a/instrument/events.h b/instrument/events.h
new file mode 100644
index 0000000000..82ad0bd827
--- /dev/null
+++ b/instrument/events.h
@@ -0,0 +1,37 @@
+/*
+ * Internal API for triggering instrumentation events.
+ *
+ * Copyright (C) 2017 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.
+ */
+
+#ifndef INSTRUMENT__EVENTS_H
+#define INSTRUMENT__EVENTS_H
+
+#include "instrument/qemu-instr/control.h"
+
+/**
+ * instr_get_event:
+ *
+ * Get value set by instrumentation library.
+ */
+#define instr_get_event(name) \
+ atomic_load_acquire(&instr_event__ ## name)
+
+/**
+ * instr_get_event:
+ *
+ * Set value from instrumentation library.
+ */
+#define instr_set_event(name, fn) \
+ atomic_store_release(&instr_event__ ## name, fn)
+
+
+extern qi_fini_fn instr_event__fini_fn;
+extern void *instr_event__fini_data;
+
+#include "instrument/events.inc.h"
+
+#endif /* INSTRUMENT__EVENTS_H */
diff --git a/instrument/events.inc.h b/instrument/events.inc.h
new file mode 100644
index 0000000000..8b1ce7fcb2
--- /dev/null
+++ b/instrument/events.inc.h
@@ -0,0 +1,11 @@
+/*
+ * Internal API for triggering instrumentation events.
+ *
+ * Copyright (C) 2017 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.
+ */
+
+
+
diff --git a/instrument/load.c b/instrument/load.c
index af98f4ce38..a01d66a4d4 100644
--- a/instrument/load.c
+++ b/instrument/load.c
@@ -11,6 +11,8 @@
#include "qemu-common.h"
#include <dlfcn.h>
+#include "instrument/control.h"
+#include "instrument/events.h"
#include "instrument/load.h"
#include "qemu/config-file.h"
#include "qemu/error-report.h"
@@ -96,8 +98,11 @@ InstrLoadError instr_load(const char *path, int argc, const
char **argv,
res = INSTR_LOAD_DLERROR;
goto err;
}
+ instr_set_event(fini_fn, NULL);
+ instr_set_state(INSTR_STATE_ENABLE);
main_res = main_cb(argc, argv);
+ instr_set_state(INSTR_STATE_DISABLE);
if (main_res != 0) {
res = INSTR_LOAD_ERROR;
@@ -126,6 +131,14 @@ InstrUnloadError instr_unload(const char *id)
goto out;
}
+ qi_fini_fn fini_fn = instr_get_event(fini_fn);
+ if (fini_fn) {
+ void *fini_data = instr_get_event(fini_data);
+ fini_fn(fini_data);
+ }
+
+ instr_set_event(fini_fn, NULL);
+
/* this should never fail */
if (dlclose(handle->dlhandle) < 0) {
res = INSTR_UNLOAD_DLERROR;
diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/control.h
new file mode 100644
index 0000000000..b841afaa31
--- /dev/null
+++ b/instrument/qemu-instr/control.h
@@ -0,0 +1,46 @@
+/*
+ * Main instrumentation interface for QEMU.
+ *
+ * Copyright (C) 2012-2017 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.
+ */
+
+#ifndef QI__CONTROL_H
+#define QI__CONTROL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include <stddef.h>
+
+
+/**
+ * SECTION:control
+ * @section_id: qi-control
+ * @title: Event control API for QEMU event instrumentation
+ */
+
+typedef void (*qi_fini_fn)(void *arg);
+
+/**
+ * qi_set_fini:
+ * @fn: Finalization function.
+ * @data: Argument to pass to the finalization function.
+ *
+ * Set the function to call when finalizing (unloading) the instrumentation
+ * library.
+ *
+ * NOTE: Calls to printf() might not be shown if the library is unloaded when
+ * QEMU terminates.
+ */
+void qi_set_fini(qi_fini_fn fn, void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* QI__CONTROL_H */
diff --git a/stubs/instrument.c b/stubs/instrument.c
index 292a2cdf26..560844469c 100644
--- a/stubs/instrument.c
+++ b/stubs/instrument.c
@@ -10,6 +10,7 @@
#include "qemu/osdep.h"
#include "instrument/cmdline.h"
+#include "instrument/control.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
@@ -38,3 +39,6 @@ void qmp_instr_unload(const char *id, Error **errp)
{
error_setg(errp, QERR_UNSUPPORTED);
}
+
+
+__thread InstrState instr_cur_state;
- [Qemu-devel] [PATCH v6 00/22] instrument: Add basic event instrumentation, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 01/22] instrument: Add documentation, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 02/22] instrument: Add configure-time flag, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 03/22] instrument: Add generic library loader, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 04/22] instrument: [linux-user] Add command line library loader, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 05/22] instrument: [bsd-user] Add command line library loader, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 06/22] instrument: [softmmu] Add command line library loader, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 07/22] instrument: [qapi] Add library loader, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 08/22] instrument: [hmp] Add library loader, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 09/22] instrument: Add basic control interface,
Lluís Vilanova <=
- [Qemu-devel] [PATCH v6 10/22] instrument: Add support for tracing events, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 11/22] instrument: Track vCPUs, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 12/22] instrument: Add event 'guest_cpu_enter', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 13/22] instrument: Support synchronous modification of vCPU state, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 14/22] exec: Add function to synchronously flush TB on a stopped vCPU, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 15/22] instrument: Add event 'guest_cpu_exit', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 16/22] instrument: Add event 'guest_cpu_reset', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 17/22] trace: Introduce a proper structure to describe memory accesses, Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 18/22] instrument: Add event 'guest_mem_before_trans', Lluís Vilanova, 2017/09/13
- [Qemu-devel] [PATCH v6 19/22] instrument: Add event 'guest_mem_before_exec', Lluís Vilanova, 2017/09/13