diff mbox

[2/5] trace: Add simple built-in tracing backend

Message ID 1274562503-10713-3-git-send-email-stefanha@linux.vnet.ibm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Stefan Hajnoczi May 22, 2010, 9:08 p.m. UTC
None
diff mbox

Patch

diff --git a/.gitignore b/.gitignore
index 4644557..68fb21d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@  config-host.*
 config-target.*
 trace.h
 trace.c
+events.py
 *-softmmu
 *-darwin-user
 *-linux-user
@@ -39,6 +40,7 @@  qemu-monitor.texi
 *.log
 *.pdf
 *.pg
+*.pyc
 *.toc
 *.tp
 *.vr
diff --git a/Makefile.objs b/Makefile.objs
index 9bbdf6f..d870767 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -252,6 +252,9 @@  libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
 # trace
 
 trace-obj-y = trace.o
+ifeq ($(TRACE_BACKEND),simple)
+trace-obj-y += simpletrace.o
+endif
 
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
 
diff --git a/configure b/configure
index 5e66f3a..d599879 100755
--- a/configure
+++ b/configure
@@ -829,7 +829,7 @@  echo "  --enable-docs            enable documentation build"
 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 "  --trace-backend=B        Trace backend nop"
+echo "  --trace-backend=B        Trace backend nop simple"
 echo ""
 echo "NOTE: The object files are built at the place where configure is launched"
 exit 1
diff --git a/simpletrace.c b/simpletrace.c
new file mode 100644
index 0000000..2fec4d3
--- /dev/null
+++ b/simpletrace.c
@@ -0,0 +1,64 @@ 
+#include <stdlib.h>
+#include <stdio.h>
+#include "trace.h"
+
+typedef struct {
+    unsigned long event;
+    unsigned long x1;
+    unsigned long x2;
+    unsigned long x3;
+    unsigned long x4;
+    unsigned long x5;
+} TraceRecord;
+
+enum {
+    TRACE_BUF_LEN = 64 * 1024 / sizeof(TraceRecord),
+};
+
+static TraceRecord trace_buf[TRACE_BUF_LEN];
+static unsigned int trace_idx;
+static FILE *trace_fp;
+
+static void trace(TraceEvent event, unsigned long x1,
+                  unsigned long x2, unsigned long x3,
+                  unsigned long x4, unsigned long x5) {
+    TraceRecord *rec = &trace_buf[trace_idx];
+    rec->event = event;
+    rec->x1 = x1;
+    rec->x2 = x2;
+    rec->x3 = x3;
+    rec->x4 = x4;
+    rec->x5 = x5;
+
+    if (++trace_idx == TRACE_BUF_LEN) {
+        trace_idx = 0;
+
+        if (!trace_fp) {
+            trace_fp = fopen("/tmp/trace.log", "w");
+        }
+        if (trace_fp) {
+            size_t result = fwrite(trace_buf, sizeof trace_buf, 1, trace_fp);
+            result = result;
+        }
+    }
+}
+
+void trace1(TraceEvent event, unsigned long x1) {
+    trace(event, x1, 0, 0, 0, 0);
+}
+
+void trace2(TraceEvent event, unsigned long x1, unsigned long x2) {
+    trace(event, x1, x2, 0, 0, 0);
+}
+
+void trace3(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3) {
+    trace(event, x1, x2, x3, 0, 0);
+}
+
+void trace4(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4) {
+    trace(event, x1, x2, x3, x4, 0);
+}
+
+void trace5(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5) {
+    trace(event, x1, x2, x3, x4, x5);
+}
diff --git a/simpletrace.py b/simpletrace.py
new file mode 100755
index 0000000..70609cf
--- /dev/null
+++ b/simpletrace.py
@@ -0,0 +1,38 @@ 
+#!/usr/bin/env python
+import sys
+import struct
+
+try:
+    from events import events
+except ImportError:
+    sys.stderr.write('''Unable to import trace events from current working directory.  Please run:
+tracetool --simple --py <trace-events >events.py\n''')
+    sys.exit(1)
+
+trace_fmt = 'LLLLLL'
+trace_len = struct.calcsize(trace_fmt)
+
+def read_record(fobj):
+    s = fobj.read(trace_len)
+    if len(s) != trace_len:
+        return None
+    return struct.unpack(trace_fmt, s)
+
+def format_record(rec):
+    event = events[rec[0]]
+    fields = [event[0]]
+    for i in xrange(1, len(event)):
+        fields.append('%s=0x%x' % (event[i], rec[i]))
+    return ' '.join(fields)
+
+if len(sys.argv) != 2:
+    sys.stderr.write('usage: %s <trace-file>\n' % sys.argv[0])
+    sys.exit(1)
+
+f = open(sys.argv[1], 'rb')
+while True:
+    rec = read_record(f)
+    if rec is None:
+        break
+
+    print format_record(rec)
diff --git a/tracetool b/tracetool
index e243d42..bcd163e 100755
--- a/tracetool
+++ b/tracetool
@@ -3,15 +3,17 @@ 
 usage()
 {
     cat >&2 <<EOF
-usage: $0 --nop [-h | -c]
+usage: $0 [--nop | --simple] [-h | -c | --py]
 Generate tracing code for a file on stdin.
 
 Backends:
-  --nop Tracing disabled
+  --nop     Tracing disabled
+  --simple  Simple built-in backend
 
 Output formats:
   -h    Generate .h file
   -c    Generate .c file
+  --py  Generate .py file (simple backend only)
 EOF
     exit 1
 }
