@@ -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
@@ -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)
@@ -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
new file mode 100644
@@ -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);
+}
new file mode 100755
@@ -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)
@@ -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