All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC PATCH v4 0/8] Rewrite tracetool using python modules
@ 2012-03-30 17:57 Lluís Vilanova
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Lluís Vilanova @ 2012-03-30 17:57 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 v4:

* Some code cleanups according to comments from Stefan Hajnoczi:
** Removed the "public backend" concept (will be introduced only when necessary).
** Moved 'tracetool.generate' from "kwargs" to explicitly named arguments.

Changes in v3:

* Some minor fixes according to comments from Alon Levy:
** Fixed some rogue tabs.
** Fixed definition of '_SCRIPT' in "tracetool.py".
** Fixed some documentation.
** Defensively treat results from 'try_import' in 'get_list'.
** Fixed the no-arguments case in 'tracetool.backend.dtrace.d'.
** Fixed the commandline checks for the "stap" format.
** Added '__repr__' methods for both Event and Arguments objects.


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                  |  138 +++++++
 scripts/tracetool/__init__.py         |  231 ++++++++++++
 scripts/tracetool/backend/__init__.py |  105 +++++
 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  |   96 +++++
 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, 1016 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] 9+ messages in thread

* [Qemu-devel] [RFC PATCH v4 1/8] tracetool: Rewrite infrastructure as python modules
  2012-03-30 17:57 [Qemu-devel] [RFC PATCH v4 0/8] Rewrite tracetool using python modules Lluís Vilanova
