From: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: aneesh.kumar@linux.vnet.ibm.com, mathieu.desnoyers@efficios.com,
vilanova@ac.upc.edu, stefanha@linux.vnet.ibm.com
Subject: [Qemu-devel] [RFC PATCH v2 1/4] Converting tracetool.sh to tracetool.py
Date: Mon, 9 Jan 2012 21:16:17 +0530 [thread overview]
Message-ID: <1326123980-6038-2-git-send-email-harsh@linux.vnet.ibm.com> (raw)
In-Reply-To: <1326123980-6038-1-git-send-email-harsh@linux.vnet.ibm.com>
Note: Upstream Qemu have build issues with LTTng ust backend, as the trace
event APIs are not yet stable in ust and therefore ust backend is not
supported in this script as of now. Once the ust API stablises, this script
can be updated for ust backend also.
Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
---
scripts/tracetool | 643 --------------------------------------------------
scripts/tracetool.py | 505 +++++++++++++++++++++++++++++++++++++++
2 files changed, 505 insertions(+), 643 deletions(-)
delete mode 100755 scripts/tracetool
create mode 100755 scripts/tracetool.py
diff --git a/scripts/tracetool b/scripts/tracetool
deleted file mode 100755
index 4c9951d..0000000
--- a/scripts/tracetool
+++ /dev/null
@@ -1,643 +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) {
- if (QEMU_${nameupper}_ENABLED()) {
- QEMU_${nameupper}($argnames);
- }
-}
-EOF
-}
-
-linetoh_end_dtrace()
-{
- return
-}
-
-linetoc_begin_dtrace()
-{
- return
-}
-
-linetoc_dtrace()
-{
- # No need for function definitions in dtrace backend
- return
-}
-
-linetoc_end_dtrace()
-{
- return
-}
-
-linetod_begin_dtrace()
-{
- cat <<EOF
-provider qemu {
-EOF
-}
-
-linetod_dtrace()
-{
- local name args
- 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 disable
- 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"
- else
- "$process_line" "$str"
- 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..408d6ed
--- /dev/null
+++ b/scripts/tracetool.py
@@ -0,0 +1,505 @@
+#!/usr/bin/env python
+# Python based tracetool script (Code generator for trace events)
+#
+# Copyright IBM, Corp. 2011
+#
+# This work is licensed under the terms of the GNU GPL, version 2. See
+# the COPYING file in the top-level directory.
+#
+#
+
+import sys
+import getopt
+
+def usage():
+ print "Tracetool: Generate tracing code for trace events file on stdin"
+ print "Usage:"
+ print sys.argv[0], " --backend=[nop|simple|stderr|dtrace] [-h|-c|-d|--stap]"
+ print '''
+Backends:
+ --nop Tracing disabled
+ --simple Simple built-in backend
+ --stderr Stderr built-in 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)
+'''
+ sys.exit(1)
+
+def get_name(line, sep='('):
+ head, sep, tail = line.partition(sep)
+ return head
+
+def get_args(line, sep1='(', sep2=')'):
+ head, sep1, tail = line.partition(sep1)
+ args, sep2, fmt_str = tail.partition(sep2)
+ return args
+
+def get_argnames(line, sep=','):
+ nfields = 0
+ str = []
+ args = get_args(line)
+ for field in args.split():
+ nfields = nfields + 1
+ # Drop pointer star
+ type, ptr, tail = field.partition('*')
+ if type != field:
+ field = tail
+
+ name, sep, tail = field.partition(',')
+
+ if name == field:
+ continue
+ str.append(name)
+ str.append(", ")
+
+ if nfields > 1:
+ str.append(name)
+ return ''.join(str)
+ else:
+ return ''
+
+def get_argc(line):
+ argc = 0
+ argnames = get_argnames(line)
+ if argnames:
+ for name in argnames.split(','):
+ argc = argc + 1
+ return argc
+
+def get_fmt(line, sep=')'):
+ event, sep, fmt = line.partition(sep)
+ return fmt
+
+def calc_sizeofargs(line):
+ args = get_args(line)
+ argc = get_argc(line)
+ strtype = ('const char*', 'char*', 'const char *', 'char *')
+ str = []
+ newstr = ""
+ if argc > 0:
+ str = args.split(',')
+ for elem in str:
+ if elem.lstrip().startswith(strtype): #strings
+ type, sep, var = elem.rpartition('*')
+ newstr = newstr+"4 + strlen("+var.lstrip()+") + "
+ #elif '*' in elem:
+ # newstr = newstr + "4 + " # pointer vars
+ else:
+ #type, sep, var = elem.rpartition(' ')
+ #newstr = newstr+"sizeof("+type.lstrip()+") + "
+ newstr = newstr + '8 + '
+ newstr = newstr + '0' # for last +
+ return newstr
+
+
+def trace_h_begin():
+ print '''#ifndef TRACE_H
+#define TRACE_H
+
+/* This file is autogenerated by tracetool, do not edit. */
+
+#include "qemu-common.h"'''
+ return
+
+def trace_h_end():
+ print '#endif /* TRACE_H */'
+ return
+
+def trace_c_begin():
+ print '/* This file is autogenerated by tracetool, do not edit. */'
+ return
+
+def trace_c_end():
+ # nop, required for trace_gen
+ return
+
+def nop_h(events):
+ print
+ for event in events:
+ print '''static inline void trace_%(name)s(%(args)s)
+{
+}
+''' % {
+ 'name': event.name,
+ 'args': event.args
+}
+ return
+
+def nop_c(events):
+ # nop, reqd for converters
+ return
+
+
+def simple_h(events):
+ print '#include "trace/simple.h"'
+ print
+ for event in events:
+ print 'void trace_%(name)s(%(args)s);' % {
+ 'name': event.name,
+ 'args': event.args
+}
+ print
+ print '#define NR_TRACE_EVENTS %d' % (event.num + 1)
+ print 'extern TraceEvent trace_list[NR_TRACE_EVENTS];'
+
+ return
+
+def is_string(arg):
+ strtype = ('const char*', 'char*', 'const char *', 'char *')
+ if arg.lstrip().startswith(strtype):
+ return True
+ else:
+ return False
+
+def simple_c(events):
+ rec_off = 0
+ print '#include "trace.h"'
+ print '#include "trace/simple.h"'
+ print
+ print 'TraceEvent trace_list[] = {'
+ print
+ eventlist = list(events)
+ for event in eventlist:
+ print '{.tp_name = "%(name)s", .state=0},' % {
+ 'name': event.name
+}
+ print
+ print '};'
+ print
+ for event in eventlist:
+ argc = event.argc
+ print '''void trace_%(name)s(%(args)s)
+{
+ unsigned int tbuf_idx, rec_off;
+ uint64_t var64 __attribute__ ((unused));
+ uint64_t pvar64 __attribute__ ((unused));
+ uint32_t slen __attribute__ ((unused));
+
+ if (!trace_list[%(event_id)s].state) {
+ return;
+ }
+''' % {
+ 'name': event.name,
+ 'args': event.args,
+ 'event_id': event.num,
+}
+ print '''
+ tbuf_idx = trace_alloc_record(%(event_id)s, %(sizestr)s);
+ rec_off = (tbuf_idx + ST_V2_REC_HDR_LEN) %% TRACE_BUF_LEN; /* seek record header */
+''' % {'event_id': event.num, 'sizestr': event.sizestr,}
+
+ if argc > 0:
+ str = event.arglist
+ for elem in str:
+ if is_string(elem): # if string
+ type, sep, var = elem.rpartition('*')
+ print '''
+ slen = strlen(%(var)s);
+ write_to_buffer(rec_off, (uint8_t*)&slen, sizeof(slen));
+ rec_off += sizeof(slen);''' % {
+ 'var': var.lstrip()
+}
+ print '''
+ write_to_buffer(rec_off, (uint8_t*)%(var)s, slen);
+ rec_off += slen;''' % {
+ 'var': var.lstrip()
+}
+ elif '*' in elem: # pointer var (not string)
+ type, sep, var = elem.rpartition('*')
+ print '''
+ pvar64 = (uint64_t)(uint64_t*)%(var)s;
+ write_to_buffer(rec_off, (uint8_t*)&pvar64, sizeof(uint64_t));
+ rec_off += sizeof(uint64_t);''' % {
+ 'var': var.lstrip()
+}
+ else: # primitive data type
+ type, sep, var = elem.rpartition(' ')
+ print '''
+ var64 = (uint64_t)%(var)s;
+ write_to_buffer(rec_off, (uint8_t*)&var64, sizeof(uint64_t));
+ rec_off += sizeof(uint64_t);''' % {
+ 'var': var.lstrip()
+}
+ print '''
+ trace_mark_record_complete(tbuf_idx);'''
+ print '}'
+ print
+
+ return
+
+def stderr_h(events):
+ print '''#include <stdio.h>
+#include "trace/stderr.h"
+
+extern TraceEvent trace_list[];'''
+ for event in events:
+ argnames = event.argnames
+ if event.argc > 0:
+ argnames = ', ' + event.argnames
+ else:
+ argnames = ''
+ print '''
+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': event.name,
+ 'args': event.args,
+ 'event_num': event.num,
+ 'fmt': event.fmt.rstrip('\n'),
+ 'argnames': argnames
+}
+ print
+ print '#define NR_TRACE_EVENTS %d' % (event.num + 1)
+
+def stderr_c(events):
+ print '''#include "trace.h"
+
+TraceEvent trace_list[] = {
+'''
+ for event in events:
+ print '{.tp_name = "%(name)s", .state=0},' % {
+ 'name': event.name
+}
+ print
+ print '};'
+
+def dtrace_h(events):
+ print '#include "trace-dtrace.h"'
+ print
+ for event in events:
+ print '''static inline void trace_%(name)s(%(args)s) {
+ if (QEMU_%(uppername)s_ENABLED()) {
+ QEMU_%(uppername)s(%(argnames)s);
+ }
+}
+''' % {
+ 'name': event.name,
+ 'args': event.args,
+ 'uppername': event.name.upper(),
+ 'argnames': event.argnames,
+}
+
+def dtrace_c(events):
+ return # No need for function definitions in dtrace backend
+
+def dtrace_d(events):
+ print 'provider qemu {'
+ for event in events:
+ args = event.args
+
+ # DTrace provider syntax expects foo() for empty
+ # params, not foo(void)
+ if args == 'void':
+ args = ''
+
+ # Define prototype for probe arguments
+ print '''
+ probe %(name)s(%(args)s);''' % {
+ 'name': event.name,
+ 'args': args
+}
+ print
+ print '};'
+ return
+
+def dtrace_stp(events):
+ for event in events:
+ # Define prototype for probe arguments
+ print '''
+probe %(probeprefix)s.%(name)s = process("%(binary)s").mark("%(name)s")
+{''' % {
+ 'probeprefix': probeprefix,
+ 'name': event.name,
+ 'binary': binary
+}
+ i = 1
+ if event.argc > 0:
+ for arg in event.argnames.split(','):
+ # 'limit' is a reserved keyword
+ if arg == 'limit':
+ arg = '_limit'
+ print ' %s = $arg%d;' % (arg.lstrip(), i)
+ i += 1
+ print '}'
+ print
+ return
+
+def trace_stap_begin():
+ global probeprefix
+ if backend != "dtrace":
+ print 'SystemTAP tapset generator not applicable to %s backend' % backend
+ sys.exit(1)
+ if binary == "":
+ print '--binary is required for SystemTAP tapset generator'
+ sys.exit(1)
+ if ((probeprefix == "") and (targettype == "")):
+ print '--target-type is required for SystemTAP tapset generator'
+ sys.exit(1)
+ if ((probeprefix == "") and (targetarch == "")):
+ print '--target-arch is required for SystemTAP tapset generator'
+ sys.exit(1)
+ if probeprefix == "":
+ probeprefix = 'qemu.' + targettype + '.' + targetarch
+ print '/* This file is autogenerated by tracetool, do not edit. */'
+ return
+
+def trace_stap_end():
+ return #nop, reqd for trace_gen
+
+def trace_d_begin():
+ if backend != 'dtrace':
+ print 'DTrace probe generator not applicable to %s backend' % backend
+ sys.exit(1)
+ print '/* This file is autogenerated by tracetool, do not edit. */'
+
+def trace_d_end():
+ return #nop, reqd for trace_gen
+
+
+# Registry of backends and their converter functions
+converters = {
+ 'simple': {
+ 'h': simple_h,
+ 'c': simple_c,
+ },
+
+ 'nop': {
+ 'h': nop_h,
+ 'c': nop_c,
+ },
+
+ 'stderr': {
+ 'h': stderr_h,
+ 'c': stderr_c,
+ },
+
+ 'dtrace': {
+ 'h': dtrace_h,
+ 'c': dtrace_c,
+ 'd': dtrace_d,
+ 'stap': dtrace_stp
+ },
+}
+
+# Trace file header and footer code generators
+trace_gen = {
+ 'h': {
+ 'begin': trace_h_begin,
+ 'end': trace_h_end,
+ },
+ 'c': {
+ 'begin': trace_c_begin,
+ 'end': trace_c_end,
+ },
+ 'd': {
+ 'begin': trace_d_begin,
+ 'end': trace_d_end,
+ },
+ 'stap': {
+ 'begin': trace_stap_begin,
+ 'end': trace_stap_end,
+ },
+}
+
+# A trace event
+class Event(object):
+ def __init__(self, num, line):
+ self.num = num
+ self.args = get_args(line)
+ self.arglist = self.args.split(',')
+ self.name = get_name(line)
+ self.argc = get_argc(line)
+ self.argnames = get_argnames(line)
+ self.sizestr = calc_sizeofargs(line)
+ self.fmt = get_fmt(line)
+
+# Generator that yields Event objects given a trace-events file object
+def read_events(fobj):
+ event_num = 0
+ for line in fobj:
+ if not line.strip():
+ continue
+ if line.lstrip().startswith('#'):
+ continue
+ yield Event(event_num, line)
+ event_num += 1
+
+backend = ""
+output = ""
+binary = ""
+targettype = ""
+targetarch = ""
+probeprefix = ""
+
+def main():
+ global backend, output, binary, targettype, targetarch, probeprefix
+ supported_backends = ["simple", "nop", "stderr", "dtrace"]
+ short_options = "hcd"
+ long_options = ["stap", "backend=", "binary=", "target-arch=", "target-type=", "probe-prefix=", "list-backends", "check-backend"]
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], short_options, long_options)
+ except getopt.GetoptError, err:
+ # print help information and exit:
+ print str(err) # will print something like "option -a not recognized"
+ usage()
+ sys.exit(2)
+ for opt, arg in opts:
+ if opt == '-h':
+ output = 'h'
+ elif opt == '-c':
+ output = 'c'
+ elif opt == '-d':
+ output = 'd'
+ elif opt == '--stap':
+ output = 'stap'
+ elif opt == '--backend':
+ backend = arg
+ elif opt == '--binary':
+ binary = arg
+ elif opt == '--target-arch':
+ targetarch = arg
+ elif opt == '--target-type':
+ targettype = arg
+ elif opt == '--probe-prefix':
+ probeprefix = arg
+ elif opt == '--list-backends':
+ print 'simple, nop, stderr, dtrace'
+ sys.exit(0)
+ elif opt == "--check-backend":
+ if any(backend in s for s in supported_backends):
+ sys.exit(0)
+ else:
+ sys.exit(1)
+ else:
+ #assert False, "unhandled option"
+ print "unhandled option: ", opt
+ usage()
+
+ if backend == "" or output == "":
+ usage()
+ sys.exit(0)
+
+ events = read_events(sys.stdin)
+ trace_gen[output]['begin']()
+ converters[backend][output](events)
+ trace_gen[output]['end']()
+ return
+
+if __name__ == "__main__":
+ main()
+
--
1.7.1.1
next prev parent reply other threads:[~2012-01-09 15:47 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-09 15:46 [Qemu-devel] [RFC PATCH v2 0/4] simpletrace : support var num of args and strings Harsh Prateek Bora
2012-01-09 15:46 ` Harsh Prateek Bora [this message]
2012-01-09 21:06 ` [Qemu-devel] [RFC PATCH v2 1/4] Converting tracetool.sh to tracetool.py Andreas Färber
2012-01-10 6:12 ` Harsh Bora
2012-01-09 15:46 ` [Qemu-devel] [RFC PATCH v2 2/4] Makefile and configure changes for tracetool.py Harsh Prateek Bora
2012-01-09 15:46 ` [Qemu-devel] [RFC PATCH v2 3/4] simpletrace-v2: Handle variable number/size of elements per trace record Harsh Prateek Bora
2012-01-09 15:46 ` [Qemu-devel] [RFC PATCH v2 4/4] simpletrace.py: updated log reader script to handle new log format Harsh Prateek Bora
2012-01-09 16:01 ` [Qemu-devel] [RFC PATCH v2 0/4] simpletrace : support var num of args and strings Mathieu Desnoyers
2012-01-09 19:20 ` Harsh Bora
2012-01-10 0:14 ` Mathieu Desnoyers
2012-01-10 6:54 ` Harsh Bora
2012-01-10 7:17 ` [Qemu-devel] [lttng-dev] " Mathieu Desnoyers
2012-01-10 9:06 ` Harsh Bora
2012-01-10 10:44 ` Harsh Bora
2012-01-10 14:18 ` Mathieu Desnoyers
2012-01-10 14:58 ` Stefan Hajnoczi
2012-01-10 17:29 ` Mathieu Desnoyers
2012-01-11 9:30 ` Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1326123980-6038-2-git-send-email-harsh@linux.vnet.ibm.com \
--to=harsh@linux.vnet.ibm.com \
--cc=aneesh.kumar@linux.vnet.ibm.com \
--cc=mathieu.desnoyers@efficios.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@linux.vnet.ibm.com \
--cc=vilanova@ac.upc.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).