@@ -48,6 +50,17 @@  get_argnames()
     echo -n "$name"
 }
 
+# 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 for a trace event
 get_fmt()
 {
@@ -67,6 +80,11 @@  warn_autogen_h()
     echo "/* This file is autogenerated by tracetool, do not edit. */"
 }
 
+warn_autogen_py()
+{
+    echo "# This file is autogenerated by tracetool, do not edit."
+}
+
 linetoh_begin_nop()
 {
     return
@@ -107,6 +125,101 @@  linetoc_end_nop()
     return
 }
 
+linetoh_begin_simple()
+{
+    cat <<EOF
+typedef unsigned int TraceEvent;
+
+void trace1(TraceEvent event, unsigned long x1);
+void trace2(TraceEvent event, unsigned long x1, unsigned long x2);
+void trace3(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3);
+void trace4(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4);
+void trace5(TraceEvent event, unsigned long x1, unsigned long x2, unsigned long x3, unsigned long x4, unsigned long x5);
+EOF
+
+    simple_event_num=0
+}
+
+cast_args_to_ulong()
+{
+    local arg
+    for arg in $(get_argnames "$1"); do
+        echo -n "(unsigned long)$arg"
+    done
+}
+
+linetoh_simple()
+{
+    local name args argc ulong_args
+    name=$(get_name "$1")
+    args=$(get_args "$1")
+    argc=$(get_argc "$1")
+    ulong_args=$(cast_args_to_ulong "$1")
+
+    cat <<EOF
+static inline void trace_$name($args) {
+    trace$argc($simple_event_num, $ulong_args);
+}
+EOF
+
+    simple_event_num=$((simple_event_num + 1))
+}
+
+linetoh_end_simple()
+{
+    return
+}
+
+linetoc_begin_simple()
+{
+    return
+}
+
+linetoc_simple()
+{
+    return
+}
+
+linetoc_end_simple()
+{
+    return
+}
+
+linetopy_begin_simple()
+{
+    echo "events = {"
+
+    simple_event_num=0
+}
+
+quote_args()
+{
+    local arg first
+    first=""
+    for arg in $(get_argnames "$1"); do
+        echo -n "$first'${arg%,}'"
+        first=", "
+    done
+}
+
+linetopy_simple()
+{
+    local name quoted_args
+    name=$(get_name "$1")
+    quoted_args=$(quote_args "$1")
+
+    cat <<EOF
+    $simple_event_num: ('$name', $quoted_args),
+EOF
+
+    simple_event_num=$((simple_event_num + 1))
+}
+
+linetopy_end_simple()
+{
+    echo "}"
+}
+
 # Process stdin by calling begin, line, and end functions for the backend
 convert()
 {
@@ -145,9 +258,16 @@  tracetoc()
     convert c
 }
 
+tracetopy()
+{
+    test "$backend" = "simple" || usage
+
+    convert py
+}
+
 # Choose backend
 case "$1" in
-"--nop") backend="${1#--}" ;;
+"--nop" | "--simple") backend="${1#--}" ;;
 *) usage ;;
 esac
 shift
@@ -155,6 +275,7 @@  shift
 case "$1" in
 "-h") tracetoh ;;
 "-c") tracetoc ;;
+"--py") tracetopy ;;
 "--check-backend") exit 0 ;; # used by ./configure to test for backend
 *) usage ;;
 esac