From 56a31b90342a6cfc86a00e587a73437a090e993d Mon Sep 17 00:00:00 2001
From: Stefan Hajnoczi <stefanha@redhat.com>
Date: Fri, 11 Jul 2014 17:18:24 +0200
Subject: [PATCH 36/44] tracetool: add tracetool simpletrace_stap format

RH-Author: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: <1405099110-10975-2-git-send-email-stefanha@redhat.com>
Patchwork-id: 59859
O-Subject: [RHEL6.6 qemu-kvm PATCH 1/7] tracetool: add tracetool simpletrace_stap format
Bugzilla: 905761
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>

This patch adds the tracetool --simpletrace-stap option for generating a .stp
file that outputs simpletrace binary trace data.

This is a reimplementation of the following upstream commit:

  This new tracetool "format" generates a SystemTap .stp file that outputs
  simpletrace binary trace data.

  In contrast to simpletrace or ftrace, SystemTap does not define its own
  trace format.  All output from SystemTap is generated by .stp files.
  This patch lets us generate a .stp file that outputs in the simpletrace
  binary format.

  This makes it possible to reuse simpletrace.py to analyze traces
  recorded using SystemTap.  The simpletrace binary format is especially
  useful for long-running traces like flight-recorder mode where string
  formatting can be expensive.

  Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>

RHEL 6.x qemu-kvm uses the shell version of tracetool (upstream tracetool has
been Python since QEMU 1.1).  Backporting the upstream code would create a huge
amount of churn.  Since RHEL only needs the dtrace backend, most of the
backport would be useless but hard to separate out and review.  It's much
easier to reimplement the upstream functionality for downstream tracetool.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 tracetool | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 108 insertions(+), 1 deletion(-)

Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
---
 tracetool |  109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 108 insertions(+), 1 deletions(-)

diff --git a/tracetool b/tracetool
index f489f43..d00b2a3 100644
--- a/tracetool
+++ b/tracetool
@@ -13,7 +13,7 @@ set -f
 usage()
 {
     cat >&2 <<EOF
-usage: $0 --nop [-h | -c]
+usage: $0 [--nop | --dtrace] [-h | -c | --stap | --simpletrace-stap]
 Generate tracing code for a file on stdin.
 
 Backends:
@@ -25,6 +25,7 @@ Output formats:
   -c     Generate .c file
   -d     Generate .d file (DTrace only)
   --stap Generate .stp file (DTrace with SystemTAP only)
+  --simpletrace-stap Generate simpletrace bridge .stp (DTrace with SystemTAP only)
 
 Options:
   --binary       [path]    Full path to QEMU binary
@@ -273,6 +274,90 @@ linetostap_end_dtrace()
     return
 }
 
+linetosimpletrace_stap_begin_dtrace()
+{
+    simpletrace_stap_event_id=0
+}
+
+linetosimpletrace_stap_dtrace()
+{
+    local name args arglist state sizestr fmtstr fmtargs argdecl
+    name=$(get_name "$1")
+    args=$(get_args "$1")
+    arglist=$(get_argnames "$1", "")
+    state=$(get_state "$1")
+    if [ "$state" = "0" ] ; then
+        name=${name##disable }
+    fi
+
+    if [ "$args" = "void" ]; then
+       args=""
+    fi
+
+    # Define prototype for probe arguments
+    cat <<EOF
+probe $probeprefix.simpletrace.$name = $probeprefix.$name ?
+{
+EOF
+
+    sizestr=""
+    fmtstr=""
+    fmtargs=""
+
+    IFS=,
+    for argdecl in $args
+    do
+        unset IFS
+
+        # Pop argument name off list
+        arg=${arglist%% *}
+        arglist=${arglist#* }
+
+        # 'limit' is a reserved keyword
+        if [ "$arg" = "limit" ]; then
+          arg="_limit"
+        fi
+
+        # Strings are variable-length and require size calculation
+        if echo "$argdecl" | grep 'char \*' >/dev/null
+        then
+            cat <<EOF
+    try {
+        arg${arg}_str = $arg ? user_string_n($arg, 512) : "<null>"
+    } catch {}
+    arg${arg}_len = strlen(arg${arg}_str)
+EOF
+            sizestr="$sizestr + 4 + arg${arg}_len"
+            fmtstr="$fmtstr%4b%.*s"
+            fmtargs="$fmtargs, arg${arg}_len, arg${arg}_len, arg${arg}_str"
+        else
+            sizestr="$sizestr + 8"
+            fmtstr="$fmtstr%8b"
+            fmtargs="$fmtargs, ${arg}"
+        fi
+
+        IFS=,
+    done
+    unset IFS
+
+    # Prepend header fields
+    sizestr="24$sizestr"
+    fmtstr="%8b%8b%4b%4b$fmtstr"
+    fmtargs="$simpletrace_stap_event_id, gettimeofday_ns(), $sizestr, pid()$fmtargs"
+
+    cat <<EOF
+    printf("$fmtstr", $fmtargs);
+}
+EOF
+
+    simpletrace_stap_event_id=$((simpletrace_stap_event_id + 1))
+}
+
+linetosimpletrace_stap_end_dtrace()
+{
+    return
+}
+
 # Process stdin by calling begin, line, and end functions for the backend
 convert()
 {
@@ -363,6 +448,27 @@ tracetostap()
     convert stap
 }
 
+tracetosimpletrace_stap()
+{
+    if [ $backend != "dtrace" ]; then
+       echo "SystemTAP simpletrace tapset generator not applicable to $backend backend"
+       exit 1
+    fi
+    if [ -z "$probeprefix" -a -z "$targettype" ]; then
+       echo "--target-type is required for SystemTAP simpletrace tapset generator"
+       exit 1
+    fi
+    if [ -z "$probeprefix" -a -z "$targetarch" ]; then
+       echo "--target-arch is required for SystemTAP simpletrace 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 simpletrace_stap
+}
+
 
 backend=
 output=
@@ -384,6 +490,7 @@ do
 
     "-h" | "-c" | "-d") output="${1#-}" ;;
     "--stap") output="${1#--}" ;;
+    "--simpletrace-stap") output="simpletrace_stap" ;;
 
     "--check-backend") exit 0 ;; # used by ./configure to test for backend
 
-- 
1.7.1

