From patchwork Mon Jul 24 17:14:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Llu=C3=ADs_Vilanova?= X-Patchwork-Id: 9859873 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CC941601A1 for ; Mon, 24 Jul 2017 17:15:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B021726E55 for ; Mon, 24 Jul 2017 17:15:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A4A0B28585; Mon, 24 Jul 2017 17:15:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9C97126E55 for ; Mon, 24 Jul 2017 17:15:39 +0000 (UTC) Received: from localhost ([::1]:56028 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dZgxG-0004yT-MW for patchwork-qemu-devel@patchwork.kernel.org; Mon, 24 Jul 2017 13:15:38 -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 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+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP This mode uses a function pointer in "trace_*" routines. By default, it points to the original tracing function (now "_backend__trace_*"). Signed-off-by: Lluís 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 INSTRUMENT_HEADERS = instrument-root.h $(trace-events-subdirs:%=%/instrument.h) INSTRUMENT_HEADERS += instrument/generated-tcg-tracers.h +INSTRUMENT_SOURCES = instrument-root.c $(trace-events-subdirs:%=%/instrument.c) +INSTRUMENT_SOURCES += instrument/generated-tcg-tracers.c GENERATED_FILES += $(INSTRUMENT_HEADERS) +GENERATED_FILES += $(INSTRUMENT_SOURCES) %/instrument.h: %/instrument.h-timestamp @cmp $< $@ >/dev/null 2>&1 || cp $< $@ @@ -205,6 +208,15 @@ GENERATED_FILES += $(INSTRUMENT_HEADERS) --backends=$(TRACE_INSTRUMENT_BACKEND) \ $< > $@,"GEN","$(@:%-timestamp=%)") +%/instrument.c: %/instrument.c-timestamp + @cmp $< $@ >/dev/null 2>&1 || cp $< $@ +%/instrument.c-timestamp: $(SRC_PATH)/%/trace-events $(BUILD_DIR)/config-host.mak $(tracetool-y) + $(call quiet-command,$(TRACETOOL) \ + --group=$(call trace-group-name,$@) \ + --format=instr-c \ + --backends=$(TRACE_INSTRUMENT_BACKEND) \ + $< > $@,"GEN","$(@:%-timestamp=%)") + 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=$(TRACE_INSTRUMENT_BACKEND) \ $< > $@,"GEN","$(@:%-timestamp=%)") +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=root \ + --format=instr-c \ + --backends=$(TRACE_INSTRUMENT_BACKEND) \ + $< > $@,"GEN","$(@:%-timestamp=%)") + # 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 libqemustub.a: $(stub-obj-y) -libqemuutil.a: $(util-obj-y) $(trace-obj-y) +libqemuutil.a: $(util-obj-y) $(trace-obj-y) $(instr-obj-y) ###################################################################### @@ -830,7 +851,8 @@ endif .SECONDARY: $(TRACE_HEADERS) $(TRACE_HEADERS:%=%-timestamp) \ $(TRACE_SOURCES) $(TRACE_SOURCES:%=%-timestamp) \ $(TRACE_DTRACE) $(TRACE_DTRACE:%=%-timestamp) \ - $(INSTRUMENT_HEADERS) $(INSTRUMENT_HEADERS:%=%-timestamp) + $(INSTRUMENT_HEADERS) $(INSTRUMENT_HEADERS:%=%-timestamp) \ + $(INSTRUMENT_SOURCES) $(INSTRUMENT_SOURCES:%=%-timestamp) # 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 += trace/ ###################################################################### # instrumentation util-obj-y += instrument/ +target-obj-y += instrument/ ###################################################################### # guest agent @@ -180,3 +181,6 @@ trace-obj-y += $(trace-events-subdirs:%=%/trace.o) trace-obj-$(CONFIG_TRACE_UST) += trace-ust-all.o trace-obj-$(CONFIG_TRACE_DTRACE) += trace-dtrace-root.o trace-obj-$(CONFIG_TRACE_DTRACE) += $(trace-events-subdirs:%=%/trace-dtrace.o) + +instr-obj-$(CONFIG_INSTRUMENT) = instrument-root.o +instr-obj-y += $(trace-events-subdirs:%=%/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=*) trace_file="$optarg" ;; + --enable-trace-instrument) + trace_instrument="yes" + trace_instrument_backend="dynamic" + ;; --enable-gprof) gprof="yes" ;; --enable-gcov) gcov="yes" @@ -1427,6 +1431,8 @@ Advanced options (experts only): Available backends: $trace_backend_list --with-trace-file=NAME 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="-I\$(SRC_PATH)/tcg $QEMU_INCLUDES" ########################################## # trace instrumentation echo "TRACE_INSTRUMENT_BACKEND=instr-$trace_instrument_backend" >> $config_host_mak +if test "$trace_instrument" = "yes"; then + echo "CONFIG_INSTRUMENT=y" >> $config_host_mak +fi ########################################## echo "TOOLS=$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)/trace-events $(BUILD_DIR)/ --format=instr-tcg-h \ --backend=$(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=root \ + --format=instr-tcg-c \ + --backend=$(TRACE_INSTRUMENT_BACKEND) \ + $< > $@,"GEN","$(patsubst %-timestamp,%,$@)") + +target-obj-$(CONFIG_INSTRUMENT) += 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 = "_TRACE_%(NAME)s_DSTATE" QEMU_EVENT = "_TRACE_%(NAME)s_EVENT" + QI_TRACE_INSTRUMENT = "qi_event_%(name)s" + QI_TRACE_INSTRUMENT_TCG = QI_TRACE_INSTRUMENT + "_tcg" + def api(self, fmt=None): if fmt is None: fmt = 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__ = "Lluís Vilanova " +__copyright__ = "Copyright 2012-2017, Lluís Vilanova " +__license__ = "GPL version 2 or (at your option) any later version" + +__maintainer__ = "Stefan Hajnoczi" +__email__ = "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=event.api(event.QI_TRACE_INSTRUMENT)) + out('') + + +def generate_instr_h(event, group): + argtypes = ", ".join(event.args.types()) + if argtypes == "": + argtypes = "void" + out(' void (*func)(%(argtypes)s) = %(qi)s_cb;', + ' func(%(argnames)s);', + qi=event.api(event.QI_TRACE_INSTRUMENT), + args=event.args, + argnames=", ".join(event.args.names()), + argtypes=argtypes) + + +################################################## +# 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=event.api(event.QI_TRACE_INSTRUMENT_TCG)) + out('') + + +def generate_instr_tcg_h(event, group): + argtypes = ", ".join(event.args.types()) + if argtypes == "": + argtypes = "void" + out(' void (*func)(%(argtypes)s) = %(qi)s_cb;', + ' func(%(argnames)s);', + qi=event.api(event.QI_TRACE_INSTRUMENT_TCG), + args=event.args, + argnames=", ".join(event.args.names()), + argtypes=argtypes) 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__ = "Lluís Vilanova " +__copyright__ = "Copyright 2012-2017, Lluís Vilanova " +__license__ = "GPL version 2 or (at your option) any later version" + +__maintainer__ = "Stefan Hajnoczi" +__email__ = "stefanha@linux.vnet.ibm.com" + + +from tracetool import out +from tracetool.transform import * + + +def generate(events, backend, group): + events = [e for e in events + if "tcg-trans" not in e.properties and + "instrument" in e.properties] + + if group == "root": + header = "trace-root.h" + else: + header = "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 = %(qi_trace)s;', + qi_cb=e.api(e.QI_TRACE_INSTRUMENT), + qi_trace=e.api(e.QEMU_TRACE_BACKEND)) + + backend.generate_end(events, group) diff --git a/scripts/tracetool/format/instr_tcg_c.py b/scripts/tracetool/format/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__ = "Lluís Vilanova " +__copyright__ = "Copyright 2012-2017, Lluís Vilanova " +__license__ = "GPL version 2 or (at your option) any later version" + +__maintainer__ = "Stefan Hajnoczi" +__email__ = "stefanha@linux.vnet.ibm.com" + + +from tracetool import out +from tracetool.transform import * + + +def generate(events, backend, group): + events = [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 = %(qi_trace)s;', + qi_cb=e.api(e.QI_TRACE_INSTRUMENT_TCG), + qi_trace=e.api(e.QEMU_TRACE_TCG_BACKEND)) + + backend.generate_end(events, group)