From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 15009161241151010.3473002048611; Mon, 24 Jul 2017 10:08:44 -0700 (PDT) Received: from localhost ([::1]:55992 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZgqV-00007f-Kt for importer@patchew.org; Mon, 24 Jul 2017 13:08:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55666) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZgod-0007Qa-Aj for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:06:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZgoY-0001hq-AP for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:06:41 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:37994) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZgoX-0001gp-PS for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:06:38 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OH6XXf032131; Mon, 24 Jul 2017 19:06:33 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id C65A4176C; Mon, 24 Jul 2017 19:06:27 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:06:26 +0300 Message-Id: <150091598647.30739.2420187318162958941.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OH6XXf032131 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 01/13] instrument: Add documentation X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- docs/devel/tracing.txt | 9 ++ docs/instrumentation.txt | 264 ++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 273 insertions(+) create mode 100644 docs/instrumentation.txt diff --git a/docs/devel/tracing.txt b/docs/devel/tracing.txt index 5768a0b7a2..17fcd12469 100644 --- a/docs/devel/tracing.txt +++ b/docs/devel/tracing.txt @@ -439,3 +439,12 @@ If the translating vCPU has address 0xc1 and code is l= ater executed by vCPU baz_trans cpu=3D0xc1 a=3D0xd3 // at guest code execution baz_exec cpu=3D0xc2 a=3D0xd3 + +=3D=3D=3D "instrument" =3D=3D=3D + +When compiling QEMU with trace instrumentation enabled, the "instrument" +property lets you provide your own implementation for that trace event. Th= is +implementation can override and/or wrap the backend-specific tracing code +(regardless of the tracing backend). + +See "docs/instrumentation.txt" for more information. diff --git a/docs/instrumentation.txt b/docs/instrumentation.txt new file mode 100644 index 0000000000..3d650ed09e --- /dev/null +++ b/docs/instrumentation.txt @@ -0,0 +1,264 @@ +=3D Trace instrumentation =3D + +=3D=3D Introduction =3D=3D + +Trace instrumentation allows users to execute their own code when QEMU rai= ses +one of its tracing events (see "docs/devel/tracing.txt"). This is more eff= icient +than instrumenting events with the "dtrace" backend, since the user will r= un +native instrumentation code and has more options to interact with the dyna= mic +tracing and instrumentation facilities of QEMU. + +When applied to guest code events (i.e., those with the "guest_" prefix, l= ike +guest memory accesses), this turns QEMU into a fairly efficient and guest +architecture-agnostic dynamic binary instrumentation framework. It works o= n all +QEMU-supported architectures, as well as works in both 'user' (standalone +application) and 'system' (full-system emulation) modes. + +Look at the headers installed by QEMU on the "qemu-instr" directory for fu= rther +information beyond this document. + + +=3D=3D Selecting the events to instrument =3D=3D + +You must first select which events must be instrumentable before compiling= QEMU +by prefixing them with the "instrument" property, and removing the "disabl= e" +property if it is present. + +To get the full list of files defining events: + + find /path/to/qemu-source -name trace-events + +To avoid modifying QEMU's sources, you can pass the "--with-instrument-eve= nts" +argument to configure with one event name per line. + + +=3D=3D Instrumenting guest code =3D=3D + +QEMU emulates all guest instructions when executing in TCG mode (as oppose= d to +using native hardware virtualization with KVM). Instructions are decompile= d and +translated into the intermediate TCG language. Then, the TCG compiler tran= slates +TCG code into the native host code that QEMU will execute. + +All events relating to guest code are named "guest_*". In addition, all ev= ents +with the "tcg" property (see "docs/devel/tracing.txt") can be instrumented= at +two levels: + +* Translation + + Raised when generating TCG code (e.g., translate a memory access instruc= tion + from the guest). + + Note: This level only exists for events with the "tcg" property. + +* Execution + + Raised when executing the native host code generated by the TCG compiler + (e.g., execute a memory access instruction from the guest). + + Note: All events without the "tcg" property are raised at execution time + (e.g., CPU hotplug). + +Note: Events with the "tcg" property (e.g., 'guest_mem_before') are intern= ally + translated into two events to differentiate the translation and exec= ution + levels (e.g., 'guest_mem_before_trans' and 'guest_mem_before_exec'). + +Note: All guest events have a "Mode" and "Target" line describing when the= y are + available (e.g., TCG, KVM, etc.). + + +=3D=3D Setting instrumentation callbacks =3D=3D + +Function qi_ctrl_event_set() in "qemu-instr/control.h" can be used to set = the +instrumentation callback on each event to a user-specified function. Header +"qemu-instr/events.h" provides the event identifiers and some pre-defined +callbacks: + +* QI_EVENT_${EVENT} + + Event identifier, passed to functions in "qemu-instr/control.h". + +* qi_event_${event}_nop + + Do nothing. + +* qi_event_${event}_trace + + Trace the event using whatever tracing backend QEMU has been configured = with. + +* qi_event_${event}_gen_exec + + Generate TCG code to raise the corresponding event when the TCG-generate= d code + is executed. Otherwise, the event will not be instrumented at execution = time, + resulting in zero-overhead when executing the guest code. + + Only available for translation-time events. + +* qi_event_${event}_trace_and_gen_exec + + Combines 'qi_event_${event}_trace' and 'qi_event_${event}_gen_exec' in a + single call. + + Only available for translation-time events. + + +=3D=3D Loading an instrumentation library =3D=3D + +There are two ways two load an instrumentation library: + +* Using the command-line "-instr" argument. + +* Using the "instr-load" and "instr-unload" commands in the HMP and QMP + interfaces. + + +=3D=3D=3D Example =3D=3D=3D + +1. Configure QEMU with the selected events to instrument: + + # instrument guest_cpu_enter and guest_mem_before + cat >/tmp/my-events < /tmp/my-instrument/Makefile < /tmp/my-instrument/instrument.c < + #include + =20 + #include /* get event declarations */ + #include /* manipulate events */ + =20 + /* as documented in QEMU's event description */ + struct mem_info { + uint8_t size_shift : 2; + bool sign_extend: 1; + uint8_t endianness : 1; + bool store : 1; + }; + =20 + /* the address for the memory access is not known at translation time = */ + void guest_mem_before_trans(QICPU *cpu, QITCGv_cpu tcg_cpu, + QITCGv vaddr, uint8_t info) + { + struct mem_info *mi =3D (struct mem_info*)&info; + qi_event_guest_mem_before_trans_trace(cpu, tcg_cpu, vaddr, info); + if (mi->store) { + /* generate at execution time only for memory writes */ + qi_event_guest_mem_before_trans_gen_exec(cpu, tcg_cpu, vaddr, = info); + } + } + =20 + /* called when QEMU executes a memory access */ + void guest_mem_before_exec(QICPU *cpu, uint64_t vaddr, uint8_t info) + { + struct mem_info *mi =3D (struct mem_info*)&info; + if (mi->store) { + /* if called by TCG code, we'll only get writes (see above) */ + qi_event_guest_mem_before_exec_trace(cpu, vaddr, info); + } + } + =20 + /* called every time QEMU hotplugs a CPU */ + void guest_cpu_enter(QICPU *cpu) + { + /* call the original tracing routine */ + qi_event_guest_cpu_enter_trace(cpu); + =20 + /* disable instrumentation and tracing after the first call */ + static bool found =3D false; + if (found) { + QIEvent *ev =3D QI_EVENT_GUEST_CPU_ENTER; + qi_ctrl_event_set(ev, NULL); + qi_trace_event_set_state_dynamic(ev, false); + } else { + found =3D true; + } + } + =20 + =20 + /* mandatory initialization callback */ + void qi_init(int argc, const char **argv) + { + int i; + printf("init!\n"); + printf(" argc :: %d\n", argc); + for (i =3D 0; i < argc; i++) { + printf(" -> %s\n", argv[i]); + } + + /* instrument and trace events */ + QIEvent *ev; + + ev =3D QI_EVENT_GUEST_CPU_ENTER; + qi_ctrl_event_set(ev, guest_cpu_enter); + qi_trace_event_set_state_dynamic(ev, true); + =20 + ev =3D QI_EVENT_GUEST_MEM_BEFORE_TRANS; + qi_ctrl_event_set(ev, guest_mem_before_trans); + qi_trace_event_set_state_dynamic(ev, true); + =20 + ev =3D QI_EVENT_GUEST_MEM_BEFORE_EXEC; + qi_ctrl_event_set(ev, guest_mem_before_exec); + qi_trace_event_set_state_dynamic(ev, true); + } + =20 + /* mandatory finalization callback */ + void qi_fini(void) + { + fprintf(stderr, "fini!\n"); + =20 + /* ensure all tracing is disabled */ + qi_trace_event_set_state_dynamic(QI_EVENT_GUEST_CPU_ENTER, false); + qi_trace_event_set_state_dynamic(QI_EVENT_GUEST_MEM_BEFORE_TRANS, = false); + qi_trace_event_set_state_dynamic(QI_EVENT_GUEST_MEM_BEFORE_EXEC, f= alse); + =20 + /* instrumentation callbacks are automatically reset by QEMU */ + } + EOF + +5. Compile the instrumentation library: + + make -C /tmp/my-instrument + +6. Start QEMU with the instrumentation library: + + /tmp/qemu-install/bin/qemu-system-x86_64 \ + -instr file=3D/tmp/my-dinstrument/.libs/libtrace-instrument.so, \ + arg=3Dfoo,arg=3Dbar From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500916537720842.9826202118372; Mon, 24 Jul 2017 10:15:37 -0700 (PDT) Received: from localhost ([::1]:56034 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZgxC-0005LY-3g for importer@patchew.org; Mon, 24 Jul 2017 13:15:34 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:56431) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZgsV-0002Bs-Dw for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:10:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZgsS-0002hk-4R for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:10:43 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:32890) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZgsR-0002hZ-FB for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:10:40 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHAapi032212; Mon, 24 Jul 2017 19:10:36 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 3755C176C; Mon, 24 Jul 2017 19:10:30 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:10:28 +0300 Message-Id: <150091622863.30739.6614221568254084366.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHAapi032212 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 02/13] instrument: [none] Add null instrumentation mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Renames existing tracing routines into "_backend__trace_*", and instead add= s an instrumentation-aware "trace_*". Since we're in a "null" instrumentation mode for tracing events, the new routines simply call the original tracing code. Signed-off-by: Llu=C3=ADs Vilanova --- .gitignore | 3 + Makefile | 26 ++++++++++ Makefile.objs | 4 ++ configure | 8 +++ include/trace-tcg.h | 1=20 instrument/Makefile.objs | 14 ++++++ scripts/tracetool/__init__.py | 6 ++ scripts/tracetool/backend/instr_none.py | 34 +++++++++++++ scripts/tracetool/format/h.py | 8 +++ scripts/tracetool/format/instr_h.py | 48 +++++++++++++++++++ scripts/tracetool/format/instr_tcg_h.py | 56 ++++++++++++++++++= ++++ scripts/tracetool/format/tcg_h.py | 6 +- scripts/tracetool/format/tcg_helper_c.py | 2 - scripts/tracetool/format/tcg_helper_h.py | 2 - scripts/tracetool/format/tcg_helper_wrapper_h.py | 2 - 15 files changed, 210 insertions(+), 10 deletions(-) create mode 100644 instrument/Makefile.objs create mode 100644 scripts/tracetool/backend/instr_none.py create mode 100644 scripts/tracetool/format/instr_h.py create mode 100644 scripts/tracetool/format/instr_tcg_h.py diff --git a/.gitignore b/.gitignore index 09c2363acf..068dc1c1ae 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ /config-target.* /config.status /config-temp +/instrument-root.h +/instrument/generated-tcg-tracers.h /trace-events-all /trace/generated-events.h /trace/generated-events.c @@ -116,6 +118,7 @@ tags TAGS docker-src.* *~ +instrument.h trace.h trace.c trace-ust.h diff --git a/Makefile b/Makefile index 38814f9a61..375bd313d7 100644 --- a/Makefile +++ b/Makefile @@ -191,6 +191,29 @@ trace-dtrace-root.h: trace-dtrace-root.dtrace =20 trace-dtrace-root.o: trace-dtrace-root.dtrace =20 +INSTRUMENT_HEADERS =3D instrument-root.h $(trace-events-subdirs:%=3D%/inst= rument.h) +INSTRUMENT_HEADERS +=3D instrument/generated-tcg-tracers.h + +GENERATED_FILES +=3D $(INSTRUMENT_HEADERS) + +%/instrument.h: %/instrument.h-timestamp + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +%/instrument.h-timestamp: $(SRC_PATH)/%/trace-events $(BUILD_DIR)/config-h= ost.mak $(tracetool-y) + $(call quiet-command,$(TRACETOOL) \ + --group=3D$(call trace-group-name,$@) \ + --format=3Dinstr-h \ + --backends=3D$(TRACE_INSTRUMENT_BACKEND) \ + $< > $@,"GEN","$(@:%-timestamp=3D%)") + +instrument-root.h: instrument-root.h-timestamp + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +instrument-root.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-= host.mak $(tracetool-y) + $(call quiet-command,$(TRACETOOL) \ + --group=3Droot \ + --format=3Dinstr-h \ + --backends=3D$(TRACE_INSTRUMENT_BACKEND) \ + $< > $@,"GEN","$(@:%-timestamp=3D%)") + # Don't try to regenerate Makefile or configure # We don't generate any of them Makefile: ; @@ -806,7 +829,8 @@ endif =20 .SECONDARY: $(TRACE_HEADERS) $(TRACE_HEADERS:%=3D%-timestamp) \ $(TRACE_SOURCES) $(TRACE_SOURCES:%=3D%-timestamp) \ - $(TRACE_DTRACE) $(TRACE_DTRACE:%=3D%-timestamp) + $(TRACE_DTRACE) $(TRACE_DTRACE:%=3D%-timestamp) \ + $(INSTRUMENT_HEADERS) $(INSTRUMENT_HEADERS:%=3D%-timestamp) =20 # Include automatically generated dependency files # Dependencies in Makefile.objs files come from our recursive subdir rules diff --git a/Makefile.objs b/Makefile.objs index bfd5a6ceb1..8e2b3770c4 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -98,6 +98,10 @@ util-obj-y +=3D trace/ target-obj-y +=3D trace/ =20 ###################################################################### +# instrumentation +util-obj-y +=3D instrument/ + +###################################################################### # guest agent =20 # FIXME: a few definitions from qapi-types.o/qapi-visit.o are needed diff --git a/configure b/configure index a3f0522e8f..75d899b40c 100755 --- a/configure +++ b/configure @@ -351,6 +351,8 @@ pie=3D"" qom_cast_debug=3D"yes" trace_backends=3D"log" trace_file=3D"trace" +trace_instrument=3D"no" +trace_instrument_backend=3D"none" spice=3D"" rbd=3D"" smartcard=3D"" @@ -5282,6 +5284,7 @@ echo "Trace backends $trace_backends" if have_backend "simple"; then echo "Trace output file $trace_file-" fi +echo "Trace instrumentation $trace_instrument" echo "spice support $spice $(echo_version $spice $spice_protocol_versi= on/$spice_server_version)" echo "rbd support $rbd" echo "xfsctl support $xfs" @@ -5989,6 +5992,11 @@ else fi QEMU_INCLUDES=3D"-I\$(SRC_PATH)/tcg $QEMU_INCLUDES" =20 +########################################## +# trace instrumentation +echo "TRACE_INSTRUMENT_BACKEND=3Dinstr-$trace_instrument_backend" >> $conf= ig_host_mak +########################################## + echo "TOOLS=3D$tools" >> $config_host_mak echo "ROMS=3D$roms" >> $config_host_mak echo "MAKE=3D$make" >> $config_host_mak diff --git a/include/trace-tcg.h b/include/trace-tcg.h index da68608c85..a626c5020c 100644 --- a/include/trace-tcg.h +++ b/include/trace-tcg.h @@ -2,5 +2,6 @@ #define TRACE_TCG_H =20 #include "trace/generated-tcg-tracers.h" +#include "instrument/generated-tcg-tracers.h" =20 #endif /* TRACE_TCG_H */ diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs new file mode 100644 index 0000000000..d1edd1696e --- /dev/null +++ b/instrument/Makefile.objs @@ -0,0 +1,14 @@ +# -*- mode: makefile -*- + +###################################################################### +# QEMU trace->instrument interface + +$(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-tcg-tracers.h-timestamp: $(SRC_PATH)/trace-events $(BUILD= _DIR)/config-host.mak $(tracetool-y) + @mkdir -p $(dir $@) + $(call quiet-command,$(TRACETOOL) \ + --group=3Droot \ + --format=3Dinstr-tcg-h \ + --backend=3D$(TRACE_INSTRUMENT_BACKEND) \ + $< > $@,"GEN","$(patsubst %-timestamp,%,$@)") diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index d4c204a472..6d382157c0 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -161,7 +161,7 @@ class Event(object): "(?:(?:(?P\".+),)?\s*(?P\".+))?" "\s*") =20 - _VALID_PROPS =3D set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu= "]) + _VALID_PROPS =3D set(["disable", "tcg", "tcg-trans", "tcg-exec", "vcpu= ", "instrument"]) =20 def __init__(self, name, props, fmt, args, orig=3DNone, event_trans=3DNone, event_exec=3DNone): @@ -269,13 +269,15 @@ class Event(object): =20 QEMU_TRACE =3D "trace_%(name)s" QEMU_TRACE_NOCHECK =3D "_nocheck__" + QEMU_TRACE + QEMU_TRACE_BACKEND =3D "_backend__" + QEMU_TRACE QEMU_TRACE_TCG =3D QEMU_TRACE + "_tcg" + QEMU_TRACE_TCG_BACKEND =3D "_backend__" + QEMU_TRACE_TCG QEMU_DSTATE =3D "_TRACE_%(NAME)s_DSTATE" QEMU_EVENT =3D "_TRACE_%(NAME)s_EVENT" =20 def api(self, fmt=3DNone): if fmt is None: - fmt =3D Event.QEMU_TRACE + fmt =3D Event.QEMU_TRACE_BACKEND return fmt % {"name": self.name, "NAME": self.name.upper()} =20 def transform(self, *trans): diff --git a/scripts/tracetool/backend/instr_none.py b/scripts/tracetool/ba= ckend/instr_none.py new file mode 100644 index 0000000000..56508cfcbe --- /dev/null +++ b/scripts/tracetool/backend/instr_none.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +No-instrumentation proxy. +""" + +__author__ =3D "Llu=C3=ADs Vilanova " +__copyright__ =3D "Copyright 2012-2017, Llu=C3=ADs Vilanova " +__license__ =3D "GPL version 2 or (at your option) any later version" + +__maintainer__ =3D "Stefan Hajnoczi" +__email__ =3D "stefanha@linux.vnet.ibm.com" + + +from tracetool import out + + +################################################## +# instr-tcg-h + +def generate_instr_tcg_h(event, group): + out(' %(backend)s(%(argnames)s);', + backend=3Devent.api(event.QEMU_TRACE_TCG_BACKEND), + argnames=3D", ".join(event.args.names())) + + +################################################## +# instr-h + +def generate_instr_h(event, group): + out(' %(backend)s(%(argnames)s);', + backend=3Devent.api(event.QEMU_TRACE_BACKEND), + argnames=3D", ".join(event.args.names())) diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py index aecf249d66..2e423079db 100644 --- a/scripts/tracetool/format/h.py +++ b/scripts/tracetool/format/h.py @@ -87,4 +87,10 @@ def generate(events, backend, group): =20 backend.generate_end(events, group) =20 - out('#endif /* TRACE_%s_GENERATED_TRACERS_H */' % group.upper()) + out('') + if group =3D=3D "root": + out('#include "instrument-root.h"') + else: + out('#include "instrument.h"') + out('', + '#endif /* TRACE_%s_GENERATED_TRACERS_H */' % group.upper()) diff --git a/scripts/tracetool/format/instr_h.py b/scripts/tracetool/format= /instr_h.py new file mode 100644 index 0000000000..2b80b3d038 --- /dev/null +++ b/scripts/tracetool/format/instr_h.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +/instrument-root.h +.../instrument.h + +""" + +__author__ =3D "Llu=C3=ADs Vilanova " +__copyright__ =3D "Copyright 2012-2017, Llu=C3=ADs Vilanova " +__license__ =3D "GPL version 2 or (at your option) any later version" + +__maintainer__ =3D "Stefan Hajnoczi" +__email__ =3D "stefanha@linux.vnet.ibm.com" + + +from tracetool import out +from tracetool.transform import * + + +def generate(events, backend, group): + out('/* This file is autogenerated by tracetool, do not edit. */', + '', + '#ifndef INSTRUMENT_%s_GENERATED_TRACERS_H' % group.upper(), + '#define INSTRUMENT_%s_GENERATED_TRACERS_H' % group.upper(), + '') + backend.generate_begin(events, group) + + for e in events: + out('static inline void %(qemu)s(%(args)s)', + '{', + qemu=3De.api(e.QEMU_TRACE), + args=3De.args) + + if "tcg-trans" in e.properties or "instrument" not in e.properties: + # "*_trans" never called directly (and never instrumented) + out(' %(backend)s(%(argnames)s);', + backend=3De.api(e.QEMU_TRACE_BACKEND), + argnames=3D", ".join(e.args.names())) + else: + backend.generate(e, group) + + out('}') + + backend.generate_end(events, group) + out('', + '#endif /* INSTRUMENT_%s_GENERATED_TRACERS_H */' % group.upper()) diff --git a/scripts/tracetool/format/instr_tcg_h.py b/scripts/tracetool/fo= rmat/instr_tcg_h.py new file mode 100644 index 0000000000..6abf97d368 --- /dev/null +++ b/scripts/tracetool/format/instr_tcg_h.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +instrument/generated-tcg-tracers.h + +""" + +__author__ =3D "Llu=C3=ADs Vilanova " +__copyright__ =3D "Copyright 2012-2017, Llu=C3=ADs Vilanova " +__license__ =3D "GPL version 2 or (at your option) any later version" + +__maintainer__ =3D "Stefan Hajnoczi" +__email__ =3D "stefanha@linux.vnet.ibm.com" + + +from tracetool import out, Arguments +import tracetool.vcpu + + +API =3D True + + +def generate(events, backend, group): + events =3D [e.original for e in events + if "tcg-trans" in e.properties] + + out('/* This file is autogenerated by tracetool, do not edit. */', + '', + '#ifndef INSTRUMENT_%s_GENERATED_TCG_TRACERS_H' % group.upper(), + '#define INSTRUMENT_%s_GENERATED_TCG_TRACERS_H' % group.upper(), + '') + backend.generate_begin(events, group) + + for e in events: + args_api =3D tracetool.vcpu.transform_args("tcg_h", e) + + out('static inline void %(qemu)s(%(args)s)', + '{', + qemu=3De.api(e.QEMU_TRACE_TCG), + args=3Dargs_api) + + if "instrument" in e.properties: + e =3D e.copy() + e.args =3D args_api + backend.generate(e, group) + else: + out(' %(backend)s(%(argnames)s);', + backend=3De.api(e.QEMU_TRACE_TCG_BACKEND), + argnames=3D", ".join(args_api.names())) + + out('}') + + backend.generate_end(events, group) + out('', + '#endif /* INSTRUMENT_%s_GENERATED_TCG_TRACERS_H */' % group.uppe= r()) diff --git a/scripts/tracetool/format/tcg_h.py b/scripts/tracetool/format/t= cg_h.py index 1651cc3f71..3363502ffc 100644 --- a/scripts/tracetool/format/tcg_h.py +++ b/scripts/tracetool/format/tcg_h.py @@ -51,7 +51,7 @@ def generate(events, backend, group): =20 out('static inline void %(name_tcg)s(%(args)s)', '{', - name_tcg=3De.original.api(e.QEMU_TRACE_TCG), + name_tcg=3De.original.api(e.QEMU_TRACE_TCG_BACKEND), args=3Dtracetool.vcpu.transform_args("tcg_h", e.original)) =20 if "disable" not in e.properties: @@ -72,8 +72,8 @@ def generate(events, backend, group): ' if (%(cond)s) {', ' gen_helper_%(name_exec)s(%(argnames_exec)s);', ' }', - name_trans=3De.original.event_trans.api(e.QEMU_TRACE), - name_exec=3De.original.event_exec.api(e.QEMU_TRACE), + name_trans=3De.original.event_trans.api(e.QEMU_TRACE_BACKE= ND), + name_exec=3De.original.event_exec.api(e.QEMU_TRACE_BACKEND= ), argnames_trans=3D", ".join(args_trans.names()), argnames_exec=3D", ".join(args_exec.names()), cond=3Dcond) diff --git a/scripts/tracetool/format/tcg_helper_c.py b/scripts/tracetool/f= ormat/tcg_helper_c.py index bbbd6ad0f4..e9ba62a136 100644 --- a/scripts/tracetool/format/tcg_helper_c.py +++ b/scripts/tracetool/format/tcg_helper_c.py @@ -74,7 +74,7 @@ def generate(events, backend, group): # NOTE: the check was already performed at TCG-generation time ' %(name)s(%(args_call)s);', '}', - name_tcg=3D"helper_%s_proxy" % e.api(), + name_tcg=3D"helper_%s_proxy" % e.api(e.QEMU_TRACE_BACKEND), name=3De.api(e.QEMU_TRACE_NOCHECK), args_api=3De_args_api, args_call=3D", ".join(e_args_call.casted()), diff --git a/scripts/tracetool/format/tcg_helper_h.py b/scripts/tracetool/f= ormat/tcg_helper_h.py index 6b184b641b..17ef0021eb 100644 --- a/scripts/tracetool/format/tcg_helper_h.py +++ b/scripts/tracetool/format/tcg_helper_h.py @@ -44,6 +44,6 @@ def generate(events, backend, group): out(fmt, flags=3Dflags, argc=3Dlen(args), - name=3De.api() + "_proxy", + name=3De.api(e.QEMU_TRACE_BACKEND) + "_proxy", types=3Dtypes, ) diff --git a/scripts/tracetool/format/tcg_helper_wrapper_h.py b/scripts/tra= cetool/format/tcg_helper_wrapper_h.py index ff53447512..377af4615b 100644 --- a/scripts/tracetool/format/tcg_helper_wrapper_h.py +++ b/scripts/tracetool/format/tcg_helper_wrapper_h.py @@ -54,7 +54,7 @@ def generate(events, backend, group): for (type_, name) in args_tcg_compat ] =20 - gen_name =3D "gen_helper_" + e.api() + gen_name =3D "gen_helper_" + e.api(e.QEMU_TRACE_BACKEND) =20 out('static inline void %(name)s(%(args)s)', '{', From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500916558823394.957162713269; Mon, 24 Jul 2017 10:15:58 -0700 (PDT) Received: from localhost ([::1]:56035 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZgxZ-0005bB-Bt for importer@patchew.org; Mon, 24 Jul 2017 13:15:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57232) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZgwQ-0004wW-1D for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:14:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZgwM-0003fW-PR for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:14:46 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:45106) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZgwM-0003fK-4m for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:14:42 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHEdhg032300; Mon, 24 Jul 2017 19:14:39 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 594F8176B; Mon, 24 Jul 2017 19:14:33 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:14:31 +0300 Message-Id: <150091647131.30739.8668633366747555026.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHEdhg032300 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 03/13] instrument: [dynamic] Add dynamic instrumentation mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 This mode uses a function pointer in "trace_*" routines. By default, it poi= nts to the original tracing function (now "_backend__trace_*"). Signed-off-by: Llu=C3=ADs Vilanova --- .gitignore | 3 + Makefile | 26 ++++++++++- Makefile.objs | 4 ++ configure | 9 ++++ instrument/Makefile.objs | 12 +++++ scripts/tracetool/__init__.py | 3 + scripts/tracetool/backend/instr_dynamic.py | 67 ++++++++++++++++++++++++= ++++ scripts/tracetool/format/instr_c.py | 44 ++++++++++++++++++ scripts/tracetool/format/instr_tcg_c.py | 40 +++++++++++++++++ 9 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 scripts/tracetool/backend/instr_dynamic.py create mode 100644 scripts/tracetool/format/instr_c.py create mode 100644 scripts/tracetool/format/instr_tcg_c.py diff --git a/.gitignore b/.gitignore index 068dc1c1ae..ee2768cb05 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,9 @@ /config.status /config-temp /instrument-root.h +/instrument-root.c /instrument/generated-tcg-tracers.h +/instrument/generated-tcg-tracers.c /trace-events-all /trace/generated-events.h /trace/generated-events.c @@ -119,6 +121,7 @@ TAGS docker-src.* *~ instrument.h +instrument.c trace.h trace.c trace-ust.h diff --git a/Makefile b/Makefile index 375bd313d7..fb226bf54b 100644 --- a/Makefile +++ b/Makefile @@ -193,8 +193,11 @@ trace-dtrace-root.o: trace-dtrace-root.dtrace =20 INSTRUMENT_HEADERS =3D instrument-root.h $(trace-events-subdirs:%=3D%/inst= rument.h) INSTRUMENT_HEADERS +=3D instrument/generated-tcg-tracers.h +INSTRUMENT_SOURCES =3D instrument-root.c $(trace-events-subdirs:%=3D%/inst= rument.c) +INSTRUMENT_SOURCES +=3D instrument/generated-tcg-tracers.c =20 GENERATED_FILES +=3D $(INSTRUMENT_HEADERS) +GENERATED_FILES +=3D $(INSTRUMENT_SOURCES) =20 %/instrument.h: %/instrument.h-timestamp @cmp $< $@ >/dev/null 2>&1 || cp $< $@ @@ -205,6 +208,15 @@ GENERATED_FILES +=3D $(INSTRUMENT_HEADERS) --backends=3D$(TRACE_INSTRUMENT_BACKEND) \ $< > $@,"GEN","$(@:%-timestamp=3D%)") =20 +%/instrument.c: %/instrument.c-timestamp + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +%/instrument.c-timestamp: $(SRC_PATH)/%/trace-events $(BUILD_DIR)/config-h= ost.mak $(tracetool-y) + $(call quiet-command,$(TRACETOOL) \ + --group=3D$(call trace-group-name,$@) \ + --format=3Dinstr-c \ + --backends=3D$(TRACE_INSTRUMENT_BACKEND) \ + $< > $@,"GEN","$(@:%-timestamp=3D%)") + instrument-root.h: instrument-root.h-timestamp @cmp $< $@ >/dev/null 2>&1 || cp $< $@ instrument-root.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-= host.mak $(tracetool-y) @@ -214,6 +226,15 @@ instrument-root.h-timestamp: $(SRC_PATH)/trace-events = $(BUILD_DIR)/config-host.m --backends=3D$(TRACE_INSTRUMENT_BACKEND) \ $< > $@,"GEN","$(@:%-timestamp=3D%)") =20 +instrument-root.c: instrument-root.c-timestamp + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +instrument-root.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-= host.mak $(tracetool-y) + $(call quiet-command,$(TRACETOOL) \ + --group=3Droot \ + --format=3Dinstr-c \ + --backends=3D$(TRACE_INSTRUMENT_BACKEND) \ + $< > $@,"GEN","$(@:%-timestamp=3D%)") + # Don't try to regenerate Makefile or configure # We don't generate any of them Makefile: ; @@ -390,7 +411,7 @@ Makefile: $(version-obj-y) # Build libraries =20 libqemustub.a: $(stub-obj-y) -libqemuutil.a: $(util-obj-y) $(trace-obj-y) +libqemuutil.a: $(util-obj-y) $(trace-obj-y) $(instr-obj-y) =20 ###################################################################### =20 @@ -830,7 +851,8 @@ endif .SECONDARY: $(TRACE_HEADERS) $(TRACE_HEADERS:%=3D%-timestamp) \ $(TRACE_SOURCES) $(TRACE_SOURCES:%=3D%-timestamp) \ $(TRACE_DTRACE) $(TRACE_DTRACE:%=3D%-timestamp) \ - $(INSTRUMENT_HEADERS) $(INSTRUMENT_HEADERS:%=3D%-timestamp) + $(INSTRUMENT_HEADERS) $(INSTRUMENT_HEADERS:%=3D%-timestamp) \ + $(INSTRUMENT_SOURCES) $(INSTRUMENT_SOURCES:%=3D%-timestamp) =20 # Include automatically generated dependency files # Dependencies in Makefile.objs files come from our recursive subdir rules diff --git a/Makefile.objs b/Makefile.objs index 8e2b3770c4..e36a519952 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -100,6 +100,7 @@ target-obj-y +=3D trace/ ###################################################################### # instrumentation util-obj-y +=3D instrument/ +target-obj-y +=3D instrument/ =20 ###################################################################### # guest agent @@ -180,3 +181,6 @@ trace-obj-y +=3D $(trace-events-subdirs:%=3D%/trace.o) trace-obj-$(CONFIG_TRACE_UST) +=3D trace-ust-all.o trace-obj-$(CONFIG_TRACE_DTRACE) +=3D trace-dtrace-root.o trace-obj-$(CONFIG_TRACE_DTRACE) +=3D $(trace-events-subdirs:%=3D%/trace-d= trace.o) + +instr-obj-$(CONFIG_INSTRUMENT) =3D instrument-root.o +instr-obj-y +=3D $(trace-events-subdirs:%=3D%/instrument.o) diff --git a/configure b/configure index 75d899b40c..13191052cb 100755 --- a/configure +++ b/configure @@ -897,6 +897,10 @@ for opt do ;; --with-trace-file=3D*) trace_file=3D"$optarg" ;; + --enable-trace-instrument) + trace_instrument=3D"yes" + trace_instrument_backend=3D"dynamic" + ;; --enable-gprof) gprof=3D"yes" ;; --enable-gcov) gcov=3D"yes" @@ -1427,6 +1431,8 @@ Advanced options (experts only): Available backends: $trace_backend_list --with-trace-file=3DNAME Full PATH,NAME of file to store traces Default:trace- + --enable-trace-instrument + Enable trace instrumentation --disable-slirp disable SLIRP userspace network connectivity --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI) --oss-lib path to OSS library @@ -5995,6 +6001,9 @@ QEMU_INCLUDES=3D"-I\$(SRC_PATH)/tcg $QEMU_INCLUDES" ########################################## # trace instrumentation echo "TRACE_INSTRUMENT_BACKEND=3Dinstr-$trace_instrument_backend" >> $conf= ig_host_mak +if test "$trace_instrument" =3D "yes"; then + echo "CONFIG_INSTRUMENT=3Dy" >> $config_host_mak +fi ########################################## =20 echo "TOOLS=3D$tools" >> $config_host_mak diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index d1edd1696e..c548bbdd8a 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -12,3 +12,15 @@ $(obj)/generated-tcg-tracers.h-timestamp: $(SRC_PATH)/tr= ace-events $(BUILD_DIR)/ --format=3Dinstr-tcg-h \ --backend=3D$(TRACE_INSTRUMENT_BACKEND) \ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)") + +$(obj)/generated-tcg-tracers.c: $(obj)/generated-tcg-tracers.c-timestamp + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +$(obj)/generated-tcg-tracers.c-timestamp: $(SRC_PATH)/trace-events $(BUILD= _DIR)/config-host.mak $(tracetool-y) + @mkdir -p $(dir $@) + $(call quiet-command,$(TRACETOOL) \ + --group=3Droot \ + --format=3Dinstr-tcg-c \ + --backend=3D$(TRACE_INSTRUMENT_BACKEND) \ + $< > $@,"GEN","$(patsubst %-timestamp,%,$@)") + +target-obj-$(CONFIG_INSTRUMENT) +=3D generated-tcg-tracers.o diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 6d382157c0..e65349bc33 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -275,6 +275,9 @@ class Event(object): QEMU_DSTATE =3D "_TRACE_%(NAME)s_DSTATE" QEMU_EVENT =3D "_TRACE_%(NAME)s_EVENT" =20 + QI_TRACE_INSTRUMENT =3D "qi_event_%(name)s" + QI_TRACE_INSTRUMENT_TCG =3D QI_TRACE_INSTRUMENT + "_tcg" + def api(self, fmt=3DNone): if fmt is None: fmt =3D Event.QEMU_TRACE_BACKEND diff --git a/scripts/tracetool/backend/instr_dynamic.py b/scripts/tracetool= /backend/instr_dynamic.py new file mode 100644 index 0000000000..f42d3afa8f --- /dev/null +++ b/scripts/tracetool/backend/instr_dynamic.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Dynamic instrumentation proxy. + +""" + +__author__ =3D "Llu=C3=ADs Vilanova " +__copyright__ =3D "Copyright 2012-2017, Llu=C3=ADs Vilanova " +__license__ =3D "GPL version 2 or (at your option) any later version" + +__maintainer__ =3D "Stefan Hajnoczi" +__email__ =3D "stefanha@linux.vnet.ibm.com" + + +from tracetool import out +from tracetool.transform import * +import tracetool.vcpu + + +################################################## +# instr-h + +def generate_instr_h_begin(events, group): + for event in events: + if "instrument" not in event.properties: + continue + out('extern void * %(qi)s_cb;', + qi=3Devent.api(event.QI_TRACE_INSTRUMENT)) + out('') + + +def generate_instr_h(event, group): + argtypes =3D ", ".join(event.args.types()) + if argtypes =3D=3D "": + argtypes =3D "void" + out(' void (*func)(%(argtypes)s) =3D %(qi)s_cb;', + ' func(%(argnames)s);', + qi=3Devent.api(event.QI_TRACE_INSTRUMENT), + args=3Devent.args, + argnames=3D", ".join(event.args.names()), + argtypes=3Dargtypes) + + +################################################## +# instr-tcg-h + +def generate_instr_tcg_h_begin(events, group): + for event in events: + if "instrument" not in event.properties: + continue + out('extern void * %(qi)s_cb;', + qi=3Devent.api(event.QI_TRACE_INSTRUMENT_TCG)) + out('') + + +def generate_instr_tcg_h(event, group): + argtypes =3D ", ".join(event.args.types()) + if argtypes =3D=3D "": + argtypes =3D "void" + out(' void (*func)(%(argtypes)s) =3D %(qi)s_cb;', + ' func(%(argnames)s);', + qi=3Devent.api(event.QI_TRACE_INSTRUMENT_TCG), + args=3Devent.args, + argnames=3D", ".join(event.args.names()), + argtypes=3Dargtypes) diff --git a/scripts/tracetool/format/instr_c.py b/scripts/tracetool/format= /instr_c.py new file mode 100644 index 0000000000..987ecbf5c2 --- /dev/null +++ b/scripts/tracetool/format/instr_c.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +/instrument-root.c +.../instrument.c + +""" + +__author__ =3D "Llu=C3=ADs Vilanova " +__copyright__ =3D "Copyright 2012-2017, Llu=C3=ADs Vilanova " +__license__ =3D "GPL version 2 or (at your option) any later version" + +__maintainer__ =3D "Stefan Hajnoczi" +__email__ =3D "stefanha@linux.vnet.ibm.com" + + +from tracetool import out +from tracetool.transform import * + + +def generate(events, backend, group): + events =3D [e for e in events + if "tcg-trans" not in e.properties and + "instrument" in e.properties] + + if group =3D=3D "root": + header =3D "trace-root.h" + else: + header =3D "trace.h" + + out('/* This file is autogenerated by tracetool, do not edit. */', + '', + '#include "qemu/osdep.h"', + '#include "%s"' % header, + '') + backend.generate_begin(events, group) + + for e in events: + out('void *%(qi_cb)s_cb =3D %(qi_trace)s;', + qi_cb=3De.api(e.QI_TRACE_INSTRUMENT), + qi_trace=3De.api(e.QEMU_TRACE_BACKEND)) + + backend.generate_end(events, group) diff --git a/scripts/tracetool/format/instr_tcg_c.py b/scripts/tracetool/fo= rmat/instr_tcg_c.py new file mode 100644 index 0000000000..382709d0bd --- /dev/null +++ b/scripts/tracetool/format/instr_tcg_c.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +instrument/generated-tcg-tracers.c + +""" + +__author__ =3D "Llu=C3=ADs Vilanova " +__copyright__ =3D "Copyright 2012-2017, Llu=C3=ADs Vilanova " +__license__ =3D "GPL version 2 or (at your option) any later version" + +__maintainer__ =3D "Stefan Hajnoczi" +__email__ =3D "stefanha@linux.vnet.ibm.com" + + +from tracetool import out +from tracetool.transform import * + + +def generate(events, backend, group): + events =3D [e.original for e in events + if "tcg-trans" in e.properties and + "instrument" in e.properties] + + out('/* This file is autogenerated by tracetool, do not edit. */', + '', + '#include "qemu/osdep.h"', + '#include "cpu.h"', + '#include "tcg-op.h"', + '#include "trace-tcg.h"', + '') + backend.generate_begin(events, group) + + for e in events: + out('void *%(qi_cb)s_cb =3D %(qi_trace)s;', + qi_cb=3De.api(e.QI_TRACE_INSTRUMENT_TCG), + qi_trace=3De.api(e.QEMU_TRACE_TCG_BACKEND)) + + backend.generate_end(events, group) From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 150091679320950.78345400812907; Mon, 24 Jul 2017 10:19:53 -0700 (PDT) Received: from localhost ([::1]:56048 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZh1L-0007ai-E7 for importer@patchew.org; Mon, 24 Jul 2017 13:19:51 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58131) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZh0M-00079k-QF for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:18:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZh0H-0005z9-RI for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:18:50 -0400 Received: from roura.ac.upc.edu ([147.83.33.10]:41356 helo=roura.ac.upc.es) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZh0H-0005yO-AX for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:18:45 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHIfes032384; Mon, 24 Jul 2017 19:18:41 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id D512E1770; Mon, 24 Jul 2017 19:18:35 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:18:34 +0300 Message-Id: <150091671441.30739.10101532119130561053.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHIfes032384 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 04/13] instrument: Allow adding the "instrument" property without modifying event files X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Adds a configure argument to allow users to add the instrument property to events without having to modify any trace event files. Signed-off-by: Llu=C3=ADs Vilanova --- configure | 17 +++++++++++++++++ rules.mak | 3 +++ scripts/tracetool.py | 11 +++++++++-- scripts/tracetool/__init__.py | 20 +++++++++++++++++++- 4 files changed, 48 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 13191052cb..8ab2a36130 100755 --- a/configure +++ b/configure @@ -353,6 +353,7 @@ trace_backends=3D"log" trace_file=3D"trace" trace_instrument=3D"no" trace_instrument_backend=3D"none" +instrument_events=3D"" spice=3D"" rbd=3D"" smartcard=3D"" @@ -901,6 +902,13 @@ for opt do trace_instrument=3D"yes" trace_instrument_backend=3D"dynamic" ;; + --with-instrument-events=3D*) + if test ! -f "$optarg"; then + echo "ERROR: no such file: $optarg" + exit 1 + fi + instrument_events=3D"`realpath $optarg`" + ;; --enable-gprof) gprof=3D"yes" ;; --enable-gcov) gcov=3D"yes" @@ -1433,6 +1441,9 @@ Advanced options (experts only): Default:trace- --enable-trace-instrument Enable trace instrumentation + --with-instrument-events=3DFILE + File with a list of events to enable instrument= ation + on (one per line) --disable-slirp disable SLIRP userspace network connectivity --enable-tcg-interpreter enable TCG with bytecode interpreter (TCI) --oss-lib path to OSS library @@ -5291,6 +5302,9 @@ if have_backend "simple"; then echo "Trace output file $trace_file-" fi echo "Trace instrumentation $trace_instrument" +if test -n "$instrument_events"; then +echo "Instrument events $instrument_events" +fi echo "spice support $spice $(echo_version $spice $spice_protocol_versi= on/$spice_server_version)" echo "rbd support $rbd" echo "xfsctl support $xfs" @@ -6004,6 +6018,9 @@ echo "TRACE_INSTRUMENT_BACKEND=3Dinstr-$trace_instrum= ent_backend" >> $config_host_ if test "$trace_instrument" =3D "yes"; then echo "CONFIG_INSTRUMENT=3Dy" >> $config_host_mak fi +if test -n "$instrument_events"; then + echo "CONFIG_INSTRUMENT_EVENTS=3D$instrument_events" >> $config_host_m= ak +fi ########################################## =20 echo "TOOLS=3D$tools" >> $config_host_mak diff --git a/rules.mak b/rules.mak index 6e943335f3..fbeda68022 100644 --- a/rules.mak +++ b/rules.mak @@ -188,6 +188,9 @@ notempty =3D $(if $1,y,n) =20 # Generate files with tracetool TRACETOOL=3D$(PYTHON) $(SRC_PATH)/scripts/tracetool.py +ifdef CONFIG_INSTRUMENT_EVENTS +TRACETOOL +=3D --instrument=3D$(CONFIG_INSTRUMENT_EVENTS) +endif =20 # Generate timestamp files for .h include files =20 diff --git a/scripts/tracetool.py b/scripts/tracetool.py index c55a21518b..d5d212e98f 100755 --- a/scripts/tracetool.py +++ b/scripts/tracetool.py @@ -6,7 +6,7 @@ Command-line wrapper for the tracetool machinery. """ =20 __author__ =3D "Llu=C3=ADs Vilanova " -__copyright__ =3D "Copyright 2012-2014, Llu=C3=ADs Vilanova " +__copyright__ =3D "Copyright 2012-2017, Llu=C3=ADs Vilanova " __license__ =3D "GPL version 2 or (at your option) any later version" =20 __maintainer__ =3D "Stefan Hajnoczi" @@ -70,6 +70,7 @@ def main(args): long_opts =3D ["backends=3D", "format=3D", "help", "list-backends", "check-backends", "group=3D"] long_opts +=3D ["binary=3D", "target-type=3D", "target-name=3D", "prob= e-prefix=3D"] + long_opts +=3D ["instrument=3D"] =20 try: opts, args =3D getopt.getopt(args[1:], "", long_opts) @@ -84,6 +85,7 @@ def main(args): target_type =3D None target_name =3D None probe_prefix =3D None + instrument =3D None for opt, arg in opts: if opt =3D=3D "--help": error_opt() @@ -111,6 +113,9 @@ def main(args): elif opt =3D=3D '--probe-prefix': probe_prefix =3D arg =20 + elif opt =3D=3D "--instrument": + instrument =3D arg + else: error_opt("unhandled option: %s" % opt) =20 @@ -137,12 +142,14 @@ def main(args): if probe_prefix is None: probe_prefix =3D ".".join(["qemu", target_type, target_name]) =20 + instrument_cre =3D tracetool.read_instrument(instrument) + if len(args) < 1: error_opt("missing trace-events filepath") events =3D [] for arg in args: with open(arg, "r") as fh: - events.extend(tracetool.read_events(fh)) + events.extend(tracetool.read_events(fh, instrument_cre)) =20 try: tracetool.generate(events, arg_group, arg_format, arg_backends, diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index e65349bc33..b9ddf8fbf9 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -292,13 +292,26 @@ class Event(object): self) =20 =20 -def read_events(fobj): +def read_instrument(path): + if path is None: + return None + + with open(path) as f: + patterns =3D f.readlines() + patterns =3D [p.replace("\n", "") for p in patterns] + patterns =3D [p.replace("*", ".*") for p in patterns] + pattern =3D "|".join(patterns) + return re.compile(pattern) + +def read_events(fobj, instrument): """Generate the output for the given (format, backends) pair. =20 Parameters ---------- fobj : file Event description file. + instrument : cre or None + Event patterns to instrument. =20 Returns a list of Event objects """ @@ -312,6 +325,11 @@ def read_events(fobj): =20 event =3D Event.build(line) =20 + if instrument is not None and instrument.match(event.name): + event.properties =3D [p for p in event.properties + if p !=3D "disable"] + event.properties.append("instrument") + # transform TCG-enabled events if "tcg" not in event.properties: events.append(event) From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500917029318794.9412082133933; Mon, 24 Jul 2017 10:23:49 -0700 (PDT) Received: from localhost ([::1]:56058 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZh59-0008Rh-7l for importer@patchew.org; Mon, 24 Jul 2017 13:23:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58480) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZh4G-00089T-LN for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:22:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZh4B-0007Dn-Pf for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:22:52 -0400 Received: from roura.ac.upc.edu ([147.83.33.10]:41378 helo=roura.ac.upc.es) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZh4B-0007DH-4D for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:22:47 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHMhtA032481; Mon, 24 Jul 2017 19:22:43 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id CEF2216EA; Mon, 24 Jul 2017 19:22:37 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:22:36 +0300 Message-Id: <150091695652.30739.17868656744714699780.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHMhtA032481 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 05/13] instrument: [dynamic] Add default public per-event functions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 For each event, adds a set of public routines available to instrumentation clients: * qi_event_*_nop: Do nothing (to disable an instrumentation event). * qi_event_*_trace Trace event using QEMU's tracing system. Default for execution-time event= s. * qi_event_*_gen_exec Generate TCG code to raise the event at execution time. Only available for translation-time events. * qi_event_*_trace_and_gen_exec Combination of qi_event_*_trace and qi_event_*_gen_exec. Only available f= or translation-time events. Default for translation-time events. The functions are defined for all events, regardless of whether they are instrumented or disabled (used later). Signed-off-by: Llu=C3=ADs Vilanova --- .gitignore | 1=20 Makefile | 14 +++++ configure | 2 + instrument/Makefile.objs | 14 +++++ instrument/qemu-instr/types.h | 73 +++++++++++++++++++++++ instrument/qemu-instr/visibility-internal.h | 58 +++++++++++++++++++ scripts/tracetool/__init__.py | 4 + scripts/tracetool/backend/instr_dynamic.py | 84 +++++++++++++++++++++++= ++++ scripts/tracetool/backend/instr_none.py | 18 ++++++ scripts/tracetool/format/instr_api_h.py | 65 +++++++++++++++++++++ scripts/tracetool/format/instr_c.py | 7 +- scripts/tracetool/format/instr_tcg_c.py | 7 +- scripts/tracetool/format/tcg_helper_c.py | 2 - scripts/tracetool/transform.py | 13 ++++ 14 files changed, 351 insertions(+), 11 deletions(-) create mode 100644 instrument/qemu-instr/types.h create mode 100644 instrument/qemu-instr/visibility-internal.h create mode 100644 scripts/tracetool/format/instr_api_h.py diff --git a/.gitignore b/.gitignore index ee2768cb05..d3aa8286b0 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ /instrument-root.c /instrument/generated-tcg-tracers.h /instrument/generated-tcg-tracers.c +/instrument/qemu-instr/events.h /trace-events-all /trace/generated-events.h /trace/generated-events.c diff --git a/Makefile b/Makefile index fb226bf54b..c8be326790 100644 --- a/Makefile +++ b/Makefile @@ -193,6 +193,9 @@ trace-dtrace-root.o: trace-dtrace-root.dtrace =20 INSTRUMENT_HEADERS =3D instrument-root.h $(trace-events-subdirs:%=3D%/inst= rument.h) INSTRUMENT_HEADERS +=3D instrument/generated-tcg-tracers.h +ifeq ($(TRACE_INSTRUMENT_BACKEND),instr-dynamic) +INSTRUMENT_HEADERS +=3D instrument/qemu-instr/events.h +endif INSTRUMENT_SOURCES =3D instrument-root.c $(trace-events-subdirs:%=3D%/inst= rument.c) INSTRUMENT_SOURCES +=3D instrument/generated-tcg-tracers.c =20 @@ -644,8 +647,13 @@ ifneq (,$(findstring qemu-ga,$(TOOLS))) endif endif =20 +install-includedir: + $(INSTALL_DIR) "$(DESTDIR)$(includedir)" =20 install: all $(if $(BUILD_DOCS),install-doc) install-datadir install-local= statedir +ifeq ($(TRACE_INSTRUMENT_BACKEND),instr-dynamic) +install: install-includedir +endif ifneq ($(TOOLS),) $(call install-prog,$(subst qemu-ga,qemu-ga$(EXESUF),$(TOOLS)),$(DESTDIR)= $(bindir)) endif @@ -676,6 +684,12 @@ endif for d in $(TARGET_DIRS); do \ $(MAKE) $(SUBDIR_MAKEFLAGS) TARGET_DIR=3D$$d/ -C $$d $@ || exit 1 ; \ done +ifeq ($(TRACE_INSTRUMENT_BACKEND),instr-dynamic) + $(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.h "$(DESTDIR)$(in= cludedir)/qemu-instr/" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/visibility-internal.h "= $(DESTDIR)$(includedir)/qemu-instr/" + $(INSTALL_DATA) $(BUILD_DIR)/instrument/qemu-instr/events.h "$(DESTDIR)$(= includedir)/qemu-instr/" +endif =20 # various test targets test speed: all diff --git a/configure b/configure index 8ab2a36130..ca61665874 100755 --- a/configure +++ b/configure @@ -489,6 +489,8 @@ QEMU_CFLAGS=3D"-Wall -Wundef -Wwrite-strings -Wmissing-= prototypes $QEMU_CFLAGS" QEMU_CFLAGS=3D"-Wstrict-prototypes -Wredundant-decls $QEMU_CFLAGS" QEMU_CFLAGS=3D"-D_GNU_SOURCE -D_FILE_OFFSET_BITS=3D64 -D_LARGEFILE_SOURCE = $QEMU_CFLAGS" QEMU_INCLUDES=3D"-I. -I\$(SRC_PATH) -I\$(SRC_PATH)/accel/tcg -I\$(SRC_PATH= )/include" +QEMU_INCLUDES=3D"$QEMU_INCLUDES -I\$(SRC_PATH)/instrument" +QEMU_INCLUDES=3D"$QEMU_INCLUDES -I\$(BUILD_DIR)/instrument" if test "$debug_info" =3D "yes"; then CFLAGS=3D"-g $CFLAGS" LDFLAGS=3D"-g $LDFLAGS" diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index c548bbdd8a..c2289aba85 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -24,3 +24,17 @@ $(obj)/generated-tcg-tracers.c-timestamp: $(SRC_PATH)/tr= ace-events $(BUILD_DIR)/ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)") =20 target-obj-$(CONFIG_INSTRUMENT) +=3D generated-tcg-tracers.o + +###################################################################### +# User interface + +$(obj)/qemu-instr/events.h: $(obj)/qemu-instr/events.h-timestamp + @cmp -s $< $@ || cp $< $@ +$(obj)/qemu-instr/events.h-timestamp: $(BUILD_DIR)/trace-events-all $(BUIL= D_DIR)/config-host.mak $(tracetool-y) + @mkdir -p $(dir $@) + $(call quiet-command,$(TRACETOOL) \ + --group=3Droot \ + --format=3Dinstr-api-h \ + --backend=3D$(TRACE_INSTRUMENT_BACKEND) \ + $(TRACETOOL_INSTR_STATIC) \ + $< > $@,"GEN","$(patsubst %-timestamp,%,$@)") diff --git a/instrument/qemu-instr/types.h b/instrument/qemu-instr/types.h new file mode 100644 index 0000000000..d3d26bbf73 --- /dev/null +++ b/instrument/qemu-instr/types.h @@ -0,0 +1,73 @@ +/* + * QI-specific types for instrumentation clients. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef QI__TYPES_H +#define QI__TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * SECTION: types + * @section_id: qi-types + * @title: Common types + * + * Data of architecture-specific length is always passed as an #int64_t to + * provide binary compatibility between the instrumentation library and QE= MU, + * regardless of the guest architecture being instrumented. + */ + +/** + * QICPU: + * + * Opaque guest CPU pointer. + */ +typedef struct QICPU QICPU; + +/** + * QITCGv_cpu: + * + * TCG register with QICPU. + */ +typedef struct QITCGv_cpu_d *QITCGv_cpu; + +/** + * QITCGv: + * + * TCG register with data of architecture-specific length. + */ +typedef struct QITCGv_d *QITCGv; + +/** + * QITCGv_i32: + * + * TCG register with 32-bit data. + */ +typedef struct QITCGv_i32_d *QITCGv_i32; + +/** + * QITCGv_i64: + * + * TCG register with 64-bit data. + */ +typedef struct QITCGv_i64_d *QITCGv_i64; + +/** + * QITCGv_ptr: + * + * TCG register with pointer of architecture-specific length. + */ +typedef struct QITCGv_ptr_d *QITCGv_ptr; + +#ifdef __cplusplus +} +#endif + +#endif /* QI__TYPES_H */ diff --git a/instrument/qemu-instr/visibility-internal.h b/instrument/qemu-= instr/visibility-internal.h new file mode 100644 index 0000000000..3bbbdc34cd --- /dev/null +++ b/instrument/qemu-instr/visibility-internal.h @@ -0,0 +1,58 @@ +/* + * Macros for symbol visibility. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * 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 + +/** + * 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 user's instrumentation code. + */ + +/** + * QI_VLOCAL: + * + * Make an element not visible to user's instrumentation code. + */ + +#if defined _WIN32 || defined __CYGWIN__ + #ifdef __GNUC__ + #define QI_VPUBLIC __attribute__ ((dllimport)) + #else + #define QI_VPUBLIC __declspec(dllimport) + #endif + #define QI_VLOCAL +#else + #if __GNUC__ >=3D 4 + #define QI_VPUBLIC __attribute__ ((visibility ("default"))) + #define QI_VLOCAL __attribute__ ((visibility ("hidden"))) + #else + #define QI_VPUBLIC + #define QI_VLOCAL + #endif +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* QI__VISIBILITY_INTERNAL_H */ diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index b9ddf8fbf9..7c19dc8c94 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -277,6 +277,10 @@ class Event(object): =20 QI_TRACE_INSTRUMENT =3D "qi_event_%(name)s" QI_TRACE_INSTRUMENT_TCG =3D QI_TRACE_INSTRUMENT + "_tcg" + QI_TRACE_NOP =3D QI_TRACE_INSTRUMENT + "_nop" + QI_TRACE_TRACE =3D QI_TRACE_INSTRUMENT + "_trace" + QI_TRACE_GEN =3D QI_TRACE_INSTRUMENT + "_gen_exec" + QI_TRACE_TRACEGEN =3D QI_TRACE_INSTRUMENT + "_trace_and_gen_exe= c" =20 def api(self, fmt=3DNone): if fmt is None: diff --git a/scripts/tracetool/backend/instr_dynamic.py b/scripts/tracetool= /backend/instr_dynamic.py index f42d3afa8f..6f9f8e49fb 100644 --- a/scripts/tracetool/backend/instr_dynamic.py +++ b/scripts/tracetool/backend/instr_dynamic.py @@ -65,3 +65,87 @@ def generate_instr_tcg_h(event, group): args=3Devent.args, argnames=3D", ".join(event.args.names()), argtypes=3Dargtypes) + + +################################################## +# instr-tcg-c + +def generate_instr_tcg_c_begin(events, group): + out('#include "qemu-instr/events.h"', + '') + +def generate_instr_tcg_c(event, group): + if "tcg" in event.properties: + event =3D event.event_trans + + iargs =3D tracetool.vcpu.transform_args("tcg_h", event.original) + api_args =3D iargs.transform(TCG_2_QI_TCG) + + qtargs =3D ["(%s)%s" % (arg[0], arg[1]) + for arg in event.args] + gargs =3D tracetool.vcpu.transform_args( + "tcg_helper_c", event.original, "wrapper") + qgargs =3D ["(%s)%s" % (arg[0], arg[1]) + for arg in gargs] + qargs =3D ["(%s)%s" % (arg[0], arg[1]) + for arg in iargs] + + out('QI_VPUBLIC void %(nop)s(%(api_args)s)', + '{', + '}', + 'QI_VPUBLIC void %(trace)s(%(api_args)s)', + '{', + ' %(b_trace)s(%(qtargs)s);', + '}', + 'QI_VPUBLIC void %(gen)s(%(api_args)s)', + '{', + ' %(b_gen)s(%(qgargs)s);', + '}', + 'QI_VPUBLIC void %(trace_gen)s(%(api_args)s)', + '{', + ' %(b_trace_gen)s(%(qargs)s);', + '}', + 'void *%(qi_cb)s_cb =3D %(trace_gen)s;', + '', + api_args=3Dapi_args, + nop=3Devent.api(event.QI_TRACE_NOP), + trace=3Devent.api(event.QI_TRACE_TRACE), + b_trace=3Devent.api(event.QEMU_TRACE_BACKEND), + gen=3Devent.api(event.QI_TRACE_GEN), + b_gen=3D"gen_helper_" + event.original.event_exec.api(event.QEMU_T= RACE_BACKEND), + trace_gen=3Devent.api(event.QI_TRACE_TRACEGEN), + b_trace_gen=3Devent.original.api(event.QEMU_TRACE_TCG_BACKEND), + iargs=3Diargs, + qargs=3D", ".join(qargs), + qtargs=3D", ".join(qtargs), + qgargs=3D", ".join(qgargs), + qi_cb=3Devent.original.api(event.QI_TRACE_INSTRUMENT_TCG)) + + +################################################## +# instr-c + +def generate_instr_c_begin(events, group): + out('#include "qemu-instr/events.h"', + '') + +def generate_instr_c(event, group): + args =3D event.args.transform(TCG_2_QI_TCG) + qargs =3D ["(%s)%s" % (arg[0], arg[1]) + for arg in event.args] + out('QI_VPUBLIC void %(nop)s(%(args)s)', + '{', + '}', + 'QI_VPUBLIC void %(trace)s(%(args)s)', + '{', + ' %(backend)s(%(qargs)s);', + '}', + 'void *%(qi_cb)s_cb =3D %(qi_trace)s;', + '', + args=3Dargs, + nop=3Devent.api(event.QI_TRACE_NOP), + trace=3Devent.api(event.QI_TRACE_TRACE), + backend=3Devent.api(event.QEMU_TRACE_BACKEND), + qargs=3D", ".join(qargs), + qi_cb=3Devent.api(event.QI_TRACE_INSTRUMENT), + qi_trace=3Devent.api(event.QI_TRACE_TRACE)) diff --git a/scripts/tracetool/backend/instr_none.py b/scripts/tracetool/ba= ckend/instr_none.py index 56508cfcbe..95aed5e96f 100644 --- a/scripts/tracetool/backend/instr_none.py +++ b/scripts/tracetool/backend/instr_none.py @@ -32,3 +32,21 @@ def generate_instr_h(event, group): out(' %(backend)s(%(argnames)s);', backend=3Devent.api(event.QEMU_TRACE_BACKEND), argnames=3D", ".join(event.args.names())) + + +################################################## +# instr-tcg-c + +def generate_instr_tcg_c(event, group): + out('void *%(qi_cb)s_cb =3D %(qi_trace)s;', + qi_cb=3Devent.api(event.QI_TRACE_INSTRUMENT_TCG), + qi_trace=3Devent.api(event.QEMU_TRACE_TCG_BACKEND)) + + +################################################## +# instr-c + +def generate_instr_c(event, group): + out('void *%(qi_cb)s_cb =3D %(qi_trace)s;', + qi_cb=3Devent.api(event.QI_TRACE_INSTRUMENT), + qi_trace=3Devent.api(event.QEMU_TRACE_BACKEND)) diff --git a/scripts/tracetool/format/instr_api_h.py b/scripts/tracetool/fo= rmat/instr_api_h.py new file mode 100644 index 0000000000..d85f64df45 --- /dev/null +++ b/scripts/tracetool/format/instr_api_h.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +instrument/qemu-instr/events.h + +""" + +__author__ =3D "Llu=C3=ADs Vilanova " +__copyright__ =3D "Copyright 2012-2017, Llu=C3=ADs Vilanova " +__license__ =3D "GPL version 2 or (at your option) any later version" + +__maintainer__ =3D "Stefan Hajnoczi" +__email__ =3D "stefanha@linux.vnet.ibm.com" + + +from tracetool import out +from tracetool.transform import * +import tracetool.vcpu + + +def generate(events, backend, group): + # We won't be using any backend, because this code is only compiled in= when + # dynamic instrumentation mode is enabled + + out('/* This file is autogenerated by tracetool, do not edit. */', + '', + '#ifndef QI__EVENTS_H', + '#define QI__EVENTS_H', + '', + '#ifdef __cplusplus', + 'extern "C" {', + '#endif', + '', + '#include ', + '#include ', + '#include ', + '#include ', + '', + '') + + for e in events: + if "tcg-trans" in e.properties: + args =3D tracetool.vcpu.transform_args("tcg_h", e.original) + args =3D args.transform(TCG_2_QI_TCG) + else: + args =3D e.args.transform(TCG_2_QI_TCG) + out('QI_VPUBLIC void %(nop)s(%(args)s);', + 'QI_VPUBLIC void %(trace)s(%(args)s);', + args=3Dargs, + nop=3De.api(e.QI_TRACE_NOP), + trace=3De.api(e.QI_TRACE_TRACE)) + if "tcg-trans" in e.properties: + out('QI_VPUBLIC void %(gen)s(%(args)s);', + 'QI_VPUBLIC void %(trace_gen)s(%(args)s);', + args=3Dargs, + gen=3De.api(e.QI_TRACE_GEN), + trace_gen=3De.api(e.QI_TRACE_TRACEGEN)) + out('') + + out('#ifdef __cplusplus', + '}', + '#endif', + '', + '#endif /* QI__EVENTS_H */') diff --git a/scripts/tracetool/format/instr_c.py b/scripts/tracetool/format= /instr_c.py index 987ecbf5c2..35b7955641 100644 --- a/scripts/tracetool/format/instr_c.py +++ b/scripts/tracetool/format/instr_c.py @@ -21,8 +21,7 @@ from tracetool.transform import * =20 def generate(events, backend, group): events =3D [e for e in events - if "tcg-trans" not in e.properties and - "instrument" in e.properties] + if "tcg-trans" not in e.properties] =20 if group =3D=3D "root": header =3D "trace-root.h" @@ -37,8 +36,6 @@ def generate(events, backend, group): backend.generate_begin(events, group) =20 for e in events: - out('void *%(qi_cb)s_cb =3D %(qi_trace)s;', - qi_cb=3De.api(e.QI_TRACE_INSTRUMENT), - qi_trace=3De.api(e.QEMU_TRACE_BACKEND)) + backend.generate(e, group) =20 backend.generate_end(events, group) diff --git a/scripts/tracetool/format/instr_tcg_c.py b/scripts/tracetool/fo= rmat/instr_tcg_c.py index 382709d0bd..61407a68c0 100644 --- a/scripts/tracetool/format/instr_tcg_c.py +++ b/scripts/tracetool/format/instr_tcg_c.py @@ -20,8 +20,7 @@ from tracetool.transform import * =20 def generate(events, backend, group): events =3D [e.original for e in events - if "tcg-trans" in e.properties and - "instrument" in e.properties] + if "tcg-trans" in e.properties] =20 out('/* This file is autogenerated by tracetool, do not edit. */', '', @@ -33,8 +32,6 @@ def generate(events, backend, group): backend.generate_begin(events, group) =20 for e in events: - out('void *%(qi_cb)s_cb =3D %(qi_trace)s;', - qi_cb=3De.api(e.QI_TRACE_INSTRUMENT_TCG), - qi_trace=3De.api(e.QEMU_TRACE_TCG_BACKEND)) + backend.generate(e, group) =20 backend.generate_end(events, group) diff --git a/scripts/tracetool/format/tcg_helper_c.py b/scripts/tracetool/f= ormat/tcg_helper_c.py index e9ba62a136..db431797d9 100644 --- a/scripts/tracetool/format/tcg_helper_c.py +++ b/scripts/tracetool/format/tcg_helper_c.py @@ -75,7 +75,7 @@ def generate(events, backend, group): ' %(name)s(%(args_call)s);', '}', name_tcg=3D"helper_%s_proxy" % e.api(e.QEMU_TRACE_BACKEND), - name=3De.api(e.QEMU_TRACE_NOCHECK), + name=3De.api(e.QEMU_TRACE), args_api=3De_args_api, args_call=3D", ".join(e_args_call.casted()), ) diff --git a/scripts/tracetool/transform.py b/scripts/tracetool/transform.py index e18b05315e..400d36a6ed 100644 --- a/scripts/tracetool/transform.py +++ b/scripts/tracetool/transform.py @@ -137,6 +137,19 @@ TCG_2_TCG_HELPER_DECL =3D { =20 =20 ################################################## +# host/tcg -> instrumentation-client tcg type + +def TCG_2_QI_TCG(type_): + if type_ =3D=3D "TCGv_env": + return "QITCGv_cpu" + elif type_.startswith("TCGv"): + return "QI" + type_ + elif type_.startswith("CPUState"): + return type_.replace("CPUState", "QICPU", 1) + else: + return type_ + +################################################## # host/tcg -> tcg temporal constant allocation =20 def _host_2_tcg_tmp_new(type_): From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500917275626650.7998649737689; Mon, 24 Jul 2017 10:27:55 -0700 (PDT) Received: from localhost ([::1]:56068 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZh96-0000we-OM for importer@patchew.org; Mon, 24 Jul 2017 13:27:52 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59032) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZh8B-0000b9-Ru for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:26:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZh86-0000nV-Ry for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:26:55 -0400 Received: from roura.ac.upc.edu ([147.83.33.10]:55462 helo=roura.ac.upc.es) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZh86-0000nD-6F for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:26:50 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHQkg4032570; Mon, 24 Jul 2017 19:26:46 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 6544A1770; Mon, 24 Jul 2017 19:26:40 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:26:39 +0300 Message-Id: <150091719881.30739.10096572040779058122.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHQkg4032570 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 06/13] instrument: Add event control interface X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Adds public and internal APIs to control event instrumentation. It also adds an event object (QI_EVENT_${NAME}) and define to know if it's = staically enabled (QI_EVENT_${NAME}_ENABLED). Signed-off-by: Llu=C3=ADs Vilanova --- Makefile | 1=20 configure | 4=20 instrument/Makefile.objs | 5=20 instrument/control.c | 316 ++++++++++++++++++++++++= ++++ instrument/control.h | 86 ++++++++ instrument/qemu-instr/control.h | 128 +++++++++++ instrument/qemu-instr/types.h | 8 + scripts/tracetool/backend/instr_dynamic.py | 14 + scripts/tracetool/format/c.py | 37 +++ scripts/tracetool/format/instr_api_h.py | 13 + trace/event-internal.h | 10 + 11 files changed, 615 insertions(+), 7 deletions(-) create mode 100644 instrument/control.c create mode 100644 instrument/control.h create mode 100644 instrument/qemu-instr/control.h diff --git a/Makefile b/Makefile index c8be326790..ee54b7e17a 100644 --- a/Makefile +++ b/Makefile @@ -688,6 +688,7 @@ ifeq ($(TRACE_INSTRUMENT_BACKEND),instr-dynamic) $(INSTALL_DIR) "$(DESTDIR)$(includedir)/qemu-instr" $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/types.h "$(DESTDIR)$(in= cludedir)/qemu-instr/" $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/visibility-internal.h "= $(DESTDIR)$(includedir)/qemu-instr/" + $(INSTALL_DATA) $(SRC_PATH)/instrument/qemu-instr/control.h "$(DESTDIR)$(= includedir)/qemu-instr/" $(INSTALL_DATA) $(BUILD_DIR)/instrument/qemu-instr/events.h "$(DESTDIR)$(= includedir)/qemu-instr/" endif =20 diff --git a/configure b/configure index ca61665874..320309e0c0 100755 --- a/configure +++ b/configure @@ -6019,10 +6019,14 @@ QEMU_INCLUDES=3D"-I\$(SRC_PATH)/tcg $QEMU_INCLUDES" echo "TRACE_INSTRUMENT_BACKEND=3Dinstr-$trace_instrument_backend" >> $conf= ig_host_mak if test "$trace_instrument" =3D "yes"; then echo "CONFIG_INSTRUMENT=3Dy" >> $config_host_mak + libs_qga=3D"-ldl $libs_qga" + LDFLAGS=3D"-rdynamic $LDFLAGS" fi if test -n "$instrument_events"; then echo "CONFIG_INSTRUMENT_EVENTS=3D$instrument_events" >> $config_host_m= ak fi +# code requiring it is always compiled-in +LIBS=3D"-ldl $LIBS" ########################################## =20 echo "TOOLS=3D$tools" >> $config_host_mak diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index c2289aba85..244936aa8c 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -38,3 +38,8 @@ $(obj)/qemu-instr/events.h-timestamp: $(BUILD_DIR)/trace-= events-all $(BUILD_DIR) --backend=3D$(TRACE_INSTRUMENT_BACKEND) \ $(TRACETOOL_INSTR_STATIC) \ $< > $@,"GEN","$(patsubst %-timestamp,%,$@)") + +###################################################################### +# Control code + +target-obj-y +=3D control.o diff --git a/instrument/control.c b/instrument/control.c new file mode 100644 index 0000000000..309228f15d --- /dev/null +++ b/instrument/control.c @@ -0,0 +1,316 @@ +/* + * Interface for controlling dynamic trace instrumentation. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" + +#include +#include "instrument/control.h" +#include "qemu/thread.h" +#include "qemu-instr/control.h" +#include "qemu/error-report.h" + + +typedef int64_t HandleID; + +typedef struct Handle +{ + HandleID id; + void *dlhandle; + void (*init)(int, const char **); + void (*fini)(void); + QSLIST_ENTRY(Handle) list; +} Handle; + +HandleID handle_last_id; +QSLIST_HEAD(, Handle) handles =3D QSLIST_HEAD_INITIALIZER(handles); +static QemuMutex instr_lock; + + +static Handle *handle_get(void) +{ + Handle *res =3D g_malloc0(sizeof(Handle)); + res->id =3D handle_last_id++; + QSLIST_INSERT_HEAD(&handles, res, list); + return res; +} + +static bool handle_put(HandleID id) +{ + Handle *prev =3D NULL; + Handle *handle; + QSLIST_FOREACH(handle, &handles, list) { + if (handle->id =3D=3D id) { + break; + } + prev =3D handle; + } + if (handle =3D=3D NULL) { + return false; + } else { + if (prev =3D=3D NULL) { + QSLIST_REMOVE_HEAD(&handles, list); + } else { + QSLIST_REMOVE_AFTER(prev, list); + } + g_free(handle); + return true; + } +} + +#if defined(CONFIG_INSTRUMENT) +static Handle *handle_find(HandleID id) +{ + Handle *handle; + QSLIST_FOREACH(handle, &handles, list) { + if (handle->id =3D=3D id) { + return handle; + } + } + return NULL; +} +#endif + +static bool instr_available(void) +{ +#if defined(CONFIG_INSTRUMENT) + return true; +#else + return false; +#endif +} + +InstrLoadError instr_load(const char * path, int argc, const char ** argv, + int64_t *handle_id) +{ + InstrLoadError res; + + qemu_rec_mutex_lock(&instr_lock); + + *handle_id =3D -1; + if (!instr_available()) { + res =3D INSTR_LOAD_UNAVAILABLE; + goto out; + } + + if (!QSLIST_EMPTY(&handles) > 0) { + /* XXX: This is in fact a hard-coded limit, but there's no reason = why a + * real multi-library implementation should fail with somethi= ng like + * "too many open libraries". + */ + res =3D INSTR_LOAD_UNAVAILABLE; + goto out; + } + + Handle * handle =3D handle_get(); + handle->dlhandle =3D dlopen(path, RTLD_NOW); + if (handle->dlhandle =3D=3D NULL) { + goto err; + } + + handle->init =3D dlsym(handle->dlhandle, "qi_init"); + if (handle->init =3D=3D NULL) { + goto err; + } + handle->fini =3D dlsym(handle->dlhandle, "qi_fini"); + if (handle->fini =3D=3D NULL) { + goto err; + } + + handle->init(argc, argv); + + *handle_id =3D handle->id; + res =3D INSTR_LOAD_OK; + goto out; + +err: + handle_put(handle->id); + res =3D INSTR_LOAD_ERROR; +out: + qemu_rec_mutex_unlock(&instr_lock); + return res; +} + +static inline bool instr_event_is_instrument(TraceEvent *ev) +{ +#if defined(CONFIG_INSTRUMENT) + return ev->is_instr; +#else + return false; +#endif +} + +InstrUnloadError instr_unload(int64_t handle_id) +{ + InstrLoadError res; + + qemu_rec_mutex_lock(&instr_lock); + + if (!instr_available()) { + res =3D INSTR_UNLOAD_UNAVAILABLE; + goto out; + } + +#if defined(CONFIG_INSTRUMENT) + Handle *handle =3D handle_find(handle_id); + if (handle =3D=3D NULL) { + res =3D INSTR_UNLOAD_INVALID; + goto out; + } + + handle->fini(); + + TraceEventIter iter; + TraceEvent *ev =3D NULL; + trace_event_iter_init(&iter, NULL); + while ((ev =3D trace_event_iter_next(&iter)) !=3D NULL) { + if (instr_event_is_instrument(ev)) { + *ev->instr_cb =3D ev->instr_cb_default; + } + } + + /* this should never fail */ + if (dlclose(handle->dlhandle) < 0) { + res =3D INSTR_UNLOAD_ERROR; + } else { + res =3D INSTR_UNLOAD_OK; + } + handle_put(handle->id); +#endif + +out: + qemu_rec_mutex_unlock(&instr_lock); + return res; +} + +InstrUnloadError instr_unload_all(void) +{ + InstrUnloadError res =3D INSTR_UNLOAD_OK; + + qemu_rec_mutex_lock(&instr_lock); + while (true) { + Handle *handle =3D QSLIST_FIRST(&handles); + if (handle =3D=3D NULL) { + break; + } else { + res =3D instr_unload(handle->id); + if (res !=3D INSTR_UNLOAD_OK) { + break; + } + } + } + qemu_rec_mutex_unlock(&instr_lock); + + return res; +} + +void qi_ctrl_event_set(QIEvent *ev, void *cb) +{ + TraceEvent *tev =3D (TraceEvent *)ev; + + if (unlikely(tev =3D=3D NULL)) { + error_report("qi_ctrl_event_set: event is NULL"); + return; + } + +#if defined(CONFIG_INSTRUMENT) + if (unlikely(!tev->is_instr)) { + error_report("qi_ctrl_event_set: event is not instrumentable"); + return; + } + + if (cb =3D=3D NULL) { + *tev->instr_cb =3D tev->instr_cb_default; + } else { + *tev->instr_cb =3D cb; + } +#else + assert(false); +#endif /* defined(CONFIG_INSTRUMENT) */ +} + +bool qi_trace_event_get_state_static(QIEvent *ev) +{ + if (unlikely(ev =3D=3D NULL)) { + error_report("qi_trace_event_get_state_static: event is NULL"); + return false; + } + return trace_event_get_state_static((TraceEvent *)ev); +} + +bool qi_trace_event_get_state_dynamic(QIEvent *ev) +{ + if (unlikely(ev =3D=3D NULL)) { + error_report("qi_trace_event_get_state_dynamic: event is NULL"); + return false; + } + return trace_event_get_state_dynamic((TraceEvent *)ev); +} + +bool qi_trace_event_get_vcpu_state_dynamic(QICPU *vcpu, QIEvent *ev) +{ + TraceEvent *tev =3D (TraceEvent *)ev; + + if (unlikely(vcpu =3D=3D NULL)) { + error_report("qi_trace_event_get_vcpu_state_dynamic: vcpu is NULL"= ); + return false; + } + if (unlikely(tev =3D=3D NULL)) { + error_report("qi_trace_event_get_vcpu_state_dynamic: event is NULL= "); + return false; + } + if (unlikely(!trace_event_is_vcpu(tev))) { + error_report("qi_trace_event_get_vcpu_state_dynamic: event does no= t have 'vcpu' property"); + return false; + } + return trace_event_get_vcpu_state_dynamic((CPUState *)vcpu, tev); +} + +void qi_trace_event_set_state_dynamic(QIEvent *ev, bool state) +{ + TraceEvent *tev =3D (TraceEvent *)ev; + + if (unlikely(tev =3D=3D NULL)) { + error_report("qi_trace_event_set_state_dynamic: event is NULL"); + return; + } + if (unlikely(!trace_event_get_state_static(tev))) { + error_report("qi_trace_event_set_state_dynamic: event is staticall= y disabled"); + return; + } + trace_event_set_state_dynamic(tev, state); +} + +void qi_trace_event_set_vcpu_state_dynamic(QICPU *vcpu, QIEvent *ev, bool = state) +{ + TraceEvent *tev =3D (TraceEvent *)ev; + + if (unlikely(vcpu =3D=3D NULL)) { + error_report("qi_trace_event_set_vcpu_state_dynamic: vcpu is NULL"= ); + return; + } + if (unlikely(tev =3D=3D NULL)) { + error_report("qi_trace_event_set_vcpu_state_dynamic: event is NULL= "); + return; + } + if (unlikely(!trace_event_is_vcpu(tev))) { + error_report("qi_trace_event_set_vcpu_state_dynamic: event does no= t have 'vcpu' property"); + return; + } + if (unlikely(!trace_event_get_state_static(tev))) { + error_report("qi_trace_event_set_vcpu_state_dynamic: event is stat= ically disabled"); + return; + } + trace_event_set_vcpu_state_dynamic((CPUState *)vcpu, tev, state); +} + +static void __attribute__((constructor)) instr_lock_init(void) +{ + qemu_rec_mutex_init(&instr_lock); +} diff --git a/instrument/control.h b/instrument/control.h new file mode 100644 index 0000000000..a83a350faf --- /dev/null +++ b/instrument/control.h @@ -0,0 +1,86 @@ +/* + * Interface for controlling dynamic trace instrumentation. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef INSTRUMENT__CONTROL_H +#define INSTRUMENT__CONTROL_H + +#include +#include +#include "qapi-types.h" +#include "trace/control.h" + + +/** + * InstrLoadError: + * @INSTR_LOAD_OK: Correctly loaded. + * @INSTR_LOAD_UNAVAILABLE: Service not available. + * @INSTR_LOAD_ERROR: Error with libdl (see dlerror). + * + * Error codes for instr_load(). + * + * Warning: Keep in sync with #InstrLoadCode + */ +typedef enum { + INSTR_LOAD_OK, + INSTR_LOAD_UNAVAILABLE, + INSTR_LOAD_ERROR, +} InstrLoadError; + +/** + * InstrUnloadError: + * @INSTR_UNLOAD_OK: Correctly unloaded. + * @INSTR_UNLOAD_UNAVAILABLE: Service not available. + * @INSTR_UNLOAD_INVALID: Invalid handle. + * @INSTR_UNLOAD_ERROR: Error with libdl (see dlerror). + * + * Error codes for instr_unload(). + * + * Warning: Keep in sync with #InstrUnloadCode + */ +typedef enum { + INSTR_UNLOAD_OK, + INSTR_UNLOAD_UNAVAILABLE, + INSTR_UNLOAD_INVALID, + INSTR_UNLOAD_ERROR, +} InstrUnloadError; + +/** + * instr_load: + * @path: Path to the shared library to load. + * @argc: Number of arguments passed to the initialization function of the= library. + * @argv: Arguments passed to the initialization function of the library. + * @handle: Instrumentation library handle (undefined in case of error). + * + * Load a dynamic trace instrumentation library. + * + * Returns: Whether the library could be loaded. + */ +InstrLoadError instr_load(const char * path, int argc, const char ** argv, + int64_t *handle); + +/** + * instr_unload: + * @handle: Instrumentation library handle returned by instr_load(). + * + * Unload the given instrumentation library. + * + * Returns: Whether the library could be unloaded. + */ +InstrUnloadError instr_unload(int64_t handle); + +/** + * instr_unload_all: + * + * Unload all instrumentation libraries. + * + * Returns: Whether any library could not be unloaded. + */ +InstrUnloadError instr_unload_all(void); + +#endif /* INSTRUMENT__CONTROL_H */ diff --git a/instrument/qemu-instr/control.h b/instrument/qemu-instr/contro= l.h new file mode 100644 index 0000000000..83f20d42f2 --- /dev/null +++ b/instrument/qemu-instr/control.h @@ -0,0 +1,128 @@ +/* + * Interface for controlling the state of events. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef QI__CONTROL_H +#define QI__CONTROL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include +#include + + +/** + * SECTION:control + * @section_id: qi-control + * @title: Event control API for QEMU event instrumentation + */ + +/** + * 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 #NULL to restore the default callback. + */ +QI_VPUBLIC void qi_ctrl_event_set(QIEvent *ev, void *cb); + +/** + * qi_trace_event_get_state: + * @ev: Event identifier name. + * + * Get the tracing state of an event (both static and dynamic). + * + * If the event has the disabled property, the check will have no performa= nce + * impact. + */ +#define qi_trace_event_get_state(ev) \ + ((ev ##_ENABLED) && qi_trace_event_get_state_dynamic(ev)) + +/** + * qi_trace_event_get_vcpu_state: + * @vcpu: Target vCPU. + * @ev: Event identifier name. + * + * Get the tracing state of an event (both static and dynamic) for the giv= en + * vCPU. + * + * If the event has the disabled property, the check will have no performa= nce + * impact. + */ +#define qi_trace_event_get_vcpu_state(vcpu, ev) \ + ((ev ##_ENABLED) && \ + qi_trace_event_get_vcpu_state_dynamic(vcpu, ev)) + +/** + * qi_trace_event_get_state_static: + * @ev: 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_VPUBLIC bool qi_trace_event_get_state_static(QIEvent *ev); + +/** + * qi_trace_event_get_state_dynamic: + * @ev: Event identifier. + * + * Get the dynamic tracing state of an event. + */ +QI_VPUBLIC bool qi_trace_event_get_state_dynamic(QIEvent *ev); + +/** + * qi_trace_event_get_vcpu_state_dynamic: + * @vcpu: Target vCPU. + * @ev: Event identifier. + * + * Get the dynamic tracing state of an event for the given vCPU. + */ +QI_VPUBLIC bool qi_trace_event_get_vcpu_state_dynamic(QICPU *vcpu, + QIEvent *ev); + +/** + * qi_trace_event_set_state_dynamic: + * @ev: Event identifier. + * @state: Target tracing state. + * + * Set the dynamic tracing state of an event. + * + * Pre-condition: qi_trace_event_get_state_static(ev) =3D=3D true + */ +QI_VPUBLIC void qi_trace_event_set_state_dynamic(QIEvent *ev, bool state); + +/** + * qi_trace_event_set_vcpu_state_dynamic: + * @vcpu: Target vCPU. + * @ev: Event identifier. + * @state: Target tracing state. + * + * Set the dynamic tracing state of an event for the given vCPU. + * + * Pre-condition: qi_trace_event_get_state_static(ev) =3D=3D true + * + * Note: Changes for execution-time events with the 'tcg' property will no= t be + * propagated until the next TB is executed (iff executing in TCG mo= de). + */ +QI_VPUBLIC void qi_trace_event_set_vcpu_state_dynamic(QICPU *vcpu, + QIEvent *ev, bool st= ate); + +#ifdef __cplusplus +} +#endif + +#endif /* QI__CONTROL_H */ diff --git a/instrument/qemu-instr/types.h b/instrument/qemu-instr/types.h index d3d26bbf73..58a84b6d01 100644 --- a/instrument/qemu-instr/types.h +++ b/instrument/qemu-instr/types.h @@ -25,6 +25,14 @@ extern "C" { */ =20 /** + * QIEvent: + * + * Opaque structure defining an instrumentation event. + */ +struct QIEvent; +typedef struct QIEvent QIEvent; + +/** * QICPU: * * Opaque guest CPU pointer. diff --git a/scripts/tracetool/backend/instr_dynamic.py b/scripts/tracetool= /backend/instr_dynamic.py index 6f9f8e49fb..2efd4a7eb1 100644 --- a/scripts/tracetool/backend/instr_dynamic.py +++ b/scripts/tracetool/backend/instr_dynamic.py @@ -90,7 +90,8 @@ def generate_instr_tcg_c(event, group): qargs =3D ["(%s)%s" % (arg[0], arg[1]) for arg in iargs] =20 - out('QI_VPUBLIC void %(nop)s(%(api_args)s)', + out('QIEvent *%(qevent)s =3D (QIEvent *)&%(tevent)s;', + 'QI_VPUBLIC void %(nop)s(%(api_args)s)', '{', '}', 'QI_VPUBLIC void %(trace)s(%(api_args)s)', @@ -99,7 +100,10 @@ def generate_instr_tcg_c(event, group): '}', 'QI_VPUBLIC void %(gen)s(%(api_args)s)', '{', + # does not exist when event is disabled + '#if %(teventu)s_ENABLED', ' %(b_gen)s(%(qgargs)s);', + '#endif', '}', 'QI_VPUBLIC void %(trace_gen)s(%(api_args)s)', '{', @@ -107,6 +111,9 @@ def generate_instr_tcg_c(event, group): '}', 'void *%(qi_cb)s_cb =3D %(trace_gen)s;', '', + qevent=3Devent.api(event.QI_TRACE_INSTRUMENT).upper(), + tevent=3Devent.api(event.QEMU_EVENT), + teventu=3Devent.api(event.QEMU_TRACE).upper(), api_args=3Dapi_args, nop=3Devent.api(event.QI_TRACE_NOP), trace=3Devent.api(event.QI_TRACE_TRACE), @@ -133,7 +140,8 @@ def generate_instr_c(event, group): args =3D event.args.transform(TCG_2_QI_TCG) qargs =3D ["(%s)%s" % (arg[0], arg[1]) for arg in event.args] - out('QI_VPUBLIC void %(nop)s(%(args)s)', + out('QIEvent *%(qevent)s =3D (QIEvent *)&%(tevent)s;', + 'QI_VPUBLIC void %(nop)s(%(args)s)', '{', '}', 'QI_VPUBLIC void %(trace)s(%(args)s)', @@ -142,6 +150,8 @@ def generate_instr_c(event, group): '}', 'void *%(qi_cb)s_cb =3D %(qi_trace)s;', '', + qevent=3Devent.api(event.QI_TRACE_INSTRUMENT).upper(), + tevent=3Devent.api(event.QEMU_EVENT), args=3Dargs, nop=3Devent.api(event.QI_TRACE_NOP), trace=3Devent.api(event.QI_TRACE_TRACE), diff --git a/scripts/tracetool/format/c.py b/scripts/tracetool/format/c.py index 833c05a022..0b8bb98d24 100644 --- a/scripts/tracetool/format/c.py +++ b/scripts/tracetool/format/c.py @@ -6,7 +6,7 @@ trace/generated-tracers.c """ =20 __author__ =3D "Llu=C3=ADs Vilanova " -__copyright__ =3D "Copyright 2012-2014, Llu=C3=ADs Vilanova " +__copyright__ =3D "Copyright 2012-2017, Llu=C3=ADs Vilanova " __license__ =3D "GPL version 2 or (at your option) any later version" =20 __maintainer__ =3D "Stefan Hajnoczi" @@ -39,18 +39,49 @@ def generate(events, backend, group): vcpu_id =3D 0 else: vcpu_id =3D "TRACE_VCPU_EVENT_NONE" + + if "instrument" in e.properties: + is_instr =3D "true" + out('#if defined(CONFIG_INSTRUMENT)') + if "tcg-trans" in e.properties: + instr_cb =3D e.original.api(e.QI_TRACE_INSTRUMENT_TCG) + "= _cb" + instr_cb_default =3D e.api(e.QI_TRACE_TRACEGEN) + out('static void *_tmp__%(name1)s;', + 'extern void *%(name1)s __attribute__((weak, alias("_t= mp__%(name1)s")));', + name1=3Dinstr_cb) + else: + instr_cb =3D e.api(e.QI_TRACE_INSTRUMENT) + "_cb" + instr_cb_default =3D e.api(e.QI_TRACE_TRACE) + out('static void _tmp__%(name2)s(void) {};', + 'void %(name2)s(void) __attribute__((weak, alias("_tmp__%(= name2)s")));', + '#endif', + name2=3Dinstr_cb_default) + instr_cb =3D "&" + instr_cb + else: + is_instr =3D "false" + instr_cb =3D "NULL" + instr_cb_default =3D "NULL" + out('TraceEvent %(event)s =3D {', ' .id =3D 0,', ' .vcpu_id =3D %(vcpu_id)s,', ' .name =3D \"%(name)s\",', ' .sstate =3D %(sstate)s,', - ' .dstate =3D &%(dstate)s ', + ' .dstate =3D &%(dstate)s,', + '#if defined(CONFIG_INSTRUMENT)', + ' .is_instr =3D %(is_instr)s,', + ' .instr_cb =3D %(instr_cb)s,', + ' .instr_cb_default =3D %(instr_cb_default)s,', + '#endif', '};', event =3D e.api(e.QEMU_EVENT), vcpu_id =3D vcpu_id, name =3D e.name, sstate =3D "TRACE_%s_ENABLED" % e.name.upper(), - dstate =3D e.api(e.QEMU_DSTATE)) + dstate =3D e.api(e.QEMU_DSTATE), + is_instr=3Dis_instr, + instr_cb=3Dinstr_cb, + instr_cb_default=3Dinstr_cb_default) =20 out('TraceEvent *%(group)s_trace_events[] =3D {', group =3D group.lower()) diff --git a/scripts/tracetool/format/instr_api_h.py b/scripts/tracetool/fo= rmat/instr_api_h.py index d85f64df45..812a5d44ec 100644 --- a/scripts/tracetool/format/instr_api_h.py +++ b/scripts/tracetool/format/instr_api_h.py @@ -40,13 +40,24 @@ def generate(events, backend, group): '') =20 for e in events: + if "disable" in e.properties: + enabled =3D 0 + else: + enabled =3D 1 + if "tcg-trans" in e.properties: args =3D tracetool.vcpu.transform_args("tcg_h", e.original) args =3D args.transform(TCG_2_QI_TCG) else: args =3D e.args.transform(TCG_2_QI_TCG) - out('QI_VPUBLIC void %(nop)s(%(args)s);', + + out('#define %(qeventu)s_ENABLED %(enabled)d', + 'extern QI_VPUBLIC QIEvent *%(event)s;', + 'QI_VPUBLIC void %(nop)s(%(args)s);', 'QI_VPUBLIC void %(trace)s(%(args)s);', + qeventu=3De.api(e.QI_TRACE_INSTRUMENT).upper(), + enabled=3Denabled, + event=3De.api(e.QI_TRACE_INSTRUMENT).upper(), args=3Dargs, nop=3De.api(e.QI_TRACE_NOP), trace=3De.api(e.QI_TRACE_TRACE)) diff --git a/trace/event-internal.h b/trace/event-internal.h index f63500b37e..b12cc110b6 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-2016 Llu=C3=ADs Vilanova + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova * * This work is licensed under the terms of the GNU GPL, version 2 or late= r. * See the COPYING file in the top-level directory. @@ -23,6 +23,9 @@ * @name: Event name. * @sstate: Static tracing state. * @dstate: Dynamic tracing state + * @is_instr: Whether the event is instrumentable. + * @instr_cb: Current instrumentation callback. + * @instr_cb_default: Default instrumentation callback. * * Interpretation of @dstate depends on whether the event has the 'vcpu' * property: @@ -37,6 +40,11 @@ typedef struct TraceEvent { const char * name; const bool sstate; uint16_t *dstate; +#if defined(CONFIG_INSTRUMENT) + bool is_instr; + void **instr_cb; + void *instr_cb_default; +#endif } TraceEvent; =20 void trace_event_set_state_dynamic_init(TraceEvent *ev, bool state); From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500917570136353.59039288306747; Mon, 24 Jul 2017 10:32:50 -0700 (PDT) Received: from localhost ([::1]:56087 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhDr-0004J7-9f for importer@patchew.org; Mon, 24 Jul 2017 13:32:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35944) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhC4-0003D2-Bh for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:30:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZhBz-0004OF-Bo for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:30:56 -0400 Received: from roura.ac.upc.edu ([147.83.33.10]:34094 helo=roura.ac.upc.es) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhBy-0004Nv-Rl for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:30:51 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHUme7032637; Mon, 24 Jul 2017 19:30:48 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id B6A2E1759; Mon, 24 Jul 2017 19:30:42 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:30:41 +0300 Message-Id: <150091744146.30739.9284399356256394869.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHUme7032637 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 07/13] instrument: Add generic command line library loader X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- instrument/Makefile.objs | 1=20 instrument/cmdline.c | 117 ++++++++++++++++++++++++++++++++++++++++++= ++++ instrument/cmdline.h | 58 +++++++++++++++++++++++ 3 files changed, 176 insertions(+) create mode 100644 instrument/cmdline.c create mode 100644 instrument/cmdline.h diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index 244936aa8c..aa6db29ff4 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -43,3 +43,4 @@ $(obj)/qemu-instr/events.h-timestamp: $(BUILD_DIR)/trace-= events-all $(BUILD_DIR) # Control code =20 target-obj-y +=3D control.o +target-obj-y +=3D cmdline.o diff --git a/instrument/cmdline.c b/instrument/cmdline.c new file mode 100644 index 0000000000..e0c0e9ce1b --- /dev/null +++ b/instrument/cmdline.c @@ -0,0 +1,117 @@ +/* + * Control dynamic trace instrumentation during program (de)initialization. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include +#include "instrument/cmdline.h" +#include "instrument/control.h" +#include "qemu/config-file.h" +#include "qemu/error-report.h" + + +QemuOptsList qemu_instr_opts =3D { + .name =3D "instrument", + .implied_opt_name =3D "file", + .merge_lists =3D true, + .head =3D QTAILQ_HEAD_INITIALIZER(qemu_instr_opts.head), + .desc =3D { + { + .name =3D "file", + .type =3D QEMU_OPT_STRING, + },{ + .name =3D "arg", + .type =3D QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + +void instr_opt_parse(const char *optarg, char **path, + int *argc, const char ***argv) +{ + const char *arg; + QemuOptsIter iter; + QemuOpts *opts =3D qemu_opts_parse_noisily(qemu_find_opts("instrument"= ), + optarg, true); + if (!opts) { + exit(1); + } else { +#if !defined(CONFIG_INSTRUMENT) + error_report("instrumentation not enabled on this build"); + exit(1); +#endif + } + + + arg =3D qemu_opt_get(opts, "file"); + if (arg !=3D NULL) { + g_free(*path); + *path =3D g_strdup(arg); + } + + qemu_opt_iter_init(&iter, opts, "arg"); + while ((arg =3D qemu_opt_iter_next(&iter)) !=3D NULL) { + *argv =3D realloc(*argv, sizeof(**argv) * (*argc + 1)); + (*argv)[*argc] =3D g_strdup(arg); + (*argc)++; + } + + qemu_opts_del(opts); +} + + +void instr_init(const char *path, int argc, const char **argv) +{ + InstrLoadError err; + int64_t handle; + + if (path =3D=3D NULL) { + return; + } + + if (atexit(instr_fini) !=3D 0) { + fprintf(stderr, "error: atexit: %s\n", strerror(errno)); + abort(); + } + + err =3D instr_load(path, argc, argv, &handle); + switch (err) { + case INSTR_LOAD_OK: + return; + case INSTR_LOAD_UNAVAILABLE: + error_report("instrument: not available"); + break; + case INSTR_LOAD_ERROR: + error_report("instrument: error loading library: %s", dlerror()); + break; + } + + exit(1); +} + +void instr_fini(void) +{ + InstrUnloadError err =3D instr_unload_all(); + + switch (err) { + case INSTR_UNLOAD_OK: + return; + case INSTR_UNLOAD_UNAVAILABLE: + error_report("instrument: not available"); + break; + case INSTR_UNLOAD_INVALID: + /* the user might have already unloaded it */ + return; + case INSTR_UNLOAD_ERROR: + error_report("instrument: error unloading library: %s", dlerror()); + break; + } + + exit(1); +} diff --git a/instrument/cmdline.h b/instrument/cmdline.h new file mode 100644 index 0000000000..c5eebf8b58 --- /dev/null +++ b/instrument/cmdline.h @@ -0,0 +1,58 @@ +/* + * Control dynamic trace instrumentation during program (de)initialization. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#ifndef INSTRUMENT__CMDLINE_H +#define INSTRUMENT__CMDLINE_H + + +/** + * Definition of QEMU options describing instrumentation subsystem + * configuration. + */ +extern QemuOptsList qemu_instr_opts; + +/** + * instr_opt_parse: + * @optarg: A string argument of --instrument command line argument + * + * Initialize instrument subsystem. + */ +void instr_opt_parse(const char *optarg, char **path, + int *argc, const char ***argv); + +/** + * instr_init: + * @path: Path to dynamic trace instrumentation library. + * @argc: Number of arguments to the library's #qi_init routine. + * @argv: Arguments to the library's #qi_init routine. + * + * Load and initialize the given instrumentation library. + * + * Automatically installs #instr_fini as an atexit callback. + * + * If path is %NULL and we're running with static instrumentation, the lib= rary + * is not loaded but just initialized. + * + * Pre-condition: There is no library already loaded. + */ +void instr_init(const char *path, int argc, const char **argv); + +/** + * instr_fini: + * + * Deinitialize and unload the current instrumentation library. + * + * If we're running with static instrumentation, the library is not unload= ed but + * just deinitialized. + * + * Pre-condition: There is an already loaded library. + */ +void instr_fini(void); + +#endif /* INSTRUMENT__CMDLINE_H */ From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500917817050887.52963091632; Mon, 24 Jul 2017 10:36:57 -0700 (PDT) Received: from localhost ([::1]:56112 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhHq-0007C8-Ix for importer@patchew.org; Mon, 24 Jul 2017 13:36:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37724) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhG5-0006Bc-UD for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:35:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZhG2-0006yz-QT for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:35:05 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:55932) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhG2-0006xM-DP for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:35:02 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHYoOW032751; Mon, 24 Jul 2017 19:34:50 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id C89181759; Mon, 24 Jul 2017 19:34:44 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:34:43 +0300 Message-Id: <150091768344.30739.12305583596427638085.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHYoOW032751 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 08/13] instrument: [linux-user] Add command line library loader X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Riku Voipio , "Emilio G. Cota" , Laurent Vivier , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- linux-user/main.c | 20 ++++++++++++++++++++ linux-user/syscall.c | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/linux-user/main.c b/linux-user/main.c index ad03c9e8b2..fdb7ddb199 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -36,6 +36,8 @@ #include "exec/log.h" #include "trace/control.h" #include "glib-compat.h" +#include "instrument/cmdline.h" +#include "instrument/control.h" =20 char *exec_path; =20 @@ -4014,6 +4016,17 @@ static void handle_arg_trace(const char *arg) trace_file =3D trace_opt_parse(arg); } =20 +static char *instrument_path; +static int instrument_argc; +static const char **instrument_argv; +#if defined(CONFIG_INSTRUMENT) +static void handle_arg_instrument(const char *arg) +{ + instr_opt_parse(arg, &instrument_path, + &instrument_argc, &instrument_argv); +} +#endif + struct qemu_argument { const char *argv; const char *env; @@ -4063,6 +4076,10 @@ static const struct qemu_argument arg_table[] =3D { "", "Seed for pseudo-random number generator"}, {"trace", "QEMU_TRACE", true, handle_arg_trace, "", "[[enable=3D]][,events=3D][,file=3D]"}, +#if defined(CONFIG_INSTRUMENT) + {"instr", "QEMU_INSTR", true, handle_arg_instrument, + "", "[file=3D][,arg=3D]"}, +#endif {"version", "QEMU_VERSION", false, handle_arg_version, "", "display version information and exit"}, {NULL, NULL, false, NULL, NULL, NULL} @@ -4252,6 +4269,7 @@ int main(int argc, char **argv, char **envp) srand(time(NULL)); =20 qemu_add_opts(&qemu_trace_opts); + qemu_add_opts(&qemu_instr_opts); =20 optind =3D parse_args(argc, argv); =20 @@ -4260,6 +4278,8 @@ int main(int argc, char **argv, char **envp) } trace_init_file(trace_file); =20 + instr_init(instrument_path, instrument_argc, instrument_argv); + /* Zero out regs */ memset(regs, 0, sizeof(struct target_pt_regs)); =20 diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 003943b736..cf7071bd35 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -115,6 +115,8 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #include "uname.h" =20 #include "qemu.h" +#include "instrument/cmdline.h" + =20 #ifndef CLONE_IO #define CLONE_IO 0x80000000 /* Clone io context */ @@ -7765,6 +7767,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 =3D 0; /* avoid warning */ break; @@ -9821,6 +9824,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long = arg1, _mcleanup(); #endif gdb_exit(cpu_env, arg1); + instr_fini(); ret =3D get_errno(exit_group(arg1)); break; #endif From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 150091803960723.929508327903363; Mon, 24 Jul 2017 10:40:39 -0700 (PDT) Received: from localhost ([::1]:56130 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhLR-00019E-US for importer@patchew.org; Mon, 24 Jul 2017 13:40:37 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38990) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhJr-00006i-20 for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:39:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZhJn-0000gV-WB for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:38:59 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:38485) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhJn-0000gF-JG for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:38:55 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHcqLZ000399; Mon, 24 Jul 2017 19:38:52 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 3EAAC16F2; Mon, 24 Jul 2017 19:38:47 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:38:45 +0300 Message-Id: <150091792554.30739.5632278947752078528.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHcqLZ000399 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 09/13] instrument: [bsd-user] Add command line library loader X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- bsd-user/main.c | 16 ++++++++++++++++ bsd-user/syscall.c | 5 +++++ 2 files changed, 21 insertions(+) diff --git a/bsd-user/main.c b/bsd-user/main.c index fa9c012c9f..37bf6a435c 100644 --- a/bsd-user/main.c +++ b/bsd-user/main.c @@ -33,6 +33,8 @@ #include "exec/log.h" #include "trace/control.h" #include "glib-compat.h" +#include "instrument/cmdline.h" +#include "instrument/control.h" =20 int singlestep; unsigned long mmap_min_addr; @@ -666,6 +668,11 @@ static void usage(void) "-B address set guest_base address to address\n" "-bsd type select emulated BSD type FreeBSD/NetBSD/Open= BSD (default)\n" "\n" +#if defined(CONFIG_INSTRUMENT) + "-instr [file=3D][,arg=3D]\n" + " load an 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" @@ -735,6 +742,9 @@ int main(int argc, char **argv) envlist_t *envlist =3D NULL; char *trace_file =3D NULL; bsd_type =3D target_openbsd; + char *instrument_path =3D NULL; + int instrument_argc =3D 0; + const char **instrument_argv =3D NULL; =20 if (argc <=3D 1) usage(); @@ -753,6 +763,7 @@ int main(int argc, char **argv) cpu_model =3D NULL; =20 qemu_add_opts(&qemu_trace_opts); + qemu_add_opts(&qemu_instr_opts); =20 optind =3D 1; for (;;) { @@ -840,6 +851,9 @@ int main(int argc, char **argv) } else if (!strcmp(r, "trace")) { g_free(trace_file); trace_file =3D trace_opt_parse(optarg); + } else if (!strcmp(r, "instr")) { + instr_opt_parse(optarg, &instrument_path, + &instrument_argc, &instrument_argv); } else { usage(); } @@ -869,6 +883,8 @@ int main(int argc, char **argv) } trace_init_file(trace_file); =20 + instr_init(instrument_path, instrument_argc, instrument_argv); + /* Zero out regs */ memset(regs, 0, sizeof(struct target_pt_regs)); =20 diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c index 66492aaf5d..3230f722f3 100644 --- a/bsd-user/syscall.c +++ b/bsd-user/syscall.c @@ -26,6 +26,8 @@ =20 #include "qemu.h" #include "qemu-common.h" +#include "instrument/cmdline.h" + =20 //#define DEBUG =20 @@ -332,6 +334,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 =3D 0; /* avoid warning */ @@ -430,6 +433,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 =3D 0; /* avoid warning */ @@ -505,6 +509,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 =3D 0; /* avoid warning */ From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500918238962995.3182737678408; Mon, 24 Jul 2017 10:43:58 -0700 (PDT) Received: from localhost ([::1]:56143 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhOd-0002YD-18 for importer@patchew.org; Mon, 24 Jul 2017 13:43:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40100) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhNl-0002E0-R5 for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:43:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZhNi-0002fY-Ke for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:43:01 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:38522) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhNi-0002eX-89 for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:42:58 -0400 Received: from correu-2.ac.upc.es (correu-2.ac.upc.es [147.83.30.92]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHgtK5000533; Mon, 24 Jul 2017 19:42:55 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-2.ac.upc.es (Postfix) with ESMTPSA id 72140358; Mon, 24 Jul 2017 19:42:49 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:42:48 +0300 Message-Id: <150091816800.30739.7702589627052162702.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHgtK5000533 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 10/13] instrument: [softmmu] Add command line library loader X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini , "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- qemu-options.hx | 17 +++++++++++++++++ vl.c | 11 +++++++++++ 2 files changed, 28 insertions(+) diff --git a/qemu-options.hx b/qemu-options.hx index 9bd6bf0eee..aacd01cee7 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4064,6 +4064,23 @@ HXCOMM HX does not support conditional compilation o= f text. @findex -trace @include qemu-option-trace.texi ETEXI +DEF("instr", HAS_ARG, QEMU_OPTION_instr, + "-instr [file=3D][,arg=3D]\n" + " load an instrumentation library\n", + QEMU_ARCH_ALL) +STEXI +@item -instr file=3D@var{file}[,arg=3D@var{string}] +@findex -instr + +Load a dynamic trace instrumentation library. + +@table @option +@item file=3D@var{file} +Load the given dynamic trace instrumentation library. +@item arg=3D@var{string} +String argument passed as to the library's @code{qi_init} routine (can be = given multiple times). +@end table +ETEXI =20 HXCOMM Internal use DEF("qtest", HAS_ARG, QEMU_OPTION_qtest, "", QEMU_ARCH_ALL) diff --git a/vl.c b/vl.c index fb6b2efafa..1a24b34d47 100644 --- a/vl.c +++ b/vl.c @@ -118,6 +118,7 @@ int main(int argc, char **argv) =20 #include "trace-root.h" #include "trace/control.h" +#include "instrument/cmdline.h" #include "qemu/queue.h" #include "sysemu/arch_init.h" =20 @@ -3031,6 +3032,9 @@ int main(int argc, char **argv, char **envp) } BlockdevOptions_queue; QSIMPLEQ_HEAD(, BlockdevOptions_queue) bdo_queue =3D QSIMPLEQ_HEAD_INITIALIZER(bdo_queue); + char *instrument_path =3D NULL; + int instrument_argc =3D 0; + const char **instrument_argv =3D NULL; =20 module_call_init(MODULE_INIT_TRACE); =20 @@ -3058,6 +3062,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_accel_opts); @@ -3999,6 +4004,10 @@ int main(int argc, char **argv, char **envp) g_free(trace_file); trace_file =3D trace_opt_parse(optarg); break; + case QEMU_OPTION_instr: + instr_opt_parse(optarg, &instrument_path, + &instrument_argc, &instrument_argv); + break; case QEMU_OPTION_readconfig: { int ret =3D qemu_read_config_file(optarg); @@ -4185,6 +4194,8 @@ int main(int argc, char **argv, char **envp) } trace_init_file(trace_file); =20 + instr_init(instrument_path, instrument_argc, instrument_argv); + /* Open the logfile at this point and set the log mask if necessary. */ if (log_file) { From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500918481593590.7498765253767; Mon, 24 Jul 2017 10:48:01 -0700 (PDT) Received: from localhost ([::1]:56155 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhSX-000401-RU for importer@patchew.org; Mon, 24 Jul 2017 13:47:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40801) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhRf-0003hH-H3 for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:47:04 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZhRc-0004Ay-DS for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:47:03 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:35543) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhRc-0004Al-11 for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:47:00 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHkvA6000622; Mon, 24 Jul 2017 19:46:57 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 849DC1759; Mon, 24 Jul 2017 19:46:51 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:46:50 +0300 Message-Id: <150091841019.30739.3661641061220051037.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHkvA6000622 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 11/13] instrument: [qapi] Add library loader X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Markus Armbruster , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- instrument/Makefile.objs | 1 + instrument/qmp.c | 71 ++++++++++++++++++++++++++++++++++++ qapi-schema.json | 3 ++ qapi/instrument.json | 92 ++++++++++++++++++++++++++++++++++++++++++= ++++ 4 files changed, 167 insertions(+) create mode 100644 instrument/qmp.c create mode 100644 qapi/instrument.json diff --git a/instrument/Makefile.objs b/instrument/Makefile.objs index aa6db29ff4..757a247321 100644 --- a/instrument/Makefile.objs +++ b/instrument/Makefile.objs @@ -44,3 +44,4 @@ $(obj)/qemu-instr/events.h-timestamp: $(BUILD_DIR)/trace-= events-all $(BUILD_DIR) =20 target-obj-y +=3D control.o target-obj-y +=3D cmdline.o +target-obj-y +=3D qmp.o diff --git a/instrument/qmp.c b/instrument/qmp.c new file mode 100644 index 0000000000..3f577e0c78 --- /dev/null +++ b/instrument/qmp.c @@ -0,0 +1,71 @@ +/* + * QMP interface for dynamic trace instrumentation control commands. + * + * Copyright (C) 2012-2017 Llu=C3=ADs Vilanova + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qapi/qmp/qerror.h" +#include "qmp-commands.h" + +#include + +#include "instrument/control.h" + + + +InstrLoadResult *qmp_instr_load(const char * path, + bool have_args, StringList * args, + Error **errp) +{ + int argc =3D 0; + const char **argv =3D NULL; + + StringList *entry =3D have_args ? args : NULL; + while (entry !=3D NULL) { + argv =3D realloc(argv, sizeof(*argv) * (argc + 1)); + argv[argc] =3D entry->value->str; + argc++; + entry =3D entry->next; + } + + InstrLoadResult *res =3D g_malloc0(sizeof(*res)); + res->code =3D instr_load(path, argc, argv, &res->handle); + switch (res->code) { + case INSTR_LOAD_CODE_OK: + case INSTR_LOAD_CODE_UNAVAILABLE: + break; + case INSTR_LOAD_CODE_ERROR: + res->msg =3D dlerror(); + break; + default: + fprintf(stderr, "Unknown instrumentation load code: %d", res->code= ); + exit(1); + break; + } + return res; +} + +InstrUnloadResult *qmp_instr_unload(int64_t handle, Error **errp) +{ + InstrUnloadResult *res =3D g_malloc0(sizeof(*res)); + res->code =3D instr_unload(handle); + switch (res->code) { + case INSTR_UNLOAD_OK: + case INSTR_UNLOAD_UNAVAILABLE: + case INSTR_UNLOAD_INVALID: + break; + case INSTR_UNLOAD_CODE_ERROR: + res->msg =3D dlerror(); + break; + default: + fprintf(stderr, "Unknown instrumentation unload code: %d", res->co= de); + exit(1); + break; + } + return res; +} diff --git a/qapi-schema.json b/qapi-schema.json index ab438ead70..6c4f237af8 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -90,6 +90,9 @@ # QAPI introspection { 'include': 'qapi/introspect.json' } =20 +# Instrumentation commands +{ 'include': 'qapi/instrument.json' } + ## # =3D QMP commands ## diff --git a/qapi/instrument.json b/qapi/instrument.json new file mode 100644 index 0000000000..f0d725e9a9 --- /dev/null +++ b/qapi/instrument.json @@ -0,0 +1,92 @@ +# *-*- Mode: Python -*-* +# +# QAPI trace instrumentation control commands. +# +# Copyright (C) 2012-2017 Llu=C3=ADs Vilanova +# +# This work is licensed under the terms of the GNU GPL, version 2 or later. +# See the COPYING file in the top-level directory. + +## +# @InstrLoadCode: +# +# Result code of an 'instr-load' command. +# +# @ok: Correctly loaded. +# @unavailable: Service not available. +# @error: Error with libdl (see 'msg'). +# +# Since: 2.10 +## +{ 'enum': 'InstrLoadCode', + 'data': [ 'ok', 'unavailable', 'error' ] } + +## +# @InstrLoadResult: +# +# Result of an 'instr-load' command. +# +# @code: Result code. +# @msg: Additional error message. +# @handle: Instrumentation library identifier (undefined in case of error). +# +# Since: 2.10 +## +{ 'struct': 'InstrLoadResult', + 'data': { 'code': 'InstrLoadCode', 'msg': 'str', 'handle': 'int' } } + +## +# @instr-load: +# +# Load an instrumentation library. +# +# @path: path to the dynamic instrumentation library +# @args: arguments to the dynamic instrumentation library +# +# Since: 2.10 +## +{ 'command': 'instr-load', + 'data': { 'path': 'str', '*args': ['String'] }, + 'returns': 'InstrLoadResult' } + + +## +# @InstrUnloadCode: +# +# Result code of an 'instr-unload' command. +# +# @ok: Correctly unloaded. +# @unavailable: Service not available. +# @invalid: Invalid handle. +# @error: Error with libdl (see 'msg'). +# +# Since: 2.10 +## +{ 'enum': 'InstrUnloadCode', + 'data': [ 'ok', 'unavailable', 'invalid', 'error' ] } + +## +# @InstrUnloadResult: +# +# Result of an 'instr-unload' command. +# +# @code: Result code. +# @msg: Additional error message. +# +# Since: 2.10 +## +{ 'struct': 'InstrUnloadResult', + 'data': { 'code': 'InstrUnloadCode', 'msg': 'str' } } + +## +# @instr-unload: +# +# Unload an instrumentation library. +# +# @handle: Instrumentation library identifier (see #InstrLoadResult). +# +# Since: 2.10 +## +{ 'command': 'instr-unload', + 'data': { 'handle': 'int' }, + 'returns': 'InstrUnloadResult' } From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500918758371489.3080166812408; Mon, 24 Jul 2017 10:52:38 -0700 (PDT) Received: from localhost ([::1]:56168 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhX1-0005au-Nx for importer@patchew.org; Mon, 24 Jul 2017 13:52:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41417) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhVb-00051K-MW for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:51:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZhVW-00060x-R1 for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:51:07 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:35840) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhVW-00060i-Ec for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:51:02 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHoxFJ000751; Mon, 24 Jul 2017 19:50:59 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id CD41D176C; Mon, 24 Jul 2017 19:50:53 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:50:52 +0300 Message-Id: <150091865221.30739.8093437461715631283.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHoxFJ000751 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 12/13] instrument: [hmp] Add library loader X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , "Dr. David Alan Gilbert" , Stefan Hajnoczi , Markus Armbruster Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Signed-off-by: Llu=C3=ADs Vilanova --- hmp-commands.hx | 28 ++++++++++++++++++++++++++++ monitor.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 83 insertions(+) diff --git a/hmp-commands.hx b/hmp-commands.hx index 1941e19932..b1f3a75ab0 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1858,6 +1858,34 @@ ETEXI .sub_table =3D info_cmds, }, =20 + { + .name =3D "instr-load", + .args_type =3D "path:F,args:s?", + .params =3D "path [args]", + .help =3D "load an instrumentation library", + .cmd =3D hmp_instr_load, + }, + +STEXI +@item instr-load @var{path} [args=3Dvalue[,...]] +@findex instr-load +Load an instrumentation library. +ETEXI + + { + .name =3D "instr-unload", + .args_type =3D "handle:i", + .params =3D "", + .help =3D "unload an instrumentation library", + .cmd =3D hmp_instr_unload, + }, + +STEXI +@item instr-unload +@findex instr-unload +Unload an instrumentation library. +ETEXI + STEXI @end table ETEXI diff --git a/monitor.c b/monitor.c index 6d040e620f..4784356798 100644 --- a/monitor.c +++ b/monitor.c @@ -2319,6 +2319,61 @@ int monitor_fd_param(Monitor *mon, const char *fdnam= e, Error **errp) return fd; } =20 +static void hmp_instr_load(Monitor *mon, const QDict *qdict) +{ + const char *path =3D qdict_get_str(qdict, "path"); + String str; + str.str =3D (char *)qdict_get_try_str(qdict, "args"); + StringList args; + args.value =3D str.str =3D=3D NULL ? NULL : &str; + args.next =3D NULL; + InstrLoadResult *res =3D qmp_instr_load(path, args.value !=3D NULL, + args.value !=3D NULL ? &args : N= ULL, + NULL); + switch (res->code) { + case INSTR_LOAD_CODE_OK: + monitor_printf(mon, "Handle: %"PRId64"\n", res->handle); + monitor_printf(mon, "OK\n"); + break; + case INSTR_LOAD_CODE_UNAVAILABLE: + monitor_printf(mon, "Not available\n"); + break; + case INSTR_LOAD_CODE_ERROR: + monitor_printf(mon, "Error loading library: %s\n", res->msg); + break; + default: + fprintf(stderr, "Unknown instrumentation load code: %d", res->code= ); + exit(1); + break; + } + qapi_free_InstrLoadResult(res); +} + +static void hmp_instr_unload(Monitor *mon, const QDict *qdict) +{ + int64_t handle =3D qdict_get_int(qdict, "handle"); + InstrUnloadResult *res =3D qmp_instr_unload(handle, NULL); + switch (res->code) { + case INSTR_UNLOAD_CODE_OK: + monitor_printf(mon, "OK\n"); + break; + case INSTR_UNLOAD_CODE_UNAVAILABLE: + monitor_printf(mon, "Not available\n"); + break; + case INSTR_UNLOAD_CODE_INVALID: + monitor_printf(mon, "Invalid handle\n"); + break; + case INSTR_UNLOAD_CODE_ERROR: + monitor_printf(mon, "Error unloading library: %s\n", res->msg); + break; + default: + fprintf(stderr, "Unknown instrumentation unload code: %d", res->co= de); + exit(1); + break; + } + qapi_free_InstrUnloadResult(res); +} + /* Please update hmp-commands.hx when adding or changing commands */ static mon_cmd_t info_cmds[] =3D { #include "hmp-commands-info.h" From nobody Wed Nov 5 00:46:02 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1500918983881597.6885052732985; Mon, 24 Jul 2017 10:56:23 -0700 (PDT) Received: from localhost ([::1]:56183 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhaf-0006yD-IF for importer@patchew.org; Mon, 24 Jul 2017 13:56:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42312) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhZW-0006N8-9z for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:55:11 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dZhZR-0007VA-F6 for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:55:10 -0400 Received: from roura.ac.upc.es ([147.83.33.10]:54108) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZhZR-0007U6-3P for qemu-devel@nongnu.org; Mon, 24 Jul 2017 13:55:05 -0400 Received: from correu-1.ac.upc.es (correu-1.ac.upc.es [147.83.30.91]) by roura.ac.upc.es (8.13.8/8.13.8) with ESMTP id v6OHt1Bq000845; Mon, 24 Jul 2017 19:55:01 +0200 Received: from localhost (unknown [31.210.188.120]) by correu-1.ac.upc.es (Postfix) with ESMTPSA id 0364A176C; Mon, 24 Jul 2017 19:54:55 +0200 (CEST) From: =?utf-8?b?TGx1w61z?= Vilanova To: qemu-devel@nongnu.org Date: Mon, 24 Jul 2017 20:54:54 +0300 Message-Id: <150091889458.30739.16324719944323757435.stgit@frigg.lan> X-Mailer: git-send-email 2.13.2 In-Reply-To: <150091574424.30739.4131793221953168474.stgit@frigg.lan> References: <150091574424.30739.4131793221953168474.stgit@frigg.lan> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-MIME-Autoconverted: from 8bit to quoted-printable by roura.ac.upc.es id v6OHt1Bq000845 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x [fuzzy] X-Received-From: 147.83.33.10 Subject: [Qemu-devel] [PATCH 13/13] trace: Rename C++-specific names in event arguments X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "Emilio G. Cota" , Stefan Hajnoczi Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Allows instrumentation clients in C++ to use the auto-generated headers. Signed-off-by: Llu=C3=ADs Vilanova --- scripts/tracetool/__init__.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 7c19dc8c94..be7f28d2be 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -42,6 +42,8 @@ def out(*lines, **kwargs): sys.stdout.writelines("\n".join(lines) + "\n") =20 =20 +FORBIDDEN =3D ["new", "class"] + class Arguments: """Event arguments description.""" =20 @@ -85,6 +87,9 @@ class Arguments: else: arg_type, identifier =3D arg.rsplit(None, 1) =20 + if identifier in FORBIDDEN: + identifier +=3D "_" + res.append((arg_type, identifier)) return Arguments(res) =20 @@ -230,7 +235,10 @@ class Event(object): fmt_trans =3D groups["fmt_trans"] if len(fmt_trans) > 0: fmt =3D [fmt_trans, fmt] - args =3D Arguments.build(groups["args"]) + try: + args =3D Arguments.build(groups["args"]) + except ForbiddenArgumentError as e: + error("Error: event '%s' uses forbidden argument name '%s'" % = (name, e.name)) =20 if "tcg-trans" in props: raise ValueError("Invalid property 'tcg-trans'")