From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=34809 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PINjq-00065X-6d for qemu-devel@nongnu.org; Tue, 16 Nov 2010 10:46:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PINjn-0000w0-Re for qemu-devel@nongnu.org; Tue, 16 Nov 2010 10:46:30 -0500 Received: from mail-pw0-f45.google.com ([209.85.160.45]:43538) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PINjn-0000vZ-Jx for qemu-devel@nongnu.org; Tue, 16 Nov 2010 10:46:27 -0500 Received: by pwj6 with SMTP id 6so155624pwj.4 for ; Tue, 16 Nov 2010 07:46:26 -0800 (PST) Message-ID: <4CE2A74C.6050302@codemonkey.ws> Date: Tue, 16 Nov 2010 09:46:20 -0600 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH 1/2] Add a DTrace tracing backend targetted for SystemTAP compatability References: <1289244788-19961-1-git-send-email-berrange@redhat.com> <1289244788-19961-2-git-send-email-berrange@redhat.com> In-Reply-To: <1289244788-19961-2-git-send-email-berrange@redhat.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: "Daniel P. Berrange" Cc: qemu-devel@nongnu.org On 11/08/2010 01:33 PM, Daniel P. Berrange wrote: > 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. > > Example usage of a dtrace probe in systemtap looks like: > > probe process("qemu").mark("qemu_malloc") { > printf("Malloc %d %p\n", $arg1, $arg2); > } > > * .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 data files > > Signed-off-by: Daniel P. Berrange > Applied both. Thanks. Regards, Anthony Liguori > --- > .gitignore | 2 + > Makefile | 23 +++++++++++ > Makefile.objs | 4 ++ > configure | 14 ++++++- > tracetool | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- > 5 files changed, 148 insertions(+), 11 deletions(-) > > diff --git a/.gitignore b/.gitignore > index a43e4d1..3efb4ec 100644 > --- a/.gitignore > +++ b/.gitignore > @@ -4,6 +4,8 @@ config-host.* > config-target.* > trace.h > trace.c > +trace-dtrace.h > +trace-dtrace.dtrace > *-timestamp > *-softmmu > *-darwin-user > diff --git a/Makefile b/Makefile > index 02698e9..554ad97 100644 > --- a/Makefile > +++ b/Makefile > @@ -1,6 +1,9 @@ > # Makefile for QEMU. > > GENERATED_HEADERS = config-host.h trace.h qemu-options.def > +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. > @@ -108,7 +111,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 > @@ -120,6 +127,20 @@ 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 > + > +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 > @@ -157,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 > $(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; \ > diff --git a/Makefile.objs b/Makefile.objs > index faf485e..84fc80e 100644 > --- a/Makefile.objs > +++ b/Makefile.objs > @@ -285,11 +285,15 @@ 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 > user-obj-y += qemu-timer-common.o > endif > +endif > > vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS) > > diff --git a/configure b/configure > index 7025d2b..f8dad3e 100755 > --- a/configure > +++ b/configure > @@ -929,7 +929,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" > @@ -2193,6 +2193,18 @@ EOF > exit 1 > fi > fi > + > +########################################## > +# For 'dtrace' backend, test if 'dtrace' command is present > +if test "$trace_backend" = "dtrace"; then > + if ! has 'dtrace' ; then > + echo > + echo "Error: dtrace command is not found in PATH $PATH" > + echo > + exit 1 > + fi > +fi > + > ########################################## > # End of CC checks > # After here, no more $cc or $ld runs > diff --git a/tracetool b/tracetool > index 7010858..5b6636a 100755 > --- a/tracetool > +++ b/tracetool > @@ -20,10 +20,12 @@ 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) > EOF > exit 1 > } > @@ -46,8 +48,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 +61,7 @@ get_argnames() > name=${field%,} > test "$field" = "$name"&& continue > > - printf "%s" "$name, " > + printf "%s%s " $name $sep > done > > # Last argument name > @@ -73,7 +76,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 +157,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 +250,7 @@ linetoh_ust() > local name args argnames > name=$(get_name "$1") > args=$(get_args "$1") > - argnames=$(get_argnames "$1") > + argnames=$(get_argnames "$1", ",") > > cat< DECLARE_TRACE(ust_$name, TP_PROTO($args), TP_ARGS($argnames)); > @@ -274,7 +277,7 @@ linetoc_ust() > local name args argnames fmt > name=$(get_name "$1") > args=$(get_args "$1") > - argnames=$(get_argnames "$1") > + argnames=$(get_argnames "$1", ",") > fmt=$(get_fmt "$1") > > cat< @@ -306,6 +309,87 @@ EOF > echo "}" > } > > +linetoh_begin_dtrace() > +{ > + cat< +#include "trace-dtrace.h" > +EOF > +} > + > +linetoh_dtrace() > +{ > + local name args argnames state nameupper > + name=$(get_name "$1") > + args=$(get_args "$1") > + argnames=$(get_argnames "$1", ",") > + state=$(get_state "$1") > + if [ "$state" = "0" ] ; then > + name=${name##disable } > + fi > + > + nameupper=`echo $name | tr '[:lower:]' '[:upper:]'` > + > + # Define an empty function for the trace event > + cat< +static inline void trace_$name($args) { > + if (QEMU_${nameupper}_ENABLED()) { > + QEMU_${nameupper}($argnames); > + } > +} > +EOF > +} > + > +linetoh_end_dtrace() > +{ > + return > +} > + > +linetoc_begin_dtrace() > +{ > + return > +} > + > +linetoc_dtrace() > +{ > + # No need for function definitions in dtrace backend > + return > +} > + > +linetoc_end_dtrace() > +{ > + return > +} > + > +linetod_begin_dtrace() > +{ > + cat< +provider qemu { > +EOF > +} > + > +linetod_dtrace() > +{ > + local name args state > + name=$(get_name "$1") > + args=$(get_args "$1") > + state=$(get_state "$1") > + if [ "$state" = "0" ] ; then > + name=${name##disable } > + fi > + > + # Define prototype for probe arguments > + cat< + probe $name($args); > +EOF > +} > + > +linetod_end_dtrace() > +{ > + cat< +}; > +EOF > +} > + > # Process stdin by calling begin, line, and end functions for the backend > convert() > { > @@ -324,9 +408,10 @@ convert() > disable=${str%%disable *} > echo > if test -z "$disable"; then > - # Pass the disabled state as an arg to lineto$1_simple(). > - # For all other cases, call lineto$1_nop() > - if [ $backend = "simple" ]; then > + # Pass the disabled state as an arg for the simple > + # or DTrace backends which handle it dynamically. > + # For all other backends, call lineto$1_nop() > + if [ $backend = "simple" -o "$backend" = "dtrace" ]; then > "$process_line" "$str" > else > "lineto$1_nop" "${str##disable }" > @@ -360,9 +445,19 @@ tracetoc() > convert c > } > > +tracetod() > +{ > + if [ $backend != "dtrace" ]; then > + echo "DTrace probe generator not applicable to $backend backend" > + exit 1 > + fi > + echo "/* This file is autogenerated by tracetool, do not edit. */" > + convert d > +} > + > # Choose backend > case "$1" in > -"--nop" | "--simple" | "--ust") backend="${1#--}" ;; > +"--nop" | "--simple" | "--ust" | "--dtrace") backend="${1#--}" ;; > *) usage ;; > esac > shift > @@ -370,6 +465,7 @@ shift > case "$1" in > "-h") tracetoh ;; > "-c") tracetoc ;; > +"-d") tracetod ;; > "--check-backend") exit 0 ;; # used by ./configure to test for backend > *) usage ;; > esac >