From patchwork Wed Oct 20 14:09:50 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 68442 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 95FE5B70B8 for ; Thu, 21 Oct 2010 01:11:03 +1100 (EST) Received: from localhost ([127.0.0.1]:42194 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P8ZNb-0007P3-8x for incoming@patchwork.ozlabs.org; Wed, 20 Oct 2010 10:10:59 -0400 Received: from [140.186.70.92] (port=53583 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P8ZMq-0007NS-5F for qemu-devel@nongnu.org; Wed, 20 Oct 2010 10:10:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1P8ZMo-0008Pe-85 for qemu-devel@nongnu.org; Wed, 20 Oct 2010 10:10:11 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53063) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1P8ZMn-0008PG-Qo for qemu-devel@nongnu.org; Wed, 20 Oct 2010 10:10:10 -0400 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o9KEA8MY029561 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 20 Oct 2010 10:10:08 -0400 Received: from t500wlan.home.berrange.com.com (vpn2-9-34.ams2.redhat.com [10.36.9.34]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o9KEA6If010329; Wed, 20 Oct 2010 10:10:07 -0400 From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Wed, 20 Oct 2010 15:09:50 +0100 Message-Id: <1287583790-9349-1-git-send-email-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. Cc: Subject: [Qemu-devel] [PATCH v2] Add a DTrace tracing backend targetted for SystemTAP compatability X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This introduces a new tracing backend that targets the SystemTAP implementation of DTrace userspace tracing. The core functionality should be applicable and standard across any DTrace implementation on Solaris, OS-X, *BSD, but the Makefile rules will likely need some small additional changes to cope with OS specific build requirements. This backend builds a little differently from the other tracing backends. Specifically there is no 'trace.c' file, because the 'dtrace' command line tool generates a '.o' file directly from the dtrace probe definition file. The probe definition is usually named with a '.d' extension but QEMU uses '.d' files for its external makefile dependancy tracking, so this uses '.dtrace' as the extension for the probe definition file. The 'tracetool' program gains the ability to generate a trace.h file for DTrace, and also to generate the trace.d file containing the dtrace probe definition, and finally a qemu.stp file which is a wrapper around the probe definition providing more convenient access from SystemTAP scripts. eg, instead of probe process("qemu").mark("qemu_malloc") { printf("Malloc %d %p\n", $arg1, $arg2); } The addition of qemu.stp to /usr/share/systemtap/tapset/ lets users write probe qemu.qemu_malloc { printf("Malloc %d %p\n", size, ptr); } In v2: - Add check for 'dtrace' command in configure - Comply with coding standards in generated code - Misc fixes to tracetool - Add more generated files to make clean target - Mention 'dtrace' backend in configure help Still todo in v3: - Change process("qemu") statement so that it applies to all 'qemu-system-XXX' binaries not just 'qemu' * .gitignore: Ignore trace-dtrace.* * Makefile: Extra rules for generating DTrace files * Makefile.obj: Don't build trace.o for DTrace, use trace-dtrace.o generated by 'dtrace' instead * tracetool: Support for generating DTrace/SystemTAP data files Signed-off-by: Daniel P. Berrange --- .gitignore | 3 + Makefile | 32 +++++++++++ Makefile.objs | 4 ++ configure | 12 ++++- tracetool | 169 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 209 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index a43e4d1..0d27afd 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,9 @@ config-host.* config-target.* trace.h trace.c +trace-dtrace.h +trace-dtrace.dtrace +qemu.stp *-timestamp *-softmmu *-darwin-user diff --git a/Makefile b/Makefile index 252c817..5aa85f6 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,9 @@ # Makefile for QEMU. GENERATED_HEADERS = config-host.h trace.h +ifeq ($(TRACE_BACKEND),dtrace) +GENERATED_HEADERS += trace-dtrace.h +endif ifneq ($(wildcard config-host.mak),) # Put the all: rule here so that config-host.mak can contain dependencies. @@ -106,7 +109,11 @@ ui/vnc.o: QEMU_CFLAGS += $(VNC_TLS_CFLAGS) bt-host.o: QEMU_CFLAGS += $(BLUEZ_CFLAGS) +ifeq ($(TRACE_BACKEND),dtrace) +trace.h: trace.h-timestamp trace-dtrace.h +else trace.h: trace.h-timestamp +endif trace.h-timestamp: $(SRC_PATH)/trace-events config-host.mak $(call quiet-command,sh $(SRC_PATH)/tracetool --$(TRACE_BACKEND) -h < $< > $@," GEN trace.h") @cmp -s $@ trace.h || cp $@ trace.h @@ -118,6 +125,23 @@ trace.c-timestamp: $(SRC_PATH)/trace-events config-host.mak trace.o: trace.c $(GENERATED_HEADERS) +trace-dtrace.h: trace-dtrace.dtrace + $(call quiet-command,dtrace -o $@ -h -s $<, " GEN trace-dtrace.h") + +# Normal practice is to name DTrace probe file with a '.d' extension +# but that gets picked up by QEMU's Makefile as an external dependancy +# rule file. So we use '.dtrace' instead +trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp +trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events config-host.mak + $(call quiet-command,sh $(SRC_PATH)/tracetool --$(TRACE_BACKEND) -d < $< > $@," GEN trace-dtrace.dtrace") + @cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace +ifdef CONFIG_LINUX + $(call quiet-command,sh $(SRC_PATH)/tracetool --$(TRACE_BACKEND) -s < $< > qemu.stp," GEN qemu.stp") +endif + +trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS) + $(call quiet-command,dtrace -o $@ -G -s $<, " GEN trace-dtrace.o") + simpletrace.o: simpletrace.c $(GENERATED_HEADERS) version.o: $(SRC_PATH)/version.rc config-host.mak @@ -154,6 +178,8 @@ clean: rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d rm -f qemu-img-cmds.h rm -f trace.c trace.h trace.c-timestamp trace.h-timestamp + rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp + rm -f trace-dtrace.h trace-dtrace.h-timestamp qemu.stp $(MAKE) -C tests clean for d in $(ALL_SUBDIRS) libhw32 libhw64 libuser libdis libdis-user; do \ if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \ @@ -214,6 +240,12 @@ ifneq ($(BLOBS),) $(INSTALL_DATA) $(SRC_PATH)/pc-bios/$$x "$(DESTDIR)$(datadir)"; \ done endif +ifeq ($(TRACE_BACKEND),dtrace) +ifdef CONFIG_LINUX + $(INSTALL_DIR) "$(DESTDIR)$(datadir)/../systemtap/tapset" + $(INSTALL_DATA) qemu.stp "$(DESTDIR)$(datadir)/../systemtap/tapset" +endif +endif $(INSTALL_DIR) "$(DESTDIR)$(datadir)/keymaps" set -e; for x in $(KEYMAPS); do \ $(INSTALL_DATA) $(SRC_PATH)/pc-bios/keymaps/$$x "$(DESTDIR)$(datadir)/keymaps"; \ diff --git a/Makefile.objs b/Makefile.objs index 816194a..ccecda0 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -273,10 +273,14 @@ libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o ###################################################################### # trace +ifeq ($(TRACE_BACKEND),dtrace) +trace-obj-y = trace-dtrace.o +else trace-obj-y = trace.o ifeq ($(TRACE_BACKEND),simple) trace-obj-y += simpletrace.o endif +endif vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) diff --git a/configure b/configure index a079a49..92bb9c9 100755 --- a/configure +++ b/configure @@ -926,7 +926,7 @@ echo " --enable-docs enable documentation build" echo " --disable-docs disable documentation build" echo " --disable-vhost-net disable vhost-net acceleration support" echo " --enable-vhost-net enable vhost-net acceleration support" -echo " --trace-backend=B Trace backend nop simple ust" +echo " --trace-backend=B Trace backend nop simple ust dtrace" echo " --trace-file=NAME Full PATH,NAME of file to store traces" echo " Default:trace-" echo " --disable-spice disable spice" @@ -2175,6 +2175,16 @@ EOF exit 1 fi fi + +########################################## +# For 'dtrace' backend, test if 'dtrace' command is present +if ! has 'dtrace' ; then + echo + echo "Error: dtrace command is not found in PATH $PATH" + echo + exit 1 +fi + ########################################## # End of CC checks # After here, no more $cc or $ld runs diff --git a/tracetool b/tracetool index 7010858..047f16b 100755 --- a/tracetool +++ b/tracetool @@ -20,10 +20,13 @@ Backends: --nop Tracing disabled --simple Simple built-in backend --ust LTTng User Space Tracing backend + --dtrace DTrace/SystemTAP backend Output formats: -h Generate .h file -c Generate .c file + -d Generate .d file (DTrace only) + -s Generate .stp file (DTrace with SystemTAP only) EOF exit 1 } @@ -46,8 +49,9 @@ get_args() # Get the argument name list of a trace event get_argnames() { - local nfields field name + local nfields field name sep nfields=0 + sep="$2" for field in $(get_args "$1"); do nfields=$((nfields + 1)) @@ -58,7 +62,7 @@ get_argnames() name=${field%,} test "$field" = "$name" && continue - printf "%s" "$name, " + printf "%s%s " $name $sep done # Last argument name @@ -73,7 +77,7 @@ get_argc() { local name argc argc=0 - for name in $(get_argnames "$1"); do + for name in $(get_argnames "$1", ","); do argc=$((argc + 1)) done echo $argc @@ -154,7 +158,7 @@ EOF cast_args_to_uint64_t() { local arg - for arg in $(get_argnames "$1"); do + for arg in $(get_argnames "$1", ","); do printf "%s" "(uint64_t)(uintptr_t)$arg" done } @@ -247,7 +251,7 @@ linetoh_ust() local name args argnames name=$(get_name "$1") args=$(get_args "$1") - argnames=$(get_argnames "$1") + argnames=$(get_argnames "$1", ",") cat <