@ 2012-03-30 17:57 ` Lluís Vilanova
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 2/8] tracetool: Add module for the 'c' format Lluís Vilanova
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2012-03-30 17:57 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                  |  108 ++++++
 scripts/tracetool/__init__.py         |  222 +++++++++++
 scripts/tracetool/backend/__init__.py |  105 +++++
 scripts/tracetool/format/__init__.py  |   96 +++++
 8 files changed, 543 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..fe2ea34
--- /dev/null
+++ b/scripts/tracetool.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Command-line wrapper for the tracetool machinery.
+"""
+
+__author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__    = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__      = "stefanha@linux.vnet.ibm.com"
+
+
+import sys
+import getopt
+
+from tracetool import error_write, out
+import tracetool.backend
+import tracetool.format
+
+
+_SCRIPT = ""
+
+def error_opt(msg = None):
+    if msg is not None:
+        error_write("Error: " + msg + "\n")
+
+    backend_descr = "\n".join([ "    %-15s %s" % (n, d)
+                                for n,d in tracetool.backend.get_list() ])
+    format_descr = "\n".join([ "    %-15s %s" % (n, d)
+                               for n,d in tracetool.format.get_list() ])
+    error_write("""\
+Usage: %(script)s --format=<format> --backend=<backend> [<options>]
+
+Backends:
+%(backends)s
+
+Formats:
+%(formats)s
+
+Options:
+    --help                   This help message.
+    --list-backends          Print list of available backends.
+    --check-backend          Check if the given backend is valid.
+""" % {
+            "script" : _SCRIPT,
+            "backends" : backend_descr,
+            "formats" : format_descr,
+            })
+
+    if msg is None:
+        sys.exit(0)
+    else:
+        sys.exit(1)
+
+
+def main(args):
+    global _SCRIPT
+    _SCRIPT = args[0]
+
+    long_opts  = [ "backend=", "format=", "help", "list-backends", "check-backend" ]
+    long_opts += [ "binary=", "target-type=", "target-arch=", "probe-prefix=" ]
+
+    try:
+        opts, args = getopt.getopt(args[1:], "", long_opts)
+    except getopt.GetoptError as err:
+        error_opt(str(err))
+
+    check_backend = False
+    arg_backend = ""
+    arg_format = ""
+    for opt, arg in opts:
+        if opt == "--help":
+            error_opt()
+
+        elif opt == "--backend":
+            arg_backend = arg
+        elif opt == "--format":
+            arg_format = arg
+
+        elif opt == "--list-backends":
+            backends = tracetool.backend.get_list()
+            out(", ".join([ b for b,_ in backends ]))
+            sys.exit(0)
+        elif opt == "--check-backend":
+            check_backend = True
+
+        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)
+
+    try:
+        tracetool.generate(sys.stdin, arg_format, arg_backend)
+    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..200cb6f
--- /dev/null
+++ b/scripts/tracetool/__init__.py
@@ -0,0 +1,222 @@
+#!/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 __repr__(self):
+        """Evaluable string representation for this object."""
+        return "Arguments(\"%s\")" % str(self)
+
+    def names(self):
+        """List of argument names."""
+        return [ name for _, name in self._args ]
+
+    def types(self):
+        """List of argument types."""
+        return [ type_ for type_, _ in self._args ]
+
+
+class Event(object):
+    """Event description.
+
+    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 __repr__(self):
+        """Evaluable string representation for this object."""
+        return "Event('%s %s(%s) %s')" % (" ".join(self.properties),
+                                          self.name,
+                                          self.args,
+                                          self.fmt)
+
+def _read_events(fobj):
+    res = []
+    for line in fobj:
+        if not line.strip():
+            continue
+        if line.lstrip().startswith('#'):
+            continue
+        res.append(Event(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):
+    """Generate the output for the given (format, backend) pair.
+
+    Parameters
+    ----------
+    fevents : file
+        Event description file.
+    format : str
+        Output format name.
+    backend : str
+        Output backend name.
+    """
+    # fix strange python error (UnboundLocalError tracetool)
+    import tracetool
+
+    format = str(format)
+    if len(format) is 0:
+        raise TracetoolError("format not set")
+    mformat = format.replace("-", "_")
+    if not tracetool.format.exists(mformat):
+        raise TracetoolError("unknown format: %s" % format)
+
+    backend = str(backend)
+    if len(backend) is 0:
+        raise TracetoolError("backend not set")
+    mbackend = backend.replace("-", "_")
+    if not tracetool.backend.exists(mbackend):
+        raise TracetoolError("unknown backend: %s" % backend)
+
+    if not tracetool.backend.compatible(mbackend, mformat):
+        raise TracetoolError("backend '%s' not compatible with format '%s'" %
+                             (backend, format))
+
+    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..891994f
--- /dev/null
+++ b/scripts/tracetool/backend/__init__.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Backend management.
+
+
+Creating new backends
+---------------------
+
+A new backend named 'foo-bar' corresponds to Python module
+'tracetool/backend/foo_bar.py'.
+
+A backend module should provide a docstring, whose first non-empty line will be
+considered its short description.
+
+All backends must generate their contents through the 'tracetool.out' routine.
+
+
+Backend functions
+-----------------
+
+======== =======================================================================
+Function Description
+======== =======================================================================
+<format> Called to generate the format- and backend-specific code for each of
+         the specified events. If the function does not exist, the backend is
+         considered not compatible with the given format.
+======== =======================================================================
+"""
+
+__author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__    = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__      = "stefanha@linux.vnet.ibm.com"
+
+
+import pkgutil
+
+import tracetool
+
+
+def get_list():
+    """Get a list of (name, description) pairs."""
+    res = [("nop", "Tracing disabled.")]
+    for _, modname, _ in pkgutil.iter_modules(tracetool.backend.__path__):
+        module = tracetool.try_import("tracetool.backend." + modname)
+
+        # just in case; should never fail unless non-module files are put there
+        if not module[0]:
+            continue
+        module = module[1]
+
+        doc = module.__doc__
+        if doc is None:
+            doc = ""
+        doc = doc.strip().split("\n")[0]
+
+        name = modname.replace("_", "-")
+        res.append((name, doc))
+    return res
+
+
+def exists(name):
+    """Return whether the given backend exists."""
+    if len(name) == 0:
+        return False
+    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..174777f
--- /dev/null
+++ b/scripts/tracetool/format/__init__.py
@@ -0,0 +1,96 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Format management.
+
+
+Creating new formats
+--------------------
+
+A new format named 'foo-bar' corresponds to Python module
+'tracetool/format/foo_bar.py'.
+
+A format module should provide a docstring, whose first non-empty line will be
+considered its short description.
+
+All formats must generate their contents through the 'tracetool.out' routine.
+
+
+Format functions
+----------------
+
+All the following functions are optional, and no output will be generated if
+they do not exist.
+
+======== =======================================================================
+Function Description
+======== =======================================================================
+begin    Called to generate the format-specific file header.
+end      Called to generate the format-specific file footer.
+nop      Called to generate the per-event contents when the event is disabled or
+         the selected backend is 'nop'.
+======== =======================================================================
+"""
+
+__author__     = "Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__  = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__license__    = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__      = "stefanha@linux.vnet.ibm.com"
+
+
+import pkgutil
+
+import tracetool
+
+
+def get_list():
+    """Get a list of (name, description) pairs."""
+    res = []
+    for _, modname, _ in pkgutil.iter_modules(tracetool.format.__path__):
+        module = tracetool.try_import("tracetool.format." + modname)
+
+        # just in case; should never fail unless non-module files are put there
+        if not module[0]:
+            continue
+        module = module[1]
+
+        doc = module.__doc__
+        if doc is None:
+            doc = ""
+        doc = doc.strip().split("\n")[0]
+
+        name = modname.replace("_", "-")
+        res.append((name, doc))
+    return res
+
+
+def exists(name):
+    """Return whether the given format exists."""
+    if len(name) == 0:
+        return False
+    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] 9+ messages in thread

* [Qemu-devel] [RFC PATCH v4 2/8] tracetool: Add module for the 'c' format
  2012-03-30 17:57 [Qemu-devel] [RFC PATCH v4 0/8] Rewrite tracetool using python modules Lluís Vilanova
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
@ 2012-03-30 17:57 ` Lluís Vilanova
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 3/8] tracetool: Add module for the 'h' format Lluís Vilanova
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2012-03-30 17:57 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] 9+ messages in thread

