summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile23
-rw-r--r--Makefile.objs4
-rwxr-xr-xconfigure14
-rwxr-xr-xtracetool116
5 files changed, 148 insertions, 11 deletions
diff --git a/.gitignore b/.gitignore
index a43e4d1d98..3efb4ecc13 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 68963198f0..747e47c834 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 15569afa14..23b17cefad 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -286,11 +286,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 7025d2bf0d..f8dad3eb00 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-<pid>"
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 701085837f..5b6636ac27 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 <<EOF
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 <<EOF
@@ -306,6 +309,87 @@ EOF
echo "}"
}
+linetoh_begin_dtrace()
+{
+ cat <<EOF
+#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 <<EOF
+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 <<EOF
+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 <<EOF
+ probe $name($args);
+EOF
+}
+
+linetod_end_dtrace()
+{
+ cat <<EOF
+};
+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