* [Qemu-devel] [RFC PATCH v2 0/8] Rewrite tracetool using python modules
@ 2012-03-26 17:37 Lluís Vilanova
2012-03-26 17:37 ` [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
` (7 more replies)
0 siblings, 8 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-26 17:37 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha
A full rewrite of the tracetool script using per-format and per-backend modules,
so that it's easier to read and extend it in the future.
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
NOTE: This series applies in current master, ignoring the "Rewrite tracetool
using python" series.
Changes in v2:
* Fixed a strange import error.
* Add a pointer to 'tracetool.out' in the format and backend documentation.
Lluís Vilanova (8):
tracetool: Rewrite infrastructure as python modules
tracetool: Add module for the 'c' format
tracetool: Add module for the 'h' format
tracetool: Add support for the 'stderr' backend
tracetool: Add support for the 'simple' backend
tracetool: Add support for the 'ust' backend
tracetool: Add support for the 'dtrace' backend
tracetool: Add MAINTAINERS info
MAINTAINERS | 2
Makefile.objs | 6
Makefile.target | 13 -
configure | 4
scripts/tracetool | 648 ---------------------------------
scripts/tracetool.py | 141 +++++++
scripts/tracetool/__init__.py | 213 +++++++++++
scripts/tracetool/backend/__init__.py | 114 ++++++
scripts/tracetool/backend/dtrace.py | 104 +++++
scripts/tracetool/backend/simple.py | 60 +++
scripts/tracetool/backend/stderr.py | 61 +++
scripts/tracetool/backend/ust.py | 102 +++++
scripts/tracetool/format/__init__.py | 91 +++++
scripts/tracetool/format/c.py | 20 +
scripts/tracetool/format/d.py | 20 +
scripts/tracetool/format/h.py | 45 ++
scripts/tracetool/format/stap.py | 20 +
17 files changed, 1005 insertions(+), 659 deletions(-)
delete mode 100755 scripts/tracetool
create mode 100755 scripts/tracetool.py
create mode 100644 scripts/tracetool/__init__.py
create mode 100644 scripts/tracetool/backend/__init__.py
create mode 100644 scripts/tracetool/backend/dtrace.py
create mode 100644 scripts/tracetool/backend/simple.py
create mode 100644 scripts/tracetool/backend/stderr.py
create mode 100644 scripts/tracetool/backend/ust.py
create mode 100644 scripts/tracetool/format/__init__.py
create mode 100644 scripts/tracetool/format/c.py
create mode 100644 scripts/tracetool/format/d.py
create mode 100644 scripts/tracetool/format/h.py
create mode 100644 scripts/tracetool/format/stap.py
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as python modules
2012-03-26 17:37 [Qemu-devel] [RFC PATCH v2 0/8] Rewrite tracetool using python modules Lluís Vilanova
@ 2012-03-26 17:37 ` Lluís Vilanova
2012-03-27 15:17 ` Alon Levy
` (2 more replies)
2012-03-26 17:37 ` [Qemu-devel] [RFC PATCH v2 2/8] tracetool: Add module for the 'c' format Lluís Vilanova
` (6 subsequent siblings)
7 siblings, 3 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-26 17:37 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
Makefile.objs | 6
Makefile.target | 13 -
configure | 4
scripts/tracetool | 648 ---------------------------------
scripts/tracetool.py | 110 ++++++
scripts/tracetool/__init__.py | 205 ++++++++++
scripts/tracetool/backend/__init__.py | 114 ++++++
scripts/tracetool/format/__init__.py | 91 +++++
8 files changed, 532 insertions(+), 659 deletions(-)
delete mode 100755 scripts/tracetool
create mode 100755 scripts/tracetool.py
create mode 100644 scripts/tracetool/__init__.py
create mode 100644 scripts/tracetool/backend/__init__.py
create mode 100644 scripts/tracetool/format/__init__.py
diff --git a/Makefile.objs b/Makefile.objs
index 226b01d..8e56f48 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -373,12 +373,12 @@ else
trace.h: trace.h-timestamp
endif
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
trace.c: trace.c-timestamp
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
trace.o: trace.c $(GENERATED_HEADERS)
@@ -391,7 +391,7 @@ trace-dtrace.h: trace-dtrace.dtrace
# rule file. So we use '.dtrace' instead
trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
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
trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
diff --git a/Makefile.target b/Makefile.target
index 63cf769..fe28e8b 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -59,12 +59,13 @@ TARGET_TYPE=system
endif
$(QEMU_PROG).stp:
- $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool \
- --$(TRACE_BACKEND) \
- --binary $(bindir)/$(QEMU_PROG) \
- --target-arch $(TARGET_ARCH) \
- --target-type $(TARGET_TYPE) \
- --stap < $(SRC_PATH)/trace-events > $(QEMU_PROG).stp," GEN $(QEMU_PROG).stp")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
+ --format=stap \
+ --backend=$(TRACE_BACKEND) \
+ --binary=$(bindir)/$(QEMU_PROG) \
+ --target-arch=$(TARGET_ARCH) \
+ --target-type=$(TARGET_TYPE) \
+ < $(SRC_PATH)/trace-events > $(QEMU_PROG).stp," GEN $(QEMU_PROG).stp")
else
stap:
endif
diff --git a/configure b/configure
index 8b4e3c1..c2d6117 100755
--- a/configure
+++ b/configure
@@ -1097,7 +1097,7 @@ 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 " --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 " Default:trace-<pid>"
echo " --disable-spice disable spice"
@@ -2654,7 +2654,7 @@ fi
##########################################
# 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
echo
echo "Error: invalid trace backend"
diff --git a/scripts/tracetool b/scripts/tracetool
deleted file mode 100755
index 65bd0a1..0000000
--- a/scripts/tracetool
+++ /dev/null
@@ -1,648 +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"
-}
-
-# 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
-}
-
-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 | tr '[:lower:]' '[:upper:]'`
-
- # 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
- # 'limit' is a reserved keyword
- if [ "$arg" = "limit" ]; then
- arg="_limit"
- fi
- 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 | tr '[:lower:]' '[:upper:]')
- 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
diff --git a/scripts/tracetool.py b/scripts/tracetool.py
new file mode 100755
index 0000000..22623ae
--- /dev/null
+++ b/scripts/tracetool.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Foo.
+"""
+
+__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.
+""" % {
+ "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 = sys.argv[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 = ""
+ 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":
+ public_backends = tracetool.backend.get_list(only_public = True)
+ out(", ".join([ b for b,_ in public_backends ]))
+ sys.exit(0)
+ elif opt == "--check-backend":
+ check_backend = True
+
+ 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)
+
+ kwargs = {}
+
+ try:
+ tracetool.generate(sys.stdin, arg_format, arg_backend, **kwargs)
+ except tracetool.TracetoolError as e:
+ error_opt(str(e))
+
+if __name__ == "__main__":
+ main(sys.argv)
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
new file mode 100644
index 0000000..d8e5cdd
--- /dev/null
+++ b/scripts/tracetool/__init__.py
@@ -0,0 +1,205 @@
+#!/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):
+ """Write a set of output lines."""
+ sys.stdout.writelines("\n".join(lines) + "\n")
+
+
+class Arguments:
+ """Event arguments description.
+
+ Parameters
+ ----------
+ arg_str : str
+ String describing the event arguments.
+ """
+
+ def __init__ (self, arg_str):
+ self._args = []
+ 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()
+ self._args.append((arg_type, tail))
+
+ 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 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.
+
+ Parameters
+ ----------
+ line : str
+ Line describing the event.
+
+ 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, line):
+ m = self._CRE.match(line)
+ assert m is not None
+ groups = m.groupdict('')
+ self.name = groups["name"]
+ self.fmt = groups["fmt"]
+ self.properties = groups["props"].split()
+ self.args = Arguments(groups["args"])
+
+ unknown_props = set(self.properties) - self._VALID_PROPS
+ if len(unknown_props) > 0:
+ raise ValueError("Unknown properties: %s" % ", ".join(unknown_props))
+
+
+def _read_events(fobj):
+ res = []
+ for line in fobj:
+ if not line.strip():
+ continue
+ if line.lstrip().startswith('#'):
+ continue
+ res.append(Event(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.
+ """
+ mod_name = mod_name.replace("-", "_")
+ 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, **options):
+ """Generate the output for the given (format, backend) pair."""
+ # fix strange python error (UnboundLocalError tracetool)
+ import tracetool
+
+ if len(options) > 0:
+ raise ValueError("unknown options: " + ", ".join(options))
+
+ 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))
+
+ 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)
diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py
new file mode 100644
index 0000000..23cad9f
--- /dev/null
+++ b/scripts/tracetool/backend/__init__.py
@@ -0,0 +1,114 @@
+#!/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 attributes
+------------------
+
+========= ====================================================================
+Attribute Description
+========= ====================================================================
+PUBLIC If exists and is set to 'True', the backend is considered "public".
+========= ====================================================================
+
+
+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(only_public = False):
+ """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)[1]
+
+ public = getattr(module, "PUBLIC", False)
+ if only_public and not public:
+ continue
+
+ 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
+ name = name.replace("-", "_")
+ if name == "nop":
+ return True
+ 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)
+
+ 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))
+
+ 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)
diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/format/__init__.py
new file mode 100644
index 0000000..5b37c00
--- /dev/null
+++ b/scripts/tracetool/format/__init__.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Format management.
+
+
+Creating new formats
+--------------------
+
+A new format named 'foo-bar' corresponds to Python module
+'tracetool/frontend/foo_bar.py'.
+
+A frontend 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)[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
+ 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)
+
+ 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)
+
+ func = tracetool.try_import("tracetool.format." + name,
+ "end", _empty)[1]
+ func(events)
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [RFC PATCH v2 2/8] tracetool: Add module for the 'c' format
2012-03-26 17:37 [Qemu-devel] [RFC PATCH v2 0/8] Rewrite tracetool using python modules Lluís Vilanova
2012-03-26 17:37 ` [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
@ 2012-03-26 17:37 ` Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 3/8] tracetool: Add module for the 'h' format Lluís Vilanova
` (5 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-26 17:37 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/tracetool/format/c.py | 20 ++++++++++++++++++++
1 files changed, 20 insertions(+), 0 deletions(-)
create mode 100644 scripts/tracetool/format/c.py
diff --git a/scripts/tracetool/format/c.py b/scripts/tracetool/format/c.py
new file mode 100644
index 0000000..35555ae
--- /dev/null
+++ b/scripts/tracetool/format/c.py
@@ -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. */')
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [RFC PATCH v2 3/8] tracetool: Add module for the 'h' format
2012-03-26 17:37 [Qemu-devel] [RFC PATCH v2 0/8] Rewrite tracetool using python modules Lluís Vilanova
2012-03-26 17:37 ` [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
2012-03-26 17:37 ` [Qemu-devel] [RFC PATCH v2 2/8] tracetool: Add module for the 'c' format Lluís Vilanova
@ 2012-03-26 17:38 ` Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 4/8] tracetool: Add support for the 'stderr' backend Lluís Vilanova
` (4 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-26 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/tracetool/format/h.py | 45 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 45 insertions(+), 0 deletions(-)
create mode 100644 scripts/tracetool/format/h.py
diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
new file mode 100644
index 0000000..41a3e2b
--- /dev/null
+++ b/scripts/tracetool/format/h.py
@@ -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
+ },
+ '{',
+ '}')
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [RFC PATCH v2 4/8] tracetool: Add support for the 'stderr' backend
2012-03-26 17:37 [Qemu-devel] [RFC PATCH v2 0/8] Rewrite tracetool using python modules Lluís Vilanova
` (2 preceding siblings ...)
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 3/8] tracetool: Add module for the 'h' format Lluís Vilanova
@ 2012-03-26 17:38 ` Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 5/8] tracetool: Add support for the 'simple' backend Lluís Vilanova
` (3 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-26 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/tracetool/backend/stderr.py | 61 +++++++++++++++++++++++++++++++++++
1 files changed, 61 insertions(+), 0 deletions(-)
create mode 100644 scripts/tracetool/backend/stderr.py
diff --git a/scripts/tracetool/backend/stderr.py b/scripts/tracetool/backend/stderr.py
new file mode 100644
index 0000000..5f9abcd
--- /dev/null
+++ b/scripts/tracetool/backend/stderr.py
@@ -0,0 +1,61 @@
+#!/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
+
+
+PUBLIC = True
+
+
+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))
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [RFC PATCH v2 5/8] tracetool: Add support for the 'simple' backend
2012-03-26 17:37 [Qemu-devel] [RFC PATCH v2 0/8] Rewrite tracetool using python modules Lluís Vilanova
` (3 preceding siblings ...)
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 4/8] tracetool: Add support for the 'stderr' backend Lluís Vilanova
@ 2012-03-26 17:38 ` Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 6/8] tracetool: Add support for the 'ust' backend Lluís Vilanova
` (2 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-26 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/tracetool/backend/simple.py | 60 +++++++++++++++++++++++++++++++++++
1 files changed, 60 insertions(+), 0 deletions(-)
create mode 100644 scripts/tracetool/backend/simple.py
diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py
new file mode 100644
index 0000000..fea0a37
--- /dev/null
+++ b/scripts/tracetool/backend/simple.py
@@ -0,0 +1,60 @@
+#!/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
+
+
+PUBLIC = True
+
+
+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];')
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [RFC PATCH v2 6/8] tracetool: Add support for the 'ust' backend
2012-03-26 17:37 [Qemu-devel] [RFC PATCH v2 0/8] Rewrite tracetool using python modules Lluís Vilanova
` (4 preceding siblings ...)
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 5/8] tracetool: Add support for the 'simple' backend Lluís Vilanova
@ 2012-03-26 17:38 ` Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 7/8] tracetool: Add support for the 'dtrace' backend Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 8/8] tracetool: Add MAINTAINERS info Lluís Vilanova
7 siblings, 0 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-26 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/tracetool/backend/ust.py | 102 ++++++++++++++++++++++++++++++++++++++
1 files changed, 102 insertions(+), 0 deletions(-)
create mode 100644 scripts/tracetool/backend/ust.py
diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py
new file mode 100644
index 0000000..6871373
--- /dev/null
+++ b/scripts/tracetool/backend/ust.py
@@ -0,0 +1,102 @@
+#!/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
+
+
+PUBLIC = True
+
+
+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()
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [RFC PATCH v2 7/8] tracetool: Add support for the 'dtrace' backend
2012-03-26 17:37 [Qemu-devel] [RFC PATCH v2 0/8] Rewrite tracetool using python modules Lluís Vilanova
` (5 preceding siblings ...)
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 6/8] tracetool: Add support for the 'ust' backend Lluís Vilanova
@ 2012-03-26 17:38 ` Lluís Vilanova
2012-03-27 15:19 ` Alon Levy
2012-03-27 16:20 ` Alon Levy
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 8/8] tracetool: Add MAINTAINERS info Lluís Vilanova
7 siblings, 2 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-26 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
scripts/tracetool.py | 31 ++++++++++
scripts/tracetool/__init__.py | 8 +++
scripts/tracetool/backend/dtrace.py | 104 +++++++++++++++++++++++++++++++++++
scripts/tracetool/format/d.py | 20 +++++++
scripts/tracetool/format/stap.py | 20 +++++++
5 files changed, 183 insertions(+), 0 deletions(-)
create mode 100644 scripts/tracetool/backend/dtrace.py
create mode 100644 scripts/tracetool/format/d.py
create mode 100644 scripts/tracetool/format/stap.py
diff --git a/scripts/tracetool.py b/scripts/tracetool.py
index 22623ae..2dd9da0 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -44,6 +44,11 @@ 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,
@@ -71,6 +76,10 @@ def main(args):
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()
@@ -87,6 +96,15 @@ def main(args):
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)
@@ -101,6 +119,19 @@ def main(args):
kwargs = {}
+ if 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 ])
+ kwargs["binary"] = binary
+ kwargs["probe_prefix"] = probe_prefix
+
try:
tracetool.generate(sys.stdin, arg_format, arg_backend, **kwargs)
except tracetool.TracetoolError as e:
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index d8e5cdd..d21f88a 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -167,6 +167,9 @@ def generate(fevents, format, backend, **options):
# fix strange python error (UnboundLocalError tracetool)
import tracetool
+ binary = options.pop("binary", None)
+ probe_prefix = options.pop("probe_prefix", None)
+
if len(options) > 0:
raise ValueError("unknown options: " + ", ".join(options))
@@ -188,6 +191,11 @@ def generate(fevents, format, backend, **options):
raise TracetoolError("backend '%s' not compatible with format '%s'" %
(backend, format))
+ if backend == "dtrace":
+ import tracetool.backend.dtrace
+ tracetool.backend.dtrace.BINARY = binary
+ tracetool.backend.dtrace.PROBEPREFIX = probe_prefix
+
events = _read_events(fevents)
if backend == "nop":
diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
new file mode 100644
index 0000000..7c2051c
--- /dev/null
+++ b/scripts/tracetool/backend/dtrace.py
@@ -0,0 +1,104 @@
+#!/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
+
+
+PUBLIC = True
+
+
+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 = 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():
+ # 'limit' is a reserved keyword
+ if name == 'limit':
+ name = '_limit'
+ out(' %s = $arg%d;' % (name.lstrip(), i))
+ i += 1
+
+ out('}')
+
+ out()
diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py
new file mode 100644
index 0000000..a2d5947
--- /dev/null
+++ b/scripts/tracetool/format/d.py
@@ -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. */')
diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py
new file mode 100644
index 0000000..50a4c69
--- /dev/null
+++ b/scripts/tracetool/format/stap.py
@@ -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. */')
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [Qemu-devel] [RFC PATCH v2 8/8] tracetool: Add MAINTAINERS info
2012-03-26 17:37 [Qemu-devel] [RFC PATCH v2 0/8] Rewrite tracetool using python modules Lluís Vilanova
` (6 preceding siblings ...)
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 7/8] tracetool: Add support for the 'dtrace' backend Lluís Vilanova
@ 2012-03-26 17:38 ` Lluís Vilanova
7 siblings, 0 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-26 17:38 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha
Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
MAINTAINERS | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index f83d07c2..0e66dd8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -548,6 +548,8 @@ Tracing
M: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
S: Maintained
F: trace/
+F: scripts/tracetool.py
+F: scripts/tracetool/
F: docs/tracing.txt
T: git://github.com/stefanha/qemu.git tracing
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as python modules
2012-03-26 17:37 ` [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
@ 2012-03-27 15:17 ` Alon Levy
2012-03-27 17:47 ` Lluís Vilanova
2012-03-27 15:21 ` Alon Levy
2012-03-27 16:37 ` [Qemu-devel] [PATCH] tracetool.py: always pass --binary, --target-arch, --target-type Alon Levy
2 siblings, 1 reply; 18+ messages in thread
From: Alon Levy @ 2012-03-27 15:17 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: stefanha, qemu-devel
On Mon, Mar 26, 2012 at 07:37:50PM +0200, Lluís Vilanova wrote:
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Hi,
Some comments inline.
Alon
> ---
> Makefile.objs | 6
> Makefile.target | 13 -
> configure | 4
> scripts/tracetool | 648 ---------------------------------
> scripts/tracetool.py | 110 ++++++
> scripts/tracetool/__init__.py | 205 ++++++++++
> scripts/tracetool/backend/__init__.py | 114 ++++++
> scripts/tracetool/format/__init__.py | 91 +++++
> 8 files changed, 532 insertions(+), 659 deletions(-)
> delete mode 100755 scripts/tracetool
> create mode 100755 scripts/tracetool.py
> create mode 100644 scripts/tracetool/__init__.py
> create mode 100644 scripts/tracetool/backend/__init__.py
> create mode 100644 scripts/tracetool/format/__init__.py
>
> diff --git a/Makefile.objs b/Makefile.objs
> index 226b01d..8e56f48 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -373,12 +373,12 @@ else
> trace.h: trace.h-timestamp
> endif
> 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
>
> trace.c: trace.c-timestamp
> 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
>
> trace.o: trace.c $(GENERATED_HEADERS)
> @@ -391,7 +391,7 @@ trace-dtrace.h: trace-dtrace.dtrace
> # rule file. So we use '.dtrace' instead
> trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
> 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
>
> trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
> diff --git a/Makefile.target b/Makefile.target
> index 63cf769..fe28e8b 100644
> --- a/Makefile.target
> +++ b/Makefile.target
> @@ -59,12 +59,13 @@ TARGET_TYPE=system
> endif
>
> $(QEMU_PROG).stp:
> - $(call quiet-command,sh $(SRC_PATH)/scripts/tracetool \
> - --$(TRACE_BACKEND) \
> - --binary $(bindir)/$(QEMU_PROG) \
> - --target-arch $(TARGET_ARCH) \
> - --target-type $(TARGET_TYPE) \
> - --stap < $(SRC_PATH)/trace-events > $(QEMU_PROG).stp," GEN $(QEMU_PROG).stp")
> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
> + --format=stap \
> + --backend=$(TRACE_BACKEND) \
> + --binary=$(bindir)/$(QEMU_PROG) \
> + --target-arch=$(TARGET_ARCH) \
> + --target-type=$(TARGET_TYPE) \
> + < $(SRC_PATH)/trace-events > $(QEMU_PROG).stp," GEN $(QEMU_PROG).stp")
> else
> stap:
> endif
> diff --git a/configure b/configure
> index 8b4e3c1..c2d6117 100755
> --- a/configure
> +++ b/configure
> @@ -1097,7 +1097,7 @@ 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 " --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 " Default:trace-<pid>"
> echo " --disable-spice disable spice"
> @@ -2654,7 +2654,7 @@ fi
> ##########################################
> # 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
> echo
> echo "Error: invalid trace backend"
> diff --git a/scripts/tracetool b/scripts/tracetool
> deleted file mode 100755
> index 65bd0a1..0000000
> --- a/scripts/tracetool
> +++ /dev/null
> @@ -1,648 +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"
> -}
> -
> -# 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
> -}
> -
> -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 | tr '[:lower:]' '[:upper:]'`
> -
> - # 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
> - # 'limit' is a reserved keyword
> - if [ "$arg" = "limit" ]; then
> - arg="_limit"
> - fi
> - 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 | tr '[:lower:]' '[:upper:]')
> - 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
> diff --git a/scripts/tracetool.py b/scripts/tracetool.py
> new file mode 100755
> index 0000000..22623ae
> --- /dev/null
> +++ b/scripts/tracetool.py
> @@ -0,0 +1,110 @@
> +#!/usr/bin/env python
> +# -*- coding: utf-8 -*-
> +
> +"""
> +Foo.
Real docstring missing.
> +"""
> +
> +__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 = ""
I don't understand the point of this, why not use sys.argv[0] directly?
> +
> +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.
> +""" % {
> + "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 = sys.argv[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 = ""
> + 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":
> + public_backends = tracetool.backend.get_list(only_public = True)
> + out(", ".join([ b for b,_ in public_backends ]))
> + sys.exit(0)
> + elif opt == "--check-backend":
> + check_backend = True
> +
> + 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)
> +
> + kwargs = {}
> +
> + try:
> + tracetool.generate(sys.stdin, arg_format, arg_backend, **kwargs)
> + except tracetool.TracetoolError as e:
> + error_opt(str(e))
> +
> +if __name__ == "__main__":
> + main(sys.argv)
> diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
> new file mode 100644
> index 0000000..d8e5cdd
> --- /dev/null
> +++ b/scripts/tracetool/__init__.py
> @@ -0,0 +1,205 @@
> +#!/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):
> + """Write a set of output lines."""
> + sys.stdout.writelines("\n".join(lines) + "\n")
> +
> +
> +class Arguments:
> + """Event arguments description.
> +
> + Parameters
> + ----------
> + arg_str : str
> + String describing the event arguments.
> + """
> +
> + def __init__ (self, arg_str):
> + self._args = []
> + 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()
> + self._args.append((arg_type, tail))
> +
> + 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 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.
> +
> + Parameters
> + ----------
> + line : str
> + Line describing the event.
> +
> + 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, line):
> + m = self._CRE.match(line)
> + assert m is not None
> + groups = m.groupdict('')
> + self.name = groups["name"]
> + self.fmt = groups["fmt"]
> + self.properties = groups["props"].split()
> + self.args = Arguments(groups["args"])
> +
> + unknown_props = set(self.properties) - self._VALID_PROPS
> + if len(unknown_props) > 0:
> + raise ValueError("Unknown properties: %s" % ", ".join(unknown_props))
> +
> +
> +def _read_events(fobj):
> + res = []
> + for line in fobj:
> + if not line.strip():
> + continue
> + if line.lstrip().startswith('#'):
> + continue
Tab got in.
> + res.append(Event(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.
> + """
> + mod_name = mod_name.replace("-", "_")
> + 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, **options):
> + """Generate the output for the given (format, backend) pair."""
> + # fix strange python error (UnboundLocalError tracetool)
> + import tracetool
> +
> + if len(options) > 0:
> + raise ValueError("unknown options: " + ", ".join(options))
> +
> + 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))
> +
> + 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)
> diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py
> new file mode 100644
> index 0000000..23cad9f
> --- /dev/null
> +++ b/scripts/tracetool/backend/__init__.py
> @@ -0,0 +1,114 @@
> +#!/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 attributes
> +------------------
> +
> +========= ====================================================================
> +Attribute Description
> +========= ====================================================================
> +PUBLIC If exists and is set to 'True', the backend is considered "public".
> +========= ====================================================================
> +
> +
> +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(only_public = False):
> + """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)[1]
> +
Here module can be None if ImportError was raised in try_import.
> + public = getattr(module, "PUBLIC", False)
public will be False
> + if only_public and not public:
> + continue
continue isn't reached if not only_public (default value)
> +
> + 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
> + name = name.replace("-", "_")
> + if name == "nop":
> + return True
> + 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)
> +
> + 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))
> +
> + 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)
> diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/format/__init__.py
> new file mode 100644
> index 0000000..5b37c00
> --- /dev/null
> +++ b/scripts/tracetool/format/__init__.py
> @@ -0,0 +1,91 @@
> +#!/usr/bin/env python
> +# -*- coding: utf-8 -*-
> +
> +"""
> +Format management.
> +
> +
> +Creating new formats
> +--------------------
> +
> +A new format named 'foo-bar' corresponds to Python module
> +'tracetool/frontend/foo_bar.py'.
s/frontend/format/ And in later places.
> +
> +A frontend 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)[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
> + 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)
> +
> + 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)
> +
> + func = tracetool.try_import("tracetool.format." + name,
> + "end", _empty)[1]
> + func(events)
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v2 7/8] tracetool: Add support for the 'dtrace' backend
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 7/8] tracetool: Add support for the 'dtrace' backend Lluís Vilanova
@ 2012-03-27 15:19 ` Alon Levy
2012-03-27 16:20 ` Alon Levy
1 sibling, 0 replies; 18+ messages in thread
From: Alon Levy @ 2012-03-27 15:19 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: stefanha, qemu-devel
On Mon, Mar 26, 2012 at 07:38:23PM +0200, Lluís Vilanova wrote:
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
> scripts/tracetool.py | 31 ++++++++++
> scripts/tracetool/__init__.py | 8 +++
> scripts/tracetool/backend/dtrace.py | 104 +++++++++++++++++++++++++++++++++++
> scripts/tracetool/format/d.py | 20 +++++++
> scripts/tracetool/format/stap.py | 20 +++++++
> 5 files changed, 183 insertions(+), 0 deletions(-)
> create mode 100644 scripts/tracetool/backend/dtrace.py
> create mode 100644 scripts/tracetool/format/d.py
> create mode 100644 scripts/tracetool/format/stap.py
>
> diff --git a/scripts/tracetool.py b/scripts/tracetool.py
> index 22623ae..2dd9da0 100755
> --- a/scripts/tracetool.py
> +++ b/scripts/tracetool.py
> @@ -44,6 +44,11 @@ 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,
> @@ -71,6 +76,10 @@ def main(args):
> 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()
> @@ -87,6 +96,15 @@ def main(args):
> 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)
>
> @@ -101,6 +119,19 @@ def main(args):
>
> kwargs = {}
>
> + if 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 ])
> + kwargs["binary"] = binary
> + kwargs["probe_prefix"] = probe_prefix
> +
> try:
> tracetool.generate(sys.stdin, arg_format, arg_backend, **kwargs)
> except tracetool.TracetoolError as e:
> diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
> index d8e5cdd..d21f88a 100644
> --- a/scripts/tracetool/__init__.py
> +++ b/scripts/tracetool/__init__.py
> @@ -167,6 +167,9 @@ def generate(fevents, format, backend, **options):
> # fix strange python error (UnboundLocalError tracetool)
> import tracetool
>
> + binary = options.pop("binary", None)
> + probe_prefix = options.pop("probe_prefix", None)
> +
> if len(options) > 0:
> raise ValueError("unknown options: " + ", ".join(options))
>
> @@ -188,6 +191,11 @@ def generate(fevents, format, backend, **options):
> raise TracetoolError("backend '%s' not compatible with format '%s'" %
> (backend, format))
>
> + if backend == "dtrace":
> + import tracetool.backend.dtrace
> + tracetool.backend.dtrace.BINARY = binary
> + tracetool.backend.dtrace.PROBEPREFIX = probe_prefix
> +
> events = _read_events(fevents)
>
> if backend == "nop":
> diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
> new file mode 100644
> index 0000000..7c2051c
> --- /dev/null
> +++ b/scripts/tracetool/backend/dtrace.py
> @@ -0,0 +1,104 @@
> +#!/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
> +
> +
> +PUBLIC = True
> +
> +
> +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 = e.args
> +
> + # DTrace provider syntax expects foo() for empty
> + # params, not foo(void)
> + if args == 'void':
This fails. since args is now an Arguments instace. Fixed by changing
to:
+ if str(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():
> + # 'limit' is a reserved keyword
> + if name == 'limit':
> + name = '_limit'
> + out(' %s = $arg%d;' % (name.lstrip(), i))
> + i += 1
> +
> + out('}')
> +
> + out()
> diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py
> new file mode 100644
> index 0000000..a2d5947
> --- /dev/null
> +++ b/scripts/tracetool/format/d.py
> @@ -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. */')
> diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py
> new file mode 100644
> index 0000000..50a4c69
> --- /dev/null
> +++ b/scripts/tracetool/format/stap.py
> @@ -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. */')
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as python modules
2012-03-26 17:37 ` [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
2012-03-27 15:17 ` Alon Levy
@ 2012-03-27 15:21 ` Alon Levy
2012-03-27 16:37 ` [Qemu-devel] [PATCH] tracetool.py: always pass --binary, --target-arch, --target-type Alon Levy
2 siblings, 0 replies; 18+ messages in thread
From: Alon Levy @ 2012-03-27 15:21 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: stefanha, qemu-devel
On Mon, Mar 26, 2012 at 07:37:50PM +0200, Lluís Vilanova wrote:
An additional comment I forgot to add.
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
[snip]
> + 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 ])
> +
Nice to have addition (for debugging mainly):
+ def __repr__(self):
+ """String suitable to recreate this instance."""
+ return '%s("%s")' % (self.__class__.__name__, 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.
> +
> + Parameters
> + ----------
> + line : str
> + Line describing the event.
> +
> + 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, line):
> + m = self._CRE.match(line)
> + assert m is not None
> + groups = m.groupdict('')
> + self.name = groups["name"]
> + self.fmt = groups["fmt"]
> + self.properties = groups["props"].split()
> + self.args = Arguments(groups["args"])
> +
> + unknown_props = set(self.properties) - self._VALID_PROPS
> + if len(unknown_props) > 0:
> + raise ValueError("Unknown properties: %s" % ", ".join(unknown_props))
> +
> +
> +def _read_events(fobj):
> + res = []
> + for line in fobj:
> + if not line.strip():
> + continue
> + if line.lstrip().startswith('#'):
> + continue
> + res.append(Event(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.
> + """
> + mod_name = mod_name.replace("-", "_")
> + 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, **options):
> + """Generate the output for the given (format, backend) pair."""
> + # fix strange python error (UnboundLocalError tracetool)
> + import tracetool
> +
> + if len(options) > 0:
> + raise ValueError("unknown options: " + ", ".join(options))
> +
> + 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))
> +
> + 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)
> diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py
> new file mode 100644
> index 0000000..23cad9f
> --- /dev/null
> +++ b/scripts/tracetool/backend/__init__.py
> @@ -0,0 +1,114 @@
> +#!/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 attributes
> +------------------
> +
> +========= ====================================================================
> +Attribute Description
> +========= ====================================================================
> +PUBLIC If exists and is set to 'True', the backend is considered "public".
> +========= ====================================================================
> +
> +
> +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(only_public = False):
> + """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)[1]
> +
> + public = getattr(module, "PUBLIC", False)
> + if only_public and not public:
> + continue
> +
> + 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
> + name = name.replace("-", "_")
> + if name == "nop":
> + return True
> + 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)
> +
> + 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))
> +
> + 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)
> diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/format/__init__.py
> new file mode 100644
> index 0000000..5b37c00
> --- /dev/null
> +++ b/scripts/tracetool/format/__init__.py
> @@ -0,0 +1,91 @@
> +#!/usr/bin/env python
> +# -*- coding: utf-8 -*-
> +
> +"""
> +Format management.
> +
> +
> +Creating new formats
> +--------------------
> +
> +A new format named 'foo-bar' corresponds to Python module
> +'tracetool/frontend/foo_bar.py'.
> +
> +A frontend 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)[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
> + 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)
> +
> + 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)
> +
> + func = tracetool.try_import("tracetool.format." + name,
> + "end", _empty)[1]
> + func(events)
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v2 7/8] tracetool: Add support for the 'dtrace' backend
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 7/8] tracetool: Add support for the 'dtrace' backend Lluís Vilanova
2012-03-27 15:19 ` Alon Levy
@ 2012-03-27 16:20 ` Alon Levy
1 sibling, 0 replies; 18+ messages in thread
From: Alon Levy @ 2012-03-27 16:20 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: stefanha, qemu-devel
On Mon, Mar 26, 2012 at 07:38:23PM +0200, Lluís Vilanova wrote:
> Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
> ---
Additional comment inline.
> scripts/tracetool.py | 31 ++++++++++
> scripts/tracetool/__init__.py | 8 +++
> scripts/tracetool/backend/dtrace.py | 104 +++++++++++++++++++++++++++++++++++
> scripts/tracetool/format/d.py | 20 +++++++
> scripts/tracetool/format/stap.py | 20 +++++++
> 5 files changed, 183 insertions(+), 0 deletions(-)
> create mode 100644 scripts/tracetool/backend/dtrace.py
> create mode 100644 scripts/tracetool/format/d.py
> create mode 100644 scripts/tracetool/format/stap.py
>
> diff --git a/scripts/tracetool.py b/scripts/tracetool.py
> index 22623ae..2dd9da0 100755
> --- a/scripts/tracetool.py
> +++ b/scripts/tracetool.py
> @@ -44,6 +44,11 @@ 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,
> @@ -71,6 +76,10 @@ def main(args):
> 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()
> @@ -87,6 +96,15 @@ def main(args):
> 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)
>
> @@ -101,6 +119,19 @@ def main(args):
>
> kwargs = {}
>
> + if format == "stap":
Needs to be
+ if arg_backed == "dtrace":
> + 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 ])
> + kwargs["binary"] = binary
> + kwargs["probe_prefix"] = probe_prefix
> +
> try:
> tracetool.generate(sys.stdin, arg_format, arg_backend, **kwargs)
> except tracetool.TracetoolError as e:
> diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
> index d8e5cdd..d21f88a 100644
> --- a/scripts/tracetool/__init__.py
> +++ b/scripts/tracetool/__init__.py
> @@ -167,6 +167,9 @@ def generate(fevents, format, backend, **options):
> # fix strange python error (UnboundLocalError tracetool)
> import tracetool
>
> + binary = options.pop("binary", None)
> + probe_prefix = options.pop("probe_prefix", None)
> +
> if len(options) > 0:
> raise ValueError("unknown options: " + ", ".join(options))
>
> @@ -188,6 +191,11 @@ def generate(fevents, format, backend, **options):
> raise TracetoolError("backend '%s' not compatible with format '%s'" %
> (backend, format))
>
> + if backend == "dtrace":
> + import tracetool.backend.dtrace
> + tracetool.backend.dtrace.BINARY = binary
> + tracetool.backend.dtrace.PROBEPREFIX = probe_prefix
> +
> events = _read_events(fevents)
>
> if backend == "nop":
> diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
> new file mode 100644
> index 0000000..7c2051c
> --- /dev/null
> +++ b/scripts/tracetool/backend/dtrace.py
> @@ -0,0 +1,104 @@
> +#!/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
> +
> +
> +PUBLIC = True
> +
> +
> +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 = 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():
> + # 'limit' is a reserved keyword
> + if name == 'limit':
> + name = '_limit'
> + out(' %s = $arg%d;' % (name.lstrip(), i))
> + i += 1
> +
> + out('}')
> +
> + out()
> diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py
> new file mode 100644
> index 0000000..a2d5947
> --- /dev/null
> +++ b/scripts/tracetool/format/d.py
> @@ -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. */')
> diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py
> new file mode 100644
> index 0000000..50a4c69
> --- /dev/null
> +++ b/scripts/tracetool/format/stap.py
> @@ -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. */')
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* [Qemu-devel] [PATCH] tracetool.py: always pass --binary, --target-arch, --target-type
2012-03-26 17:37 ` [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
2012-03-27 15:17 ` Alon Levy
2012-03-27 15:21 ` Alon Levy
@ 2012-03-27 16:37 ` Alon Levy
2012-03-27 18:01 ` Lluís Vilanova
2 siblings, 1 reply; 18+ messages in thread
From: Alon Levy @ 2012-03-27 16:37 UTC (permalink / raw)
To: qemu-devel, Lluís Vilanova; +Cc: stefanha
Signed-off-by: Alon Levy <alevy@redhat.com>
---
Makefile.objs | 25 ++++++++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/Makefile.objs b/Makefile.objs
index 8e56f48..0e33f4b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -373,12 +373,25 @@ else
trace.h: trace.h-timestamp
endif
trace.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=h --backend=$(TRACE_BACKEND) < $< > $@," GEN trace.h")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
+ --format=h \
+ --backend=$(TRACE_BACKEND) \
+ --binary=$(bindir)/$(QEMU_PROG) \
+ --target-arch=$(TARGET_ARCH) \
+ --target-type=$(TARGET_TYPE) \
+ --target-type=$(TARGET_TYPE) < $< > $@, \
+ " GEN trace.h")
@cmp -s $@ trace.h || cp $@ trace.h
trace.c: trace.c-timestamp
trace.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=c --backend=$(TRACE_BACKEND) < $< > $@," GEN trace.c")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
+ --format=c \
+ --backend=$(TRACE_BACKEND) \
+ --binary=$(bindir)/$(QEMU_PROG) \
+ --target-arch=$(TARGET_ARCH) \
+ --target-type=$(TARGET_TYPE) < $< > $@, \
+ " GEN trace.c")
@cmp -s $@ trace.c || cp $@ trace.c
trace.o: trace.c $(GENERATED_HEADERS)
@@ -391,7 +404,13 @@ trace-dtrace.h: trace-dtrace.dtrace
# rule file. So we use '.dtrace' instead
trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
- $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=d --backend=$(TRACE_BACKEND) < $< > $@," GEN trace-dtrace.dtrace")
+ $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
+ --format=d \
+ --backend=$(TRACE_BACKEND) \
+ --binary=$(bindir)/$(QEMU_PROG) \
+ --target-arch=$(TARGET_ARCH) \
+ --target-type=$(TARGET_TYPE) < $< > $@, \
+ " GEN trace-dtrace.dtrace")
@cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace
trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
--
1.7.9.3
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as python modules
2012-03-27 15:17 ` Alon Levy
@ 2012-03-27 17:47 ` Lluís Vilanova
0 siblings, 0 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-27 17:47 UTC (permalink / raw)
To: qemu-devel; +Cc: stefanha
Alon Levy writes:
[...]
>> +
>> +
>> +_SCRIPT = ""
> I don't understand the point of this, why not use sys.argv[0] directly?
[...]
>> +def main(args):
>> + global _SCRIPT
>> + _SCRIPT = sys.argv[0]
>> +
Well, my idea is that it must work only with the arguments to 'main',
without depending on any other system state.
BTW, I fixed main to be "_SCRIPT = args[0]" instead of "sys.argv[0]" (otherwise
it makes no sense).
[...]
>> +def get_list(only_public = False):
>> + """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)[1]
>> +
> Here module can be None if ImportError was raised in try_import.
>> + public = getattr(module, "PUBLIC", False)
> public will be False
Not really; as it only tries to import files stemming from
'pkgutil.iter_modules', this should always succeed.
In any case, I put a guard just in case someone puts a non-module file there
(which should never happen).
>> + if only_public and not public:
>> + continue
> continue isn't reached if not only_public (default value)
Right, 'only_public' is only used sometimes (when handling "--list-backends"
cmdline option).
I'll send a new version once I put all the changes into my tree.
Thanks for all the catches,
Lluis
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH] tracetool.py: always pass --binary, --target-arch, --target-type
2012-03-27 16:37 ` [Qemu-devel] [PATCH] tracetool.py: always pass --binary, --target-arch, --target-type Alon Levy
@ 2012-03-27 18:01 ` Lluís Vilanova
2012-03-28 9:35 ` Alon Levy
0 siblings, 1 reply; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-27 18:01 UTC (permalink / raw)
To: Alon Levy; +Cc: stefanha, qemu-devel
Alon Levy writes:
> Signed-off-by: Alon Levy <alevy@redhat.com>
> ---
> Makefile.objs | 25 ++++++++++++++++++++++---
> 1 file changed, 22 insertions(+), 3 deletions(-)
> diff --git a/Makefile.objs b/Makefile.objs
> index 8e56f48..0e33f4b 100644
> --- a/Makefile.objs
> +++ b/Makefile.objs
> @@ -373,12 +373,25 @@ else
> trace.h: trace.h-timestamp
> endif
> trace.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
> - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=h --backend=$(TRACE_BACKEND) < $< > $@," GEN trace.h")
> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
> + --format=h \
> + --backend=$(TRACE_BACKEND) \
> + --binary=$(bindir)/$(QEMU_PROG) \
> + --target-arch=$(TARGET_ARCH) \
> + --target-type=$(TARGET_TYPE) \
> + --target-type=$(TARGET_TYPE) < $< > $@, \
> + " GEN trace.h")
> @cmp -s $@ trace.h || cp $@ trace.h
> trace.c: trace.c-timestamp
> trace.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
> - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=c --backend=$(TRACE_BACKEND) < $< > $@," GEN trace.c")
> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
> + --format=c \
> + --backend=$(TRACE_BACKEND) \
> + --binary=$(bindir)/$(QEMU_PROG) \
> + --target-arch=$(TARGET_ARCH) \
> + --target-type=$(TARGET_TYPE) < $< > $@, \
> + " GEN trace.c")
> @cmp -s $@ trace.c || cp $@ trace.c
> trace.o: trace.c $(GENERATED_HEADERS)
> @@ -391,7 +404,13 @@ trace-dtrace.h: trace-dtrace.dtrace
> # rule file. So we use '.dtrace' instead
> trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
> trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
> - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=d --backend=$(TRACE_BACKEND) < $< > $@," GEN trace-dtrace.dtrace")
> + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
> + --format=d \
> + --backend=$(TRACE_BACKEND) \
> + --binary=$(bindir)/$(QEMU_PROG) \
> + --target-arch=$(TARGET_ARCH) \
> + --target-type=$(TARGET_TYPE) < $< > $@, \
> + " GEN trace-dtrace.dtrace")
> @cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace
> trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
> --
> 1.7.9.3
I don't see the reason for such a change, as in the current bash code it's not
used except when generating files in the 'stap' format.
Same applies to your change in tracetool.py when checking the binary/probe/etc
options.
Lluis
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH] tracetool.py: always pass --binary, --target-arch, --target-type
2012-03-27 18:01 ` Lluís Vilanova
@ 2012-03-28 9:35 ` Alon Levy
2012-03-28 10:29 ` Lluís Vilanova
0 siblings, 1 reply; 18+ messages in thread
From: Alon Levy @ 2012-03-28 9:35 UTC (permalink / raw)
To: Lluís Vilanova; +Cc: stefanha, qemu-devel
On Tue, Mar 27, 2012 at 08:01:54PM +0200, Lluís Vilanova wrote:
> Alon Levy writes:
>
> > Signed-off-by: Alon Levy <alevy@redhat.com>
> > ---
> > Makefile.objs | 25 ++++++++++++++++++++++---
> > 1 file changed, 22 insertions(+), 3 deletions(-)
>
> > diff --git a/Makefile.objs b/Makefile.objs
> > index 8e56f48..0e33f4b 100644
> > --- a/Makefile.objs
> > +++ b/Makefile.objs
> > @@ -373,12 +373,25 @@ else
> > trace.h: trace.h-timestamp
> > endif
> > trace.h-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
> > - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=h --backend=$(TRACE_BACKEND) < $< > $@," GEN trace.h")
> > + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
> > + --format=h \
> > + --backend=$(TRACE_BACKEND) \
> > + --binary=$(bindir)/$(QEMU_PROG) \
> > + --target-arch=$(TARGET_ARCH) \
> > + --target-type=$(TARGET_TYPE) \
> > + --target-type=$(TARGET_TYPE) < $< > $@, \
> > + " GEN trace.h")
> > @cmp -s $@ trace.h || cp $@ trace.h
>
> > trace.c: trace.c-timestamp
> > trace.c-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
> > - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=c --backend=$(TRACE_BACKEND) < $< > $@," GEN trace.c")
> > + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
> > + --format=c \
> > + --backend=$(TRACE_BACKEND) \
> > + --binary=$(bindir)/$(QEMU_PROG) \
> > + --target-arch=$(TARGET_ARCH) \
> > + --target-type=$(TARGET_TYPE) < $< > $@, \
> > + " GEN trace.c")
> > @cmp -s $@ trace.c || cp $@ trace.c
>
> > trace.o: trace.c $(GENERATED_HEADERS)
> > @@ -391,7 +404,13 @@ trace-dtrace.h: trace-dtrace.dtrace
> > # rule file. So we use '.dtrace' instead
> > trace-dtrace.dtrace: trace-dtrace.dtrace-timestamp
> > trace-dtrace.dtrace-timestamp: $(SRC_PATH)/trace-events $(BUILD_DIR)/config-host.mak
> > - $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py --format=d --backend=$(TRACE_BACKEND) < $< > $@," GEN trace-dtrace.dtrace")
> > + $(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/tracetool.py \
> > + --format=d \
> > + --backend=$(TRACE_BACKEND) \
> > + --binary=$(bindir)/$(QEMU_PROG) \
> > + --target-arch=$(TARGET_ARCH) \
> > + --target-type=$(TARGET_TYPE) < $< > $@, \
> > + " GEN trace-dtrace.dtrace")
> > @cmp -s $@ trace-dtrace.dtrace || cp $@ trace-dtrace.dtrace
>
> > trace-dtrace.o: trace-dtrace.dtrace $(GENERATED_HEADERS)
> > --
> > 1.7.9.3
>
> I don't see the reason for such a change, as in the current bash code it's not
> used except when generating files in the 'stap' format.
Have you tried building with trace backend dtrace? without those changed
it breaks because tracetool.py requires both target_arch and target_type
for dtrace backend. Either change the source or change the invocation. I
thought the later is better, hence this patch.
>
> Same applies to your change in tracetool.py when checking the binary/probe/etc
> options.
>
>
> Lluis
>
> --
> "And it's much the same thing with knowledge, for whenever you learn
> something new, the whole world becomes that much richer."
> -- The Princess of Pure Reason, as told by Norton Juster in The Phantom
> Tollbooth
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [Qemu-devel] [PATCH] tracetool.py: always pass --binary, --target-arch, --target-type
2012-03-28 9:35 ` Alon Levy
@ 2012-03-28 10:29 ` Lluís Vilanova
0 siblings, 0 replies; 18+ messages in thread
From: Lluís Vilanova @ 2012-03-28 10:29 UTC (permalink / raw)
To: Alon Levy; +Cc: stefanha, qemu-devel
Alon Levy writes:
[...]
>> I don't see the reason for such a change, as in the current bash code it's not
>> used except when generating files in the 'stap' format.
> Have you tried building with trace backend dtrace? without those changed
> it breaks because tracetool.py requires both target_arch and target_type
> for dtrace backend. Either change the source or change the invocation. I
> thought the later is better, hence this patch.
If you're referring to your changes in tracetool.py related to this (when
checking binary/prefix/etc), it should be fixed in v3 without resorting to your
changes:
- if format == "stap":
+ if arg_format == "stap":
Instead of your proposal:
- if format == "stap":
+ if arg_backend == "dtrace":
I didn't try to compile the resulting dtrace files (they should be the same),
but tracetool does not fail with the aforementioned changes.
Thanks,
Lluis
--
"And it's much the same thing with knowledge, for whenever you learn
something new, the whole world becomes that much richer."
-- The Princess of Pure Reason, as told by Norton Juster in The Phantom
Tollbooth
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2012-03-28 10:29 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-03-26 17:37 [Qemu-devel] [RFC PATCH v2 0/8] Rewrite tracetool using python modules Lluís Vilanova
2012-03-26 17:37 ` [Qemu-devel] [RFC PATCH v2 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
2012-03-27 15:17 ` Alon Levy
2012-03-27 17:47 ` Lluís Vilanova
2012-03-27 15:21 ` Alon Levy
2012-03-27 16:37 ` [Qemu-devel] [PATCH] tracetool.py: always pass --binary, --target-arch, --target-type Alon Levy
2012-03-27 18:01 ` Lluís Vilanova
2012-03-28 9:35 ` Alon Levy
2012-03-28 10:29 ` Lluís Vilanova
2012-03-26 17:37 ` [Qemu-devel] [RFC PATCH v2 2/8] tracetool: Add module for the 'c' format Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 3/8] tracetool: Add module for the 'h' format Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 4/8] tracetool: Add support for the 'stderr' backend Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 5/8] tracetool: Add support for the 'simple' backend Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 6/8] tracetool: Add support for the 'ust' backend Lluís Vilanova
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 7/8] tracetool: Add support for the 'dtrace' backend Lluís Vilanova
2012-03-27 15:19 ` Alon Levy
2012-03-27 16:20 ` Alon Levy
2012-03-26 17:38 ` [Qemu-devel] [RFC PATCH v2 8/8] tracetool: Add MAINTAINERS info Lluís Vilanova
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).