* [Qemu-devel] [RFC PATCH v4 3/8] tracetool: Add module for the 'h' format
  2012-03-30 17:57 [Qemu-devel] [RFC PATCH v4 0/8] Rewrite tracetool using python modules Lluís Vilanova
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 2/8] tracetool: Add module for the 'c' format Lluís Vilanova
@ 2012-03-30 17:57 ` Lluís Vilanova
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 4/8] tracetool: Add support for the 'stderr' backend Lluís Vilanova
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2012-03-30 17:57 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] 9+ messages in thread

* [Qemu-devel] [RFC PATCH v4 4/8] tracetool: Add support for the 'stderr' backend
  2012-03-30 17:57 [Qemu-devel] [RFC PATCH v4 0/8] Rewrite tracetool using python modules Lluís Vilanova
                   ` (2 preceding siblings ...)
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 3/8] tracetool: Add module for the 'h' format Lluís Vilanova
@ 2012-03-30 17:57 ` Lluís Vilanova
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 5/8] tracetool: Add support for the 'simple' backend Lluís Vilanova
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2012-03-30 17:57 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] 9+ messages in thread

* [Qemu-devel] [RFC PATCH v4 5/8] tracetool: Add support for the 'simple' backend
  2012-03-30 17:57 [Qemu-devel] [RFC PATCH v4 0/8] Rewrite tracetool using python modules Lluís Vilanova
                   ` (3 preceding siblings ...)
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 4/8] tracetool: Add support for the 'stderr' backend Lluís Vilanova
@ 2012-03-30 17:57 ` Lluís Vilanova
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 6/8] tracetool: Add support for the 'ust' backend Lluís Vilanova
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2012-03-30 17:57 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] 9+ messages in thread

* [Qemu-devel] [RFC PATCH v4 6/8] tracetool: Add support for the 'ust' backend
  2012-03-30 17:57 [Qemu-devel] [RFC PATCH v4 0/8] Rewrite tracetool using python modules Lluís Vilanova
                   ` (4 preceding siblings ...)
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 5/8] tracetool: Add support for the 'simple' backend Lluís Vilanova
@ 2012-03-30 17:57 ` Lluís Vilanova
  2012-03-30 17:58 ` [Qemu-devel] [RFC PATCH v4 7/8] tracetool: Add support for the 'dtrace' backend Lluís Vilanova
  2012-03-30 17:58 ` [Qemu-devel] [RFC PATCH v4 8/8] tracetool: Add MAINTAINERS info Lluís Vilanova
  7 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2012-03-30 17:57 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] 9+ messages in thread

* [Qemu-devel] [RFC PATCH v4 7/8] tracetool: Add support for the 'dtrace' backend
  2012-03-30 17:57 [Qemu-devel] [RFC PATCH v4 0/8] Rewrite tracetool using python modules Lluís Vilanova
                   ` (5 preceding siblings ...)
  2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 6/8] tracetool: Add support for the 'ust' backend Lluís Vilanova
@ 2012-03-30 17:58 ` Lluís Vilanova
  2012-03-30 17:58 ` [Qemu-devel] [RFC PATCH v4 8/8] tracetool: Add MAINTAINERS info Lluís Vilanova
  7 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2012-03-30 17:58 UTC (permalink / raw)
  To: qemu-devel; +Cc: stefanha

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
---
 scripts/tracetool.py                |   32 ++++++++++-
 scripts/tracetool/__init__.py       |   11 +++-
 scripts/tracetool/backend/dtrace.py |  104 +++++++++++++++++++++++++++++++++++
 scripts/tracetool/format/d.py       |   20 +++++++
 scripts/tracetool/format/stap.py    |   20 +++++++
 5 files changed, 185 insertions(+), 2 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 fe2ea34..cacfd99 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)
 
@@ -99,8 +117,20 @@ def main(args):
         else:
             sys.exit(1)
 
