mirror of
https://git.proxmox.com/git/qemu
synced 2025-08-14 12:07:25 +00:00
Merge remote-tracking branch 'stefanha/tracing' into staging
* stefanha/tracing: tracetool: handle DTrace keywords 'in', 'next', 'self' tracetool: Add MAINTAINERS info tracetool: Add support for the 'dtrace' backend tracetool: Add support for the 'ust' backend tracetool: Add support for the 'simple' backend tracetool: Add support for the 'stderr' backend tracetool: Add module for the 'h' format tracetool: Add module for the 'c' format tracetool: Rewrite infrastructure as python modules
This commit is contained in:
commit
e5e3895702
@ -553,6 +553,8 @@ Tracing
|
|||||||
M: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
M: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: trace/
|
F: trace/
|
||||||
|
F: scripts/tracetool.py
|
||||||
|
F: scripts/tracetool/
|
||||||
F: docs/tracing.txt
|
F: docs/tracing.txt
|
||||||
T: git://github.com/stefanha/qemu.git tracing
|
T: git://github.com/stefanha/qemu.git tracing
|
||||||
|
|
||||||
|
@ -378,12 +378,12 @@ else
|
|||||||
trace.h: trace.h-timestamp
|
trace.h: trace.h-timestamp
|
||||||
endif
|
endif
|
||||||
trace.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
|
trace.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
|
||||||
$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -h < $< > $@," GEN trace.h")
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=h --backend=$(TRACE_BACKEND) < $< > $@," GEN trace.h")
|
||||||
@cmp -s $@ trace.h || cp $@ trace.h
|
@cmp -s $@ trace.h || cp $@ trace.h
|
||||||
|
|
||||||
trace.c: trace.c-timestamp
|
trace.c: trace.c-timestamp
|
||||||
trace.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
|
trace.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
|
||||||
$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -c < $< > $@," GEN trace.c")
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=c --backend=$(TRACE_BACKEND) < $< > $@," GEN trace.c")
|
||||||
@cmp -s $@ trace.c || cp $@ trace.c
|
@cmp -s $@ trace.c || cp $@ trace.c
|
||||||
|
|
||||||
trace.o: trace.c $(GENERATED_HEADERS)
|
trace.o: trace.c $(GENERATED_HEADERS)
|
||||||
@ -396,7 +396,7 @@ trace-dtrace.h: trace-dtrace.dtrace
|
|||||||
# rule file. So we use '.dtrace' instead
|
# rule file. So we use '.dtrace' instead
|
||||||
trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
|
trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
|
||||||
trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
|
trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
|
||||||
$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool --$(TRACE_BACKEND) -d < $< > $@," GEN trace-dtrace.dtrace")
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=d --backend=$(TRACE_BACKEND) < $< > $@," GEN trace-dtrace.dtrace")
|
||||||
@cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace
|
@cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace
|
||||||
|
|
||||||
trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
|
trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
|
||||||
|
@ -59,12 +59,13 @@ TARGET_TYPE=system
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
|
$(QEMU_PROG).stp: $(SRC_PATH)/trace-events
|
||||||
$(call quiet-command,sh $(SRC_PATH)/scripts/tracetool \
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
|
||||||
--$(TRACE_BACKEND) \
|
--format=stap \
|
||||||
--binary $(bindir)/$(QEMU_PROG) \
|
--backend=$(TRACE_BACKEND) \
|
||||||
--target-arch $(TARGET_ARCH) \
|
--binary=$(bindir)/$(QEMU_PROG) \
|
||||||
--target-type $(TARGET_TYPE) \
|
--target-arch=$(TARGET_ARCH) \
|
||||||
--stap < $(SRC_PATH)/trace-events > $(QEMU_PROG).stp," GEN $(QEMU_PROG).stp")
|
--target-type=$(TARGET_TYPE) \
|
||||||
|
< $(SRC_PATH)/trace-events > $(QEMU_PROG).stp," GEN $(QEMU_PROG).stp")
|
||||||
else
|
else
|
||||||
stap:
|
stap:
|
||||||
endif
|
endif
|
||||||
|
4
configure
vendored
4
configure
vendored
@ -1097,7 +1097,7 @@ echo " --disable-docs disable documentation build"
|
|||||||
echo " --disable-vhost-net disable vhost-net acceleration support"
|
echo " --disable-vhost-net disable vhost-net acceleration support"
|
||||||
echo " --enable-vhost-net enable vhost-net acceleration support"
|
echo " --enable-vhost-net enable vhost-net acceleration support"
|
||||||
echo " --enable-trace-backend=B Set trace backend"
|
echo " --enable-trace-backend=B Set trace backend"
|
||||||
echo " Available backends:" $("$source_path"/scripts/tracetool --list-backends)
|
echo " Available backends:" $($python "$source_path"/scripts/tracetool.py --list-backends)
|
||||||
echo " --with-trace-file=NAME Full PATH,NAME of file to store traces"
|
echo " --with-trace-file=NAME Full PATH,NAME of file to store traces"
|
||||||
echo " Default:trace-<pid>"
|
echo " Default:trace-<pid>"
|
||||||
echo " --disable-spice disable spice"
|
echo " --disable-spice disable spice"
|
||||||
@ -2670,7 +2670,7 @@ fi
|
|||||||
##########################################
|
##########################################
|
||||||
# check if trace backend exists
|
# check if trace backend exists
|
||||||
|
|
||||||
sh "$source_path/scripts/tracetool" "--$trace_backend" --check-backend > /dev/null 2> /dev/null
|
$python "$source_path/scripts/tracetool.py" "--backend=$trace_backend" --check-backend > /dev/null 2> /dev/null
|
||||||
if test "$?" -ne 0 ; then
|
if test "$?" -ne 0 ; then
|
||||||
echo
|
echo
|
||||||
echo "Error: invalid trace backend"
|
echo "Error: invalid trace backend"
|
||||||
|
@ -1,666 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# Code generator for trace events
|
|
||||||
#
|
|
||||||
# Copyright IBM, Corp. 2010
|
|
||||||
#
|
|
||||||
# This work is licensed under the terms of the GNU GPL, version 2. See
|
|
||||||
# the COPYING file in the top-level directory.
|
|
||||||
|
|
||||||
# Disable pathname expansion, makes processing text with '*' characters simpler
|
|
||||||
set -f
|
|
||||||
|
|
||||||
usage()
|
|
||||||
{
|
|
||||||
cat >&2 <<EOF
|
|
||||||
usage: $0 [--nop | --simple | --stderr | --ust | --dtrace] [-h | -c]
|
|
||||||
Generate tracing code for a file on stdin.
|
|
||||||
|
|
||||||
Backends:
|
|
||||||
--nop Tracing disabled
|
|
||||||
--simple Simple built-in backend
|
|
||||||
--stderr Stderr 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)
|
|
||||||
--stap Generate .stp file (DTrace with SystemTAP only)
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--binary [path] Full path to QEMU binary
|
|
||||||
--target-arch [arch] QEMU emulator target arch
|
|
||||||
--target-type [type] QEMU emulator target type ('system' or 'user')
|
|
||||||
--probe-prefix [prefix] Prefix for dtrace probe names
|
|
||||||
(default: qemu-\$targettype-\$targetarch)
|
|
||||||
|
|
||||||
EOF
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Print a line without interpreting backslash escapes
|
|
||||||
#
|
|
||||||
# The built-in echo command may interpret backslash escapes without an option
|
|
||||||
# to disable this behavior.
|
|
||||||
puts()
|
|
||||||
{
|
|
||||||
printf "%s\n" "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the name of a trace event
|
|
||||||
get_name()
|
|
||||||
{
|
|
||||||
local name
|
|
||||||
name=${1%%\(*}
|
|
||||||
echo "${name##* }"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the given property of a trace event
|
|
||||||
# 1: trace-events line
|
|
||||||
# 2: property name
|
|
||||||
# -> return 0 if property is present, or 1 otherwise
|
|
||||||
has_property()
|
|
||||||
{
|
|
||||||
local props prop
|
|
||||||
props=${1%%\(*}
|
|
||||||
props=${props% *}
|
|
||||||
for prop in $props; do
|
|
||||||
if [ "$prop" = "$2" ]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the argument list of a trace event, including types and names
|
|
||||||
get_args()
|
|
||||||
{
|
|
||||||
local args
|
|
||||||
args=${1#*\(}
|
|
||||||
args=${args%%\)*}
|
|
||||||
echo "$args"
|
|
||||||
|
|
||||||
if (echo "$args" | grep "[ *]next\($\|[, ]\)" > /dev/null 2>&1); then
|
|
||||||
echo -e "\n#error 'next' is a bad argument name (clash with systemtap keyword)\n "
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the argument name list of a trace event
|
|
||||||
get_argnames()
|
|
||||||
{
|
|
||||||
local nfields field name sep
|
|
||||||
nfields=0
|
|
||||||
sep="$2"
|
|
||||||
for field in $(get_args "$1"); do
|
|
||||||
nfields=$((nfields + 1))
|
|
||||||
|
|
||||||
# Drop pointer star
|
|
||||||
field=${field#\*}
|
|
||||||
|
|
||||||
# Only argument names have commas at the end
|
|
||||||
name=${field%,}
|
|
||||||
test "$field" = "$name" && continue
|
|
||||||
|
|
||||||
printf "%s%s " $name $sep
|
|
||||||
done
|
|
||||||
|
|
||||||
# Last argument name
|
|
||||||
if [ "$nfields" -gt 1 ]
|
|
||||||
then
|
|
||||||
printf "%s" "$name"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the number of arguments to a trace event
|
|
||||||
get_argc()
|
|
||||||
{
|
|
||||||
local name argc
|
|
||||||
argc=0
|
|
||||||
for name in $(get_argnames "$1", ","); do
|
|
||||||
argc=$((argc + 1))
|
|
||||||
done
|
|
||||||
echo $argc
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the format string including double quotes for a trace event
|
|
||||||
get_fmt()
|
|
||||||
{
|
|
||||||
puts "${1#*)}"
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_begin_nop()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_nop()
|
|
||||||
{
|
|
||||||
local name args
|
|
||||||
name=$(get_name "$1")
|
|
||||||
args=$(get_args "$1")
|
|
||||||
|
|
||||||
# Define an empty function for the trace event
|
|
||||||
cat <<EOF
|
|
||||||
static inline void trace_$name($args)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_end_nop()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_begin_nop()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_nop()
|
|
||||||
{
|
|
||||||
# No need for function definitions in nop backend
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
linetod_nop()
|
|
||||||
{
|
|
||||||
# Used when "disabled" events are processed
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
linetostap_nop()
|
|
||||||
{
|
|
||||||
# Used when "disabled" events are processed
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_end_nop()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_begin_simple()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
#include "trace/simple.h"
|
|
||||||
EOF
|
|
||||||
|
|
||||||
simple_event_num=0
|
|
||||||
}
|
|
||||||
|
|
||||||
cast_args_to_uint64_t()
|
|
||||||
{
|
|
||||||
local arg
|
|
||||||
for arg in $(get_argnames "$1", ","); do
|
|
||||||
printf "%s" "(uint64_t)(uintptr_t)$arg"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_simple()
|
|
||||||
{
|
|
||||||
local name args argc trace_args
|
|
||||||
name=$(get_name "$1")
|
|
||||||
args=$(get_args "$1")
|
|
||||||
argc=$(get_argc "$1")
|
|
||||||
|
|
||||||
trace_args="$simple_event_num"
|
|
||||||
if [ "$argc" -gt 0 ]
|
|
||||||
then
|
|
||||||
trace_args="$trace_args, $(cast_args_to_uint64_t "$1")"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat <<EOF
|
|
||||||
static inline void trace_$name($args)
|
|
||||||
{
|
|
||||||
trace$argc($trace_args);
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
simple_event_num=$((simple_event_num + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_end_simple()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
#define NR_TRACE_EVENTS $simple_event_num
|
|
||||||
extern TraceEvent trace_list[NR_TRACE_EVENTS];
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_begin_simple()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
#include "trace.h"
|
|
||||||
|
|
||||||
TraceEvent trace_list[] = {
|
|
||||||
EOF
|
|
||||||
simple_event_num=0
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_simple()
|
|
||||||
{
|
|
||||||
local name
|
|
||||||
name=$(get_name "$1")
|
|
||||||
cat <<EOF
|
|
||||||
{.tp_name = "$name", .state=0},
|
|
||||||
EOF
|
|
||||||
simple_event_num=$((simple_event_num + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_end_simple()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
};
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
#STDERR
|
|
||||||
linetoh_begin_stderr()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "trace/stderr.h"
|
|
||||||
|
|
||||||
extern TraceEvent trace_list[];
|
|
||||||
EOF
|
|
||||||
|
|
||||||
stderr_event_num=0
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_stderr()
|
|
||||||
{
|
|
||||||
local name args argnames argc fmt
|
|
||||||
name=$(get_name "$1")
|
|
||||||
args=$(get_args "$1")
|
|
||||||
argnames=$(get_argnames "$1" ",")
|
|
||||||
argc=$(get_argc "$1")
|
|
||||||
fmt=$(get_fmt "$1")
|
|
||||||
|
|
||||||
if [ "$argc" -gt 0 ]; then
|
|
||||||
argnames=", $argnames"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat <<EOF
|
|
||||||
static inline void trace_$name($args)
|
|
||||||
{
|
|
||||||
if (trace_list[$stderr_event_num].state != 0) {
|
|
||||||
fprintf(stderr, "$name " $fmt "\n" $argnames);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
stderr_event_num=$((stderr_event_num + 1))
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_end_stderr()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
#define NR_TRACE_EVENTS $stderr_event_num
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_begin_stderr()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
#include "trace.h"
|
|
||||||
|
|
||||||
TraceEvent trace_list[] = {
|
|
||||||
EOF
|
|
||||||
stderr_event_num=0
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_stderr()
|
|
||||||
{
|
|
||||||
local name
|
|
||||||
name=$(get_name "$1")
|
|
||||||
cat <<EOF
|
|
||||||
{.tp_name = "$name", .state=0},
|
|
||||||
EOF
|
|
||||||
stderr_event_num=$(($stderr_event_num + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_end_stderr()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
};
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
#END OF STDERR
|
|
||||||
|
|
||||||
# Clean up after UST headers which pollute the namespace
|
|
||||||
ust_clean_namespace() {
|
|
||||||
cat <<EOF
|
|
||||||
#undef mutex_lock
|
|
||||||
#undef mutex_unlock
|
|
||||||
#undef inline
|
|
||||||
#undef wmb
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_begin_ust()
|
|
||||||
{
|
|
||||||
echo "#include <ust/tracepoint.h>"
|
|
||||||
ust_clean_namespace
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_ust()
|
|
||||||
{
|
|
||||||
local name args argnames
|
|
||||||
name=$(get_name "$1")
|
|
||||||
args=$(get_args "$1")
|
|
||||||
argnames=$(get_argnames "$1", ",")
|
|
||||||
|
|
||||||
cat <<EOF
|
|
||||||
DECLARE_TRACE(ust_$name, TP_PROTO($args), TP_ARGS($argnames));
|
|
||||||
#define trace_$name trace_ust_$name
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_end_ust()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_begin_ust()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
#include <ust/marker.h>
|
|
||||||
$(ust_clean_namespace)
|
|
||||||
#include "trace.h"
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_ust()
|
|
||||||
{
|
|
||||||
local name args argnames fmt
|
|
||||||
name=$(get_name "$1")
|
|
||||||
args=$(get_args "$1")
|
|
||||||
argnames=$(get_argnames "$1", ",")
|
|
||||||
[ -z "$argnames" ] || argnames=", $argnames"
|
|
||||||
fmt=$(get_fmt "$1")
|
|
||||||
|
|
||||||
cat <<EOF
|
|
||||||
DEFINE_TRACE(ust_$name);
|
|
||||||
|
|
||||||
static void ust_${name}_probe($args)
|
|
||||||
{
|
|
||||||
trace_mark(ust, $name, $fmt$argnames);
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Collect names for later
|
|
||||||
names="$names $name"
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoc_end_ust()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
static void __attribute__((constructor)) trace_init(void)
|
|
||||||
{
|
|
||||||
EOF
|
|
||||||
|
|
||||||
for name in $names; do
|
|
||||||
cat <<EOF
|
|
||||||
register_trace_ust_$name(ust_${name}_probe);
|
|
||||||
EOF
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "}"
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_begin_dtrace()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
#include "trace-dtrace.h"
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
linetoh_dtrace()
|
|
||||||
{
|
|
||||||
local name args argnames nameupper
|
|
||||||
name=$(get_name "$1")
|
|
||||||
args=$(get_args "$1")
|
|
||||||
argnames=$(get_argnames "$1", ",")
|
|
||||||
|
|
||||||
nameupper=`echo $name | LC_ALL=C tr '[a-z]' '[A-Z]'`
|
|
||||||
|
|
||||||
# Define an empty function for the trace event
|
|
||||||
cat <<EOF
|
|
||||||
static inline void trace_$name($args) {
|
|
||||||
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
|
|
||||||
name=$(get_name "$1")
|
|
||||||
args=$(get_args "$1")
|
|
||||||
|
|
||||||
# DTrace provider syntax expects foo() for empty
|
|
||||||
# params, not foo(void)
|
|
||||||
if [ "$args" = "void" ]; then
|
|
||||||
args=""
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Define prototype for probe arguments
|
|
||||||
cat <<EOF
|
|
||||||
probe $name($args);
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
linetod_end_dtrace()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
};
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
linetostap_begin_dtrace()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
linetostap_dtrace()
|
|
||||||
{
|
|
||||||
local i arg name args arglist
|
|
||||||
name=$(get_name "$1")
|
|
||||||
args=$(get_args "$1")
|
|
||||||
arglist=$(get_argnames "$1", "")
|
|
||||||
|
|
||||||
# Define prototype for probe arguments
|
|
||||||
cat <<EOF
|
|
||||||
probe $probeprefix.$name = process("$binary").mark("$name")
|
|
||||||
{
|
|
||||||
EOF
|
|
||||||
|
|
||||||
i=1
|
|
||||||
for arg in $arglist
|
|
||||||
do
|
|
||||||
# postfix reserved words with '_'
|
|
||||||
case "$arg" in
|
|
||||||
limit|in|next|self)
|
|
||||||
arg="${arg}_"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
cat <<EOF
|
|
||||||
$arg = \$arg$i;
|
|
||||||
EOF
|
|
||||||
i="$((i+1))"
|
|
||||||
done
|
|
||||||
|
|
||||||
cat <<EOF
|
|
||||||
}
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
linetostap_end_dtrace()
|
|
||||||
{
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
# Process stdin by calling begin, line, and end functions for the backend
|
|
||||||
convert()
|
|
||||||
{
|
|
||||||
local begin process_line end str name NAME enabled
|
|
||||||
begin="lineto$1_begin_$backend"
|
|
||||||
process_line="lineto$1_$backend"
|
|
||||||
end="lineto$1_end_$backend"
|
|
||||||
|
|
||||||
"$begin"
|
|
||||||
|
|
||||||
while read -r str; do
|
|
||||||
# Skip comments and empty lines
|
|
||||||
test -z "${str%%#*}" && continue
|
|
||||||
|
|
||||||
echo
|
|
||||||
# Process the line. The nop backend handles disabled lines.
|
|
||||||
if has_property "$str" "disable"; then
|
|
||||||
"lineto$1_nop" "$str"
|
|
||||||
enabled=0
|
|
||||||
else
|
|
||||||
"$process_line" "$str"
|
|
||||||
enabled=1
|
|
||||||
fi
|
|
||||||
if [ "$1" = "h" ]; then
|
|
||||||
name=$(get_name "$str")
|
|
||||||
NAME=$(echo $name | LC_ALL=C tr '[a-z]' '[A-Z]')
|
|
||||||
echo "#define TRACE_${NAME}_ENABLED ${enabled}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
echo
|
|
||||||
"$end"
|
|
||||||
}
|
|
||||||
|
|
||||||
tracetoh()
|
|
||||||
{
|
|
||||||
cat <<EOF
|
|
||||||
#ifndef TRACE_H
|
|
||||||
#define TRACE_H
|
|
||||||
|
|
||||||
/* This file is autogenerated by tracetool, do not edit. */
|
|
||||||
|
|
||||||
#include "qemu-common.h"
|
|
||||||
EOF
|
|
||||||
convert h
|
|
||||||
echo "#endif /* TRACE_H */"
|
|
||||||
}
|
|
||||||
|
|
||||||
tracetoc()
|
|
||||||
{
|
|
||||||
echo "/* This file is autogenerated by tracetool, do not edit. */"
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
tracetostap()
|
|
||||||
{
|
|
||||||
if [ $backend != "dtrace" ]; then
|
|
||||||
echo "SystemTAP tapset generator not applicable to $backend backend"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ -z "$binary" ]; then
|
|
||||||
echo "--binary is required for SystemTAP tapset generator"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ -z "$probeprefix" -a -z "$targettype" ]; then
|
|
||||||
echo "--target-type is required for SystemTAP tapset generator"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ -z "$probeprefix" -a -z "$targetarch" ]; then
|
|
||||||
echo "--target-arch is required for SystemTAP tapset generator"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
if [ -z "$probeprefix" ]; then
|
|
||||||
probeprefix="qemu.$targettype.$targetarch";
|
|
||||||
fi
|
|
||||||
echo "/* This file is autogenerated by tracetool, do not edit. */"
|
|
||||||
convert stap
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
backend=
|
|
||||||
output=
|
|
||||||
binary=
|
|
||||||
targettype=
|
|
||||||
targetarch=
|
|
||||||
probeprefix=
|
|
||||||
|
|
||||||
|
|
||||||
until [ -z "$1" ]
|
|
||||||
do
|
|
||||||
case "$1" in
|
|
||||||
"--nop" | "--simple" | "--stderr" | "--ust" | "--dtrace") backend="${1#--}" ;;
|
|
||||||
|
|
||||||
"--binary") shift ; binary="$1" ;;
|
|
||||||
"--target-arch") shift ; targetarch="$1" ;;
|
|
||||||
"--target-type") shift ; targettype="$1" ;;
|
|
||||||
"--probe-prefix") shift ; probeprefix="$1" ;;
|
|
||||||
|
|
||||||
"-h" | "-c" | "-d") output="${1#-}" ;;
|
|
||||||
"--stap") output="${1#--}" ;;
|
|
||||||
|
|
||||||
"--check-backend") exit 0 ;; # used by ./configure to test for backend
|
|
||||||
|
|
||||||
"--list-backends") # used by ./configure to list available backends
|
|
||||||
echo "nop simple stderr ust dtrace"
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
|
|
||||||
*)
|
|
||||||
usage;;
|
|
||||||
esac
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
|
|
||||||
if [ "$backend" = "" -o "$output" = "" ]; then
|
|
||||||
usage
|
|
||||||
fi
|
|
||||||
|
|
||||||
gen="traceto$output"
|
|
||||||
"$gen"
|
|
||||||
|
|
||||||
exit 0
|
|
138
scripts/tracetool.py
Executable file
138
scripts/tracetool.py
Executable file
@ -0,0 +1,138 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Command-line wrapper for the tracetool machinery.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import getopt
|
||||||
|
|
||||||
|
from tracetool import error_write, out
|
||||||
|
import tracetool.backend
|
||||||
|
import tracetool.format
|
||||||
|
|
||||||
|
|
||||||
|
_SCRIPT = ""
|
||||||
|
|
||||||
|
def error_opt(msg = None):
|
||||||
|
if msg is not None:
|
||||||
|
error_write("Error: " + msg + "\n")
|
||||||
|
|
||||||
|
backend_descr = "\n".join([ " %-15s %s" % (n, d)
|
||||||
|
for n,d in tracetool.backend.get_list() ])
|
||||||
|
format_descr = "\n".join([ " %-15s %s" % (n, d)
|
||||||
|
for n,d in tracetool.format.get_list() ])
|
||||||
|
error_write("""\
|
||||||
|
Usage: %(script)s --format=<format> --backend=<backend> [<options>]
|
||||||
|
|
||||||
|
Backends:
|
||||||
|
%(backends)s
|
||||||
|
|
||||||
|
Formats:
|
||||||
|
%(formats)s
|
||||||
|
|
||||||
|
Options:
|
||||||
|
--help This help message.
|
||||||
|
--list-backends Print list of available backends.
|
||||||
|
--check-backend Check if the given backend is valid.
|
||||||
|
--binary <path> Full path to QEMU binary.
|
||||||
|
--target-type <type> QEMU emulator target type ('system' or 'user').
|
||||||
|
--target-arch <arch> QEMU emulator target arch.
|
||||||
|
--probe-prefix <prefix> Prefix for dtrace probe names
|
||||||
|
(default: qemu-<target-type>-<target-arch>).\
|
||||||
|
""" % {
|
||||||
|
"script" : _SCRIPT,
|
||||||
|
"backends" : backend_descr,
|
||||||
|
"formats" : format_descr,
|
||||||
|
})
|
||||||
|
|
||||||
|
if msg is None:
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main(args):
|
||||||
|
global _SCRIPT
|
||||||
|
_SCRIPT = args[0]
|
||||||
|
|
||||||
|
long_opts = [ "backend=", "format=", "help", "list-backends", "check-backend" ]
|
||||||
|
long_opts += [ "binary=", "target-type=", "target-arch=", "probe-prefix=" ]
|
||||||
|
|
||||||
|
try:
|
||||||
|
opts, args = getopt.getopt(args[1:], "", long_opts)
|
||||||
|
except getopt.GetoptError as err:
|
||||||
|
error_opt(str(err))
|
||||||
|
|
||||||
|
check_backend = False
|
||||||
|
arg_backend = ""
|
||||||
|
arg_format = ""
|
||||||
|
binary = None
|
||||||
|
target_type = None
|
||||||
|
target_arch = None
|
||||||
|
probe_prefix = None
|
||||||
|
for opt, arg in opts:
|
||||||
|
if opt == "--help":
|
||||||
|
error_opt()
|
||||||
|
|
||||||
|
elif opt == "--backend":
|
||||||
|
arg_backend = arg
|
||||||
|
elif opt == "--format":
|
||||||
|
arg_format = arg
|
||||||
|
|
||||||
|
elif opt == "--list-backends":
|
||||||
|
backends = tracetool.backend.get_list()
|
||||||
|
out(", ".join([ b for b,_ in backends ]))
|
||||||
|
sys.exit(0)
|
||||||
|
elif opt == "--check-backend":
|
||||||
|
check_backend = True
|
||||||
|
|
||||||
|
elif opt == "--binary":
|
||||||
|
binary = arg
|
||||||
|
elif opt == '--target-type':
|
||||||
|
target_type = arg
|
||||||
|
elif opt == '--target-arch':
|
||||||
|
target_arch = arg
|
||||||
|
elif opt == '--probe-prefix':
|
||||||
|
probe_prefix = arg
|
||||||
|
|
||||||
|
else:
|
||||||
|
error_opt("unhandled option: %s" % opt)
|
||||||
|
|
||||||
|
if arg_backend is None:
|
||||||
|
error_opt("backend not set")
|
||||||
|
|
||||||
|
if check_backend:
|
||||||
|
if tracetool.backend.exists(arg_backend):
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if arg_format == "stap":
|
||||||
|
if binary is None:
|
||||||
|
error_opt("--binary is required for SystemTAP tapset generator")
|
||||||
|
if probe_prefix is None and target_type is None:
|
||||||
|
error_opt("--target-type is required for SystemTAP tapset generator")
|
||||||
|
if probe_prefix is None and target_arch is None:
|
||||||
|
error_opt("--target-arch is required for SystemTAP tapset generator")
|
||||||
|
|
||||||
|
if probe_prefix is None:
|
||||||
|
probe_prefix = ".".join([ "qemu", target_type, target_arch ])
|
||||||
|
|
||||||
|
try:
|
||||||
|
tracetool.generate(sys.stdin, arg_format, arg_backend,
|
||||||
|
binary = binary, probe_prefix = probe_prefix)
|
||||||
|
except tracetool.TracetoolError as e:
|
||||||
|
error_opt(str(e))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main(sys.argv)
|
271
scripts/tracetool/__init__.py
Normal file
271
scripts/tracetool/__init__.py
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Machinery for generating tracing-related intermediate files.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import tracetool.format
|
||||||
|
import tracetool.backend
|
||||||
|
|
||||||
|
|
||||||
|
def error_write(*lines):
|
||||||
|
"""Write a set of error lines."""
|
||||||
|
sys.stderr.writelines("\n".join(lines) + "\n")
|
||||||
|
|
||||||
|
def error(*lines):
|
||||||
|
"""Write a set of error lines and exit."""
|
||||||
|
error_write(*lines)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def out(*lines, **kwargs):
|
||||||
|
"""Write a set of output lines.
|
||||||
|
|
||||||
|
You can use kwargs as a shorthand for mapping variables when formating all
|
||||||
|
the strings in lines.
|
||||||
|
"""
|
||||||
|
lines = [ l % kwargs for l in lines ]
|
||||||
|
sys.stdout.writelines("\n".join(lines) + "\n")
|
||||||
|
|
||||||
|
|
||||||
|
class Arguments:
|
||||||
|
"""Event arguments description."""
|
||||||
|
|
||||||
|
def __init__(self, args):
|
||||||
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
args :
|
||||||
|
List of (type, name) tuples.
|
||||||
|
"""
|
||||||
|
self._args = args
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def build(arg_str):
|
||||||
|
"""Build and Arguments instance from an argument string.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
arg_str : str
|
||||||
|
String describing the event arguments.
|
||||||
|
"""
|
||||||
|
res = []
|
||||||
|
for arg in arg_str.split(","):
|
||||||
|
arg = arg.strip()
|
||||||
|
parts = arg.split()
|
||||||
|
head, sep, tail = parts[-1].rpartition("*")
|
||||||
|
parts = parts[:-1]
|
||||||
|
if tail == "void":
|
||||||
|
assert len(parts) == 0 and sep == ""
|
||||||
|
continue
|
||||||
|
arg_type = " ".join(parts + [ " ".join([head, sep]).strip() ]).strip()
|
||||||
|
res.append((arg_type, tail))
|
||||||
|
return Arguments(res)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
"""Iterate over the (type, name) pairs."""
|
||||||
|
return iter(self._args)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
"""Number of arguments."""
|
||||||
|
return len(self._args)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
"""String suitable for declaring function arguments."""
|
||||||
|
if len(self._args) == 0:
|
||||||
|
return "void"
|
||||||
|
else:
|
||||||
|
return ", ".join([ " ".join([t, n]) for t,n in self._args ])
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""Evaluable string representation for this object."""
|
||||||
|
return "Arguments(\"%s\")" % str(self)
|
||||||
|
|
||||||
|
def names(self):
|
||||||
|
"""List of argument names."""
|
||||||
|
return [ name for _, name in self._args ]
|
||||||
|
|
||||||
|
def types(self):
|
||||||
|
"""List of argument types."""
|
||||||
|
return [ type_ for type_, _ in self._args ]
|
||||||
|
|
||||||
|
|
||||||
|
class Event(object):
|
||||||
|
"""Event description.
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
name : str
|
||||||
|
The event name.
|
||||||
|
fmt : str
|
||||||
|
The event format string.
|
||||||
|
properties : set(str)
|
||||||
|
Properties of the event.
|
||||||
|
args : Arguments
|
||||||
|
The event arguments.
|
||||||
|
"""
|
||||||
|
|
||||||
|
_CRE = re.compile("((?P<props>.*)\s+)?(?P<name>[^(\s]+)\((?P<args>[^)]*)\)\s*(?P<fmt>\".*)?")
|
||||||
|
|
||||||
|
_VALID_PROPS = set(["disable"])
|
||||||
|
|
||||||
|
def __init__(self, name, props, fmt, args):
|
||||||
|
"""
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
name : string
|
||||||
|
Event name.
|
||||||
|
props : list of str
|
||||||
|
Property names.
|
||||||
|
fmt : str
|
||||||
|
Event printing format.
|
||||||
|
args : Arguments
|
||||||
|
Event arguments.
|
||||||
|
"""
|
||||||
|
self.name = name
|
||||||
|
self.properties = props
|
||||||
|
self.fmt = fmt
|
||||||
|
self.args = args
|
||||||
|
|
||||||
|
unknown_props = set(self.properties) - self._VALID_PROPS
|
||||||
|
if len(unknown_props) > 0:
|
||||||
|
raise ValueError("Unknown properties: %s" % ", ".join(unknown_props))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def build(line_str):
|
||||||
|
"""Build an Event instance from a string.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
line_str : str
|
||||||
|
Line describing the event.
|
||||||
|
"""
|
||||||
|
m = Event._CRE.match(line_str)
|
||||||
|
assert m is not None
|
||||||
|
groups = m.groupdict('')
|
||||||
|
|
||||||
|
name = groups["name"]
|
||||||
|
props = groups["props"].split()
|
||||||
|
fmt = groups["fmt"]
|
||||||
|
args = Arguments.build(groups["args"])
|
||||||
|
|
||||||
|
return Event(name, props, fmt, args)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""Evaluable string representation for this object."""
|
||||||
|
return "Event('%s %s(%s) %s')" % (" ".join(self.properties),
|
||||||
|
self.name,
|
||||||
|
self.args,
|
||||||
|
self.fmt)
|
||||||
|
|
||||||
|
def _read_events(fobj):
|
||||||
|
res = []
|
||||||
|
for line in fobj:
|
||||||
|
if not line.strip():
|
||||||
|
continue
|
||||||
|
if line.lstrip().startswith('#'):
|
||||||
|
continue
|
||||||
|
res.append(Event.build(line))
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
class TracetoolError (Exception):
|
||||||
|
"""Exception for calls to generate."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def try_import(mod_name, attr_name = None, attr_default = None):
|
||||||
|
"""Try to import a module and get an attribute from it.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
mod_name : str
|
||||||
|
Module name.
|
||||||
|
attr_name : str, optional
|
||||||
|
Name of an attribute in the module.
|
||||||
|
attr_default : optional
|
||||||
|
Default value if the attribute does not exist in the module.
|
||||||
|
|
||||||
|
Returns
|
||||||
|
-------
|
||||||
|
A pair indicating whether the module could be imported and the module or
|
||||||
|
object or attribute value.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
module = __import__(mod_name, fromlist=["__package__"])
|
||||||
|
if attr_name is None:
|
||||||
|
return True, module
|
||||||
|
return True, getattr(module, str(attr_name), attr_default)
|
||||||
|
except ImportError:
|
||||||
|
return False, None
|
||||||
|
|
||||||
|
|
||||||
|
def generate(fevents, format, backend,
|
||||||
|
binary = None, probe_prefix = None):
|
||||||
|
"""Generate the output for the given (format, backend) pair.
|
||||||
|
|
||||||
|
Parameters
|
||||||
|
----------
|
||||||
|
fevents : file
|
||||||
|
Event description file.
|
||||||
|
format : str
|
||||||
|
Output format name.
|
||||||
|
backend : str
|
||||||
|
Output backend name.
|
||||||
|
binary : str or None
|
||||||
|
See tracetool.backend.dtrace.BINARY.
|
||||||
|
probe_prefix : str or None
|
||||||
|
See tracetool.backend.dtrace.PROBEPREFIX.
|
||||||
|
"""
|
||||||
|
# fix strange python error (UnboundLocalError tracetool)
|
||||||
|
import tracetool
|
||||||
|
|
||||||
|
format = str(format)
|
||||||
|
if len(format) is 0:
|
||||||
|
raise TracetoolError("format not set")
|
||||||
|
mformat = format.replace("-", "_")
|
||||||
|
if not tracetool.format.exists(mformat):
|
||||||
|
raise TracetoolError("unknown format: %s" % format)
|
||||||
|
|
||||||
|
backend = str(backend)
|
||||||
|
if len(backend) is 0:
|
||||||
|
raise TracetoolError("backend not set")
|
||||||
|
mbackend = backend.replace("-", "_")
|
||||||
|
if not tracetool.backend.exists(mbackend):
|
||||||
|
raise TracetoolError("unknown backend: %s" % backend)
|
||||||
|
|
||||||
|
if not tracetool.backend.compatible(mbackend, mformat):
|
||||||
|
raise TracetoolError("backend '%s' not compatible with format '%s'" %
|
||||||
|
(backend, format))
|
||||||
|
|
||||||
|
import tracetool.backend.dtrace
|
||||||
|
tracetool.backend.dtrace.BINARY = binary
|
||||||
|
tracetool.backend.dtrace.PROBEPREFIX = probe_prefix
|
||||||
|
|
||||||
|
events = _read_events(fevents)
|
||||||
|
|
||||||
|
if backend == "nop":
|
||||||
|
( e.properies.add("disable") for e in events )
|
||||||
|
|
||||||
|
tracetool.format.generate_begin(mformat, events)
|
||||||
|
tracetool.backend.generate("nop", format,
|
||||||
|
[ e
|
||||||
|
for e in events
|
||||||
|
if "disable" in e.properties ])
|
||||||
|
tracetool.backend.generate(backend, format,
|
||||||
|
[ e
|
||||||
|
for e in events
|
||||||
|
if "disable" not in e.properties ])
|
||||||
|
tracetool.format.generate_end(mformat, events)
|
111
scripts/tracetool/backend/__init__.py
Normal file
111
scripts/tracetool/backend/__init__.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Backend management.
|
||||||
|
|
||||||
|
|
||||||
|
Creating new backends
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
A new backend named 'foo-bar' corresponds to Python module
|
||||||
|
'tracetool/backend/foo_bar.py'.
|
||||||
|
|
||||||
|
A backend module should provide a docstring, whose first non-empty line will be
|
||||||
|
considered its short description.
|
||||||
|
|
||||||
|
All backends must generate their contents through the 'tracetool.out' routine.
|
||||||
|
|
||||||
|
|
||||||
|
Backend functions
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
======== =======================================================================
|
||||||
|
Function Description
|
||||||
|
======== =======================================================================
|
||||||
|
<format> Called to generate the format- and backend-specific code for each of
|
||||||
|
the specified events. If the function does not exist, the backend is
|
||||||
|
considered not compatible with the given format.
|
||||||
|
======== =======================================================================
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
import pkgutil
|
||||||
|
|
||||||
|
import tracetool
|
||||||
|
|
||||||
|
|
||||||
|
def get_list():
|
||||||
|
"""Get a list of (name, description) pairs."""
|
||||||
|
res = [("nop", "Tracing disabled.")]
|
||||||
|
for _, modname, _ in pkgutil.iter_modules(tracetool.backend.__path__):
|
||||||
|
module = tracetool.try_import("tracetool.backend." + modname)
|
||||||
|
|
||||||
|
# just in case; should never fail unless non-module files are put there
|
||||||
|
if not module[0]:
|
||||||
|
continue
|
||||||
|
module = module[1]
|
||||||
|
|
||||||
|
doc = module.__doc__
|
||||||
|
if doc is None:
|
||||||
|
doc = ""
|
||||||
|
doc = doc.strip().split("\n")[0]
|
||||||
|
|
||||||
|
name = modname.replace("_", "-")
|
||||||
|
res.append((name, doc))
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def exists(name):
|
||||||
|
"""Return whether the given backend exists."""
|
||||||
|
if len(name) == 0:
|
||||||
|
return False
|
||||||
|
if name == "nop":
|
||||||
|
return True
|
||||||
|
name = name.replace("-", "_")
|
||||||
|
return tracetool.try_import("tracetool.backend." + name)[1]
|
||||||
|
|
||||||
|
|
||||||
|
def compatible(backend, format):
|
||||||
|
"""Whether a backend is compatible with the given format."""
|
||||||
|
if not exists(backend):
|
||||||
|
raise ValueError("unknown backend: %s" % backend)
|
||||||
|
|
||||||
|
backend = backend.replace("-", "_")
|
||||||
|
format = format.replace("-", "_")
|
||||||
|
|
||||||
|
if backend == "nop":
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
func = tracetool.try_import("tracetool.backend." + backend,
|
||||||
|
format, None)[1]
|
||||||
|
return func is not None
|
||||||
|
|
||||||
|
|
||||||
|
def _empty(events):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def generate(backend, format, events):
|
||||||
|
"""Generate the per-event output for the given (backend, format) pair."""
|
||||||
|
if not compatible(backend, format):
|
||||||
|
raise ValueError("backend '%s' not compatible with format '%s'" %
|
||||||
|
(backend, format))
|
||||||
|
|
||||||
|
backend = backend.replace("-", "_")
|
||||||
|
format = format.replace("-", "_")
|
||||||
|
|
||||||
|
if backend == "nop":
|
||||||
|
func = tracetool.try_import("tracetool.format." + format,
|
||||||
|
"nop", _empty)[1]
|
||||||
|
else:
|
||||||
|
func = tracetool.try_import("tracetool.backend." + backend,
|
||||||
|
format, None)[1]
|
||||||
|
|
||||||
|
func(events)
|
97
scripts/tracetool/backend/dtrace.py
Normal file
97
scripts/tracetool/backend/dtrace.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
DTrace/SystemTAP backend.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
from tracetool import out
|
||||||
|
|
||||||
|
|
||||||
|
PROBEPREFIX = None
|
||||||
|
|
||||||
|
def _probeprefix():
|
||||||
|
if PROBEPREFIX is None:
|
||||||
|
raise ValueError("you must set PROBEPREFIX")
|
||||||
|
return PROBEPREFIX
|
||||||
|
|
||||||
|
|
||||||
|
BINARY = None
|
||||||
|
|
||||||
|
def _binary():
|
||||||
|
if BINARY is None:
|
||||||
|
raise ValueError("you must set BINARY")
|
||||||
|
return BINARY
|
||||||
|
|
||||||
|
|
||||||
|
def c(events):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def h(events):
|
||||||
|
out('#include "trace-dtrace.h"',
|
||||||
|
'')
|
||||||
|
|
||||||
|
for e in events:
|
||||||
|
out('static inline void trace_%(name)s(%(args)s) {',
|
||||||
|
' QEMU_%(uppername)s(%(argnames)s);',
|
||||||
|
'}',
|
||||||
|
name = e.name,
|
||||||
|
args = e.args,
|
||||||
|
uppername = e.name.upper(),
|
||||||
|
argnames = ", ".join(e.args.names()),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def d(events):
|
||||||
|
out('provider qemu {')
|
||||||
|
|
||||||
|
for e in events:
|
||||||
|
args = str(e.args)
|
||||||
|
|
||||||
|
# DTrace provider syntax expects foo() for empty
|
||||||
|
# params, not foo(void)
|
||||||
|
if args == 'void':
|
||||||
|
args = ''
|
||||||
|
|
||||||
|
# Define prototype for probe arguments
|
||||||
|
out('',
|
||||||
|
'probe %(name)s(%(args)s);',
|
||||||
|
name = e.name,
|
||||||
|
args = args,
|
||||||
|
)
|
||||||
|
|
||||||
|
out('',
|
||||||
|
'};')
|
||||||
|
|
||||||
|
|
||||||
|
def stap(events):
|
||||||
|
for e in events:
|
||||||
|
# Define prototype for probe arguments
|
||||||
|
out('probe %(probeprefix)s.%(name)s = process("%(binary)s").mark("%(name)s")',
|
||||||
|
'{',
|
||||||
|
probeprefix = _probeprefix(),
|
||||||
|
name = e.name,
|
||||||
|
binary = _binary(),
|
||||||
|
)
|
||||||
|
|
||||||
|
i = 1
|
||||||
|
if len(e.args) > 0:
|
||||||
|
for name in e.args.names():
|
||||||
|
# Append underscore to reserved keywords
|
||||||
|
if name in ('limit', 'in', 'next', 'self'):
|
||||||
|
name += '_'
|
||||||
|
out(' %s = $arg%d;' % (name, i))
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
out('}')
|
||||||
|
|
||||||
|
out()
|
55
scripts/tracetool/backend/simple.py
Normal file
55
scripts/tracetool/backend/simple.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Simple built-in backend.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
from tracetool import out
|
||||||
|
|
||||||
|
|
||||||
|
def c(events):
|
||||||
|
out('#include "trace.h"',
|
||||||
|
'',
|
||||||
|
'TraceEvent trace_list[] = {')
|
||||||
|
|
||||||
|
for e in events:
|
||||||
|
out('{.tp_name = "%(name)s", .state=0},',
|
||||||
|
name = e.name,
|
||||||
|
)
|
||||||
|
|
||||||
|
out('};')
|
||||||
|
|
||||||
|
def h(events):
|
||||||
|
out('#include "trace/simple.h"',
|
||||||
|
'')
|
||||||
|
|
||||||
|
for num, e in enumerate(events):
|
||||||
|
if len(e.args):
|
||||||
|
argstr = e.args.names()
|
||||||
|
arg_prefix = ', (uint64_t)(uintptr_t)'
|
||||||
|
cast_args = arg_prefix + arg_prefix.join(argstr)
|
||||||
|
simple_args = (str(num) + cast_args)
|
||||||
|
else:
|
||||||
|
simple_args = str(num)
|
||||||
|
|
||||||
|
out('static inline void trace_%(name)s(%(args)s)',
|
||||||
|
'{',
|
||||||
|
' trace%(argc)d(%(trace_args)s);',
|
||||||
|
'}',
|
||||||
|
name = e.name,
|
||||||
|
args = e.args,
|
||||||
|
argc = len(e.args),
|
||||||
|
trace_args = simple_args,
|
||||||
|
)
|
||||||
|
|
||||||
|
out('#define NR_TRACE_EVENTS %d' % len(events))
|
||||||
|
out('extern TraceEvent trace_list[NR_TRACE_EVENTS];')
|
56
scripts/tracetool/backend/stderr.py
Normal file
56
scripts/tracetool/backend/stderr.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Stderr built-in backend.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
from tracetool import out
|
||||||
|
|
||||||
|
|
||||||
|
def c(events):
|
||||||
|
out('#include "trace.h"',
|
||||||
|
'',
|
||||||
|
'TraceEvent trace_list[] = {')
|
||||||
|
|
||||||
|
for e in events:
|
||||||
|
out('{.tp_name = "%(name)s", .state=0},',
|
||||||
|
name = e.name,
|
||||||
|
)
|
||||||
|
|
||||||
|
out('};')
|
||||||
|
|
||||||
|
def h(events):
|
||||||
|
out('#include <stdio.h>',
|
||||||
|
'#include "trace/stderr.h"',
|
||||||
|
'',
|
||||||
|
'extern TraceEvent trace_list[];')
|
||||||
|
|
||||||
|
for num, e in enumerate(events):
|
||||||
|
argnames = ", ".join(e.args.names())
|
||||||
|
if len(e.args) > 0:
|
||||||
|
argnames = ", " + argnames
|
||||||
|
|
||||||
|
out('static inline void trace_%(name)s(%(args)s)',
|
||||||
|
'{',
|
||||||
|
' if (trace_list[%(event_num)s].state != 0) {',
|
||||||
|
' fprintf(stderr, "%(name)s " %(fmt)s "\\n" %(argnames)s);',
|
||||||
|
' }',
|
||||||
|
'}',
|
||||||
|
name = e.name,
|
||||||
|
args = e.args,
|
||||||
|
event_num = num,
|
||||||
|
fmt = e.fmt,
|
||||||
|
argnames = argnames,
|
||||||
|
)
|
||||||
|
|
||||||
|
out('',
|
||||||
|
'#define NR_TRACE_EVENTS %d' % len(events))
|
90
scripts/tracetool/backend/ust.py
Normal file
90
scripts/tracetool/backend/ust.py
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
LTTng User Space Tracing backend.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
from tracetool import out
|
||||||
|
|
||||||
|
|
||||||
|
def c(events):
|
||||||
|
out('#include <ust/marker.h>',
|
||||||
|
'#undef mutex_lock',
|
||||||
|
'#undef mutex_unlock',
|
||||||
|
'#undef inline',
|
||||||
|
'#undef wmb',
|
||||||
|
'#include "trace.h"')
|
||||||
|
|
||||||
|
for e in events:
|
||||||
|
argnames = ", ".join(e.args.names())
|
||||||
|
if len(e.args) > 0:
|
||||||
|
argnames = ', ' + argnames
|
||||||
|
|
||||||
|
out('DEFINE_TRACE(ust_%(name)s);',
|
||||||
|
'',
|
||||||
|
'static void ust_%(name)s_probe(%(args)s)',
|
||||||
|
'{',
|
||||||
|
' trace_mark(ust, %(name)s, %(fmt)s%(argnames)s);',
|
||||||
|
'}',
|
||||||
|
name = e.name,
|
||||||
|
args = e.args,
|
||||||
|
fmt = e.fmt,
|
||||||
|
argnames = argnames,
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
out('DEFINE_TRACE(ust_%(name)s);',
|
||||||
|
'',
|
||||||
|
'static void ust_%(name)s_probe(%(args)s)',
|
||||||
|
'{',
|
||||||
|
' trace_mark(ust, %(name)s, UST_MARKER_NOARGS);',
|
||||||
|
'}',
|
||||||
|
name = e.name,
|
||||||
|
args = e.args,
|
||||||
|
)
|
||||||
|
|
||||||
|
# register probes
|
||||||
|
out('',
|
||||||
|
'static void __attribute__((constructor)) trace_init(void)',
|
||||||
|
'{')
|
||||||
|
|
||||||
|
for e in events:
|
||||||
|
out(' register_trace_ust_%(name)s(ust_%(name)s_probe);',
|
||||||
|
name = e.name,
|
||||||
|
)
|
||||||
|
|
||||||
|
out('}')
|
||||||
|
|
||||||
|
|
||||||
|
def h(events):
|
||||||
|
out('#include <ust/tracepoint.h>',
|
||||||
|
'#undef mutex_lock',
|
||||||
|
'#undef mutex_unlock',
|
||||||
|
'#undef inline',
|
||||||
|
'#undef wmb')
|
||||||
|
|
||||||
|
for e in events:
|
||||||
|
if len(e.args) > 0:
|
||||||
|
out('DECLARE_TRACE(ust_%(name)s, TP_PROTO(%(args)s), TP_ARGS(%(argnames)s));',
|
||||||
|
'#define trace_%(name)s trace_ust_%(name)s',
|
||||||
|
name = e.name,
|
||||||
|
args = e.args,
|
||||||
|
argnames = ", ".join(e.args.names()),
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
out('_DECLARE_TRACEPOINT_NOARGS(ust_%(name)s);',
|
||||||
|
'#define trace_%(name)s trace_ust_%(name)s',
|
||||||
|
name = e.name,
|
||||||
|
)
|
||||||
|
|
||||||
|
out()
|
99
scripts/tracetool/format/__init__.py
Normal file
99
scripts/tracetool/format/__init__.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Format management.
|
||||||
|
|
||||||
|
|
||||||
|
Creating new formats
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
A new format named 'foo-bar' corresponds to Python module
|
||||||
|
'tracetool/format/foo_bar.py'.
|
||||||
|
|
||||||
|
A format module should provide a docstring, whose first non-empty line will be
|
||||||
|
considered its short description.
|
||||||
|
|
||||||
|
All formats must generate their contents through the 'tracetool.out' routine.
|
||||||
|
|
||||||
|
|
||||||
|
Format functions
|
||||||
|
----------------
|
||||||
|
|
||||||
|
All the following functions are optional, and no output will be generated if
|
||||||
|
they do not exist.
|
||||||
|
|
||||||
|
======== =======================================================================
|
||||||
|
Function Description
|
||||||
|
======== =======================================================================
|
||||||
|
begin Called to generate the format-specific file header.
|
||||||
|
end Called to generate the format-specific file footer.
|
||||||
|
nop Called to generate the per-event contents when the event is disabled or
|
||||||
|
the selected backend is 'nop'.
|
||||||
|
======== =======================================================================
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
import pkgutil
|
||||||
|
|
||||||
|
import tracetool
|
||||||
|
|
||||||
|
|
||||||
|
def get_list():
|
||||||
|
"""Get a list of (name, description) pairs."""
|
||||||
|
res = []
|
||||||
|
for _, modname, _ in pkgutil.iter_modules(tracetool.format.__path__):
|
||||||
|
module = tracetool.try_import("tracetool.format." + modname)
|
||||||
|
|
||||||
|
# just in case; should never fail unless non-module files are put there
|
||||||
|
if not module[0]:
|
||||||
|
continue
|
||||||
|
module = module[1]
|
||||||
|
|
||||||
|
doc = module.__doc__
|
||||||
|
if doc is None:
|
||||||
|
doc = ""
|
||||||
|
doc = doc.strip().split("\n")[0]
|
||||||
|
|
||||||
|
name = modname.replace("_", "-")
|
||||||
|
res.append((name, doc))
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
def exists(name):
|
||||||
|
"""Return whether the given format exists."""
|
||||||
|
if len(name) == 0:
|
||||||
|
return False
|
||||||
|
name = name.replace("-", "_")
|
||||||
|
return tracetool.try_import("tracetool.format." + name)[1]
|
||||||
|
|
||||||
|
|
||||||
|
def _empty(events):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def generate_begin(name, events):
|
||||||
|
"""Generate the header of the format-specific file."""
|
||||||
|
if not exists(name):
|
||||||
|
raise ValueError("unknown format: %s" % name)
|
||||||
|
|
||||||
|
name = name.replace("-", "_")
|
||||||
|
func = tracetool.try_import("tracetool.format." + name,
|
||||||
|
"begin", _empty)[1]
|
||||||
|
func(events)
|
||||||
|
|
||||||
|
def generate_end(name, events):
|
||||||
|
"""Generate the footer of the format-specific file."""
|
||||||
|
if not exists(name):
|
||||||
|
raise ValueError("unknown format: %s" % name)
|
||||||
|
|
||||||
|
name = name.replace("-", "_")
|
||||||
|
func = tracetool.try_import("tracetool.format." + name,
|
||||||
|
"end", _empty)[1]
|
||||||
|
func(events)
|
20
scripts/tracetool/format/c.py
Normal file
20
scripts/tracetool/format/c.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Generate .c file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
from tracetool import out
|
||||||
|
|
||||||
|
|
||||||
|
def begin(events):
|
||||||
|
out('/* This file is autogenerated by tracetool, do not edit. */')
|
20
scripts/tracetool/format/d.py
Normal file
20
scripts/tracetool/format/d.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Generate .d file (DTrace only).
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
from tracetool import out
|
||||||
|
|
||||||
|
|
||||||
|
def begin(events):
|
||||||
|
out('/* This file is autogenerated by tracetool, do not edit. */')
|
45
scripts/tracetool/format/h.py
Normal file
45
scripts/tracetool/format/h.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Generate .h file.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
from tracetool import out
|
||||||
|
|
||||||
|
|
||||||
|
def begin(events):
|
||||||
|
out('/* This file is autogenerated by tracetool, do not edit. */',
|
||||||
|
'',
|
||||||
|
'#ifndef TRACE_H',
|
||||||
|
'#define TRACE_H',
|
||||||
|
'',
|
||||||
|
'#include "qemu-common.h"')
|
||||||
|
|
||||||
|
def end(events):
|
||||||
|
for e in events:
|
||||||
|
if "disable" in e.properties:
|
||||||
|
enabled = 0
|
||||||
|
else:
|
||||||
|
enabled = 1
|
||||||
|
out('#define TRACE_%s_ENABLED %d' % (e.name.upper(), enabled))
|
||||||
|
out('',
|
||||||
|
'#endif /* TRACE_H */')
|
||||||
|
|
||||||
|
def nop(events):
|
||||||
|
for e in events:
|
||||||
|
out('',
|
||||||
|
'static inline void trace_%(name)s(%(args)s)',
|
||||||
|
'{',
|
||||||
|
'}',
|
||||||
|
name = e.name,
|
||||||
|
args = e.args,
|
||||||
|
)
|
20
scripts/tracetool/format/stap.py
Normal file
20
scripts/tracetool/format/stap.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""
|
||||||
|
Generate .stp file (DTrace with SystemTAP only).
|
||||||
|
"""
|
||||||
|
|
||||||
|
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||||
|
__license__ = "GPL version 2 or (at your option) any later version"
|
||||||
|
|
||||||
|
__maintainer__ = "Stefan Hajnoczi"
|
||||||
|
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||||
|
|
||||||
|
|
||||||
|
from tracetool import out
|
||||||
|
|
||||||
|
|
||||||
|
def begin(events):
|
||||||
|
out('/* This file is autogenerated by tracetool, do not edit. */')
|
Loading…
Reference in New Issue
Block a user