+    if arg_format == "stap":
+        if binary is None:
+            error_opt("--binary is required for SystemTAP tapset generator")
+        if probe_prefix is None and target_type is None:
+            error_opt("--target-type is required for SystemTAP tapset generator")
+        if probe_prefix is None and target_arch is None:
+            error_opt("--target-arch is required for SystemTAP tapset generator")
+
+        if probe_prefix is None:
+            probe_prefix = ".".join([ "qemu", target_type, target_arch ])
+
     try:
-        tracetool.generate(sys.stdin, arg_format, arg_backend)
+        tracetool.generate(sys.stdin, arg_format, arg_backend,
+                           binary = binary, probe_prefix = probe_prefix)
     except tracetool.TracetoolError as e:
         error_opt(str(e))
 
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 200cb6f..5471b1a 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -172,7 +172,8 @@ def try_import(mod_name, attr_name = None, attr_default = None):
         return False, None
 
 
-def generate(fevents, format, backend):
+def generate(fevents, format, backend,
+             binary = None, probe_prefix = None):
     """Generate the output for the given (format, backend) pair.
 
     Parameters
@@ -183,6 +184,10 @@ def generate(fevents, format, backend):
         Output format name.
     backend : str
         Output backend name.
+    binary : str or None
+        See tracetool.backend.dtrace.BINARY.
+    probe_prefix : str or None
+        See tracetool.backend.dtrace.PROBEPREFIX.
     """
     # fix strange python error (UnboundLocalError tracetool)
     import tracetool
@@ -205,6 +210,10 @@ def generate(fevents, format, backend):
         raise TracetoolError("backend '%s' not compatible with format '%s'" %
                              (backend, format))
 
+    import tracetool.backend.dtrace
+    tracetool.backend.dtrace.BINARY = binary
+    tracetool.backend.dtrace.PROBEPREFIX = probe_prefix
+
     events = _read_events(fevents)
 
     if backend == "nop":
diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
new file mode 100644
index 0000000..817d656
--- /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 = str(e.args)
+
+        # DTrace provider syntax expects foo() for empty
+        # params, not foo(void)
+        if args == 'void':
+            args = ''
+
+        # Define prototype for probe arguments
+        out('',
+            'probe %(name)s(%(args)s);' %
+            {
+                'name': e.name,
+                'args': args
+                })
+
+    out('',
+        '};')
+
+
+def stap(events):
+    for e in events:
+        # Define prototype for probe arguments
+        out('probe %(probeprefix)s.%(name)s = process("%(binary)s").mark("%(name)s")' %
+            {
+                'probeprefix': _probeprefix(),
+                'name': e.name,
+                'binary': _binary(),
+                },
+            '{')
+
+        i = 1
+        if len(e.args) > 0:
+            for name in e.args.names():
+                # '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] 9+ messages in thread

* [Qemu-devel] [RFC PATCH v4 8/8] tracetool: Add MAINTAINERS info
  2012-03-30 17:57 [Qemu-devel] [RFC PATCH v4 0/8] Rewrite tracetool using python modules Lluís Vilanova
                   ` (6 preceding siblings ...)
  2012-03-30 17:58 ` [Qemu-devel] [RFC PATCH v4 7/8] tracetool: Add support for the 'dtrace' backend Lluís Vilanova
@ 2012-03-30 17:58 ` Lluís Vilanova
  7 siblings, 0 replies; 9+ messages in thread
From: Lluís Vilanova @ 2012-03-30 17:58 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] 9+ messages in thread

end of thread, other threads:[~2012-03-30 17:58 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-30 17:57 [Qemu-devel] [RFC PATCH v4 0/8] Rewrite tracetool using python modules Lluís Vilanova
2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 1/8] tracetool: Rewrite infrastructure as " Lluís Vilanova
2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 2/8] tracetool: Add module for the 'c' format Lluís Vilanova
2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 3/8] tracetool: Add module for the 'h' format Lluís Vilanova
2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 4/8] tracetool: Add support for the 'stderr' backend Lluís Vilanova
2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 5/8] tracetool: Add support for the 'simple' backend Lluís Vilanova
2012-03-30 17:57 ` [Qemu-devel] [RFC PATCH v4 6/8] tracetool: Add support for the 'ust' backend Lluís Vilanova
2012-03-30 17:58 ` [Qemu-devel] [RFC PATCH v4 7/8] tracetool: Add support for the 'dtrace' backend Lluís Vilanova
2012-03-30 17:58 ` [Qemu-devel] [RFC PATCH v4 8/8] tracetool: Add MAINTAINERS info Lluís Vilanova

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.