958e1b
From a38cb7ff39accd9ea600e2409866eb12fb3b8871 Mon Sep 17 00:00:00 2001
958e1b
From: Stefan Hajnoczi <stefanha@redhat.com>
958e1b
Date: Tue, 7 Oct 2014 14:06:55 +0200
958e1b
Subject: [PATCH 37/43] trace: add tracetool simpletrace_stap format
958e1b
958e1b
Message-id: <1412690820-31016-7-git-send-email-stefanha@redhat.com>
958e1b
Patchwork-id: 61611
958e1b
O-Subject: [RHEL7.1 qemu-kvm PATCH 06/11] trace: add tracetool simpletrace_stap format
958e1b
Bugzilla: 1088112
958e1b
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
958e1b
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
958e1b
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
958e1b
958e1b
This new tracetool "format" generates a SystemTap .stp file that outputs
958e1b
simpletrace binary trace data.
958e1b
958e1b
In contrast to simpletrace or ftrace, SystemTap does not define its own
958e1b
trace format.  All output from SystemTap is generated by .stp files.
958e1b
This patch lets us generate a .stp file that outputs in the simpletrace
958e1b
binary format.
958e1b
958e1b
This makes it possible to reuse simpletrace.py to analyze traces
958e1b
recorded using SystemTap.  The simpletrace binary format is especially
958e1b
useful for long-running traces like flight-recorder mode where string
958e1b
formatting can be expensive.
958e1b
958e1b
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
958e1b
(cherry picked from commit 3f8b112d6b9ab65e165096582c78154dda1adc69)
958e1b
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
958e1b
958e1b
Downstream tracetool does not have the code reorganization from the
958e1b
multi-backend tracing changes.  Therefore the stap generation has to
958e1b
happen in scripts/tracetool/backend/dtrace.py while the
958e1b
scripts/tracetool/format/simpletrace_stap.py file just emits the file
958e1b
header.
958e1b
958e1b
Remember to import tracetool.backend.simple is_string() in dtrace.py.
958e1b
958e1b
Also note that scripts/tracetool/__init__.py filters out disabled events
958e1b
so we don't need to skip them explicitly.
958e1b
958e1b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
958e1b
---
958e1b
 scripts/tracetool/backend/dtrace.py          | 47 ++++++++++++++++++++++++++++
958e1b
 scripts/tracetool/format/simpletrace_stap.py | 21 +++++++++++++
958e1b
 2 files changed, 68 insertions(+)
958e1b
 create mode 100644 scripts/tracetool/format/simpletrace_stap.py
958e1b
958e1b
diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
958e1b
index 614316f..2d8cd2d 100644
958e1b
--- a/scripts/tracetool/backend/dtrace.py
958e1b
+++ b/scripts/tracetool/backend/dtrace.py
958e1b
@@ -14,6 +14,7 @@ __email__      = "stefanha@linux.vnet.ibm.com"
958e1b
 
958e1b
 
958e1b
 from tracetool import out
958e1b
+from tracetool.backend.simple import is_string
958e1b
 
958e1b
 
958e1b
 PUBLIC = True
958e1b
@@ -112,3 +113,49 @@ def stap(events):
958e1b
         out('}')
958e1b
 
958e1b
     out()
958e1b
+
958e1b
+
958e1b
+def simpletrace_stap(events):
958e1b
+    for event_id, e in enumerate(events):
958e1b
+        out('probe %(probeprefix)s.simpletrace.%(name)s = %(probeprefix)s.%(name)s ?',
958e1b
+            '{',
958e1b
+            probeprefix=_probeprefix(),
958e1b
+            name=e.name)
958e1b
+
958e1b
+        # Calculate record size
958e1b
+        sizes = ['24'] # sizeof(TraceRecord)
958e1b
+        for type_, name in e.args:
958e1b
+            name = stap_escape(name)
958e1b
+            if is_string(type_):
958e1b
+                out('    try {',
958e1b
+                    '        arg%(name)s_str = %(name)s ? user_string_n(%(name)s, 512) : "<null>"',
958e1b
+                    '    } catch {}',
958e1b
+                    '    arg%(name)s_len = strlen(arg%(name)s_str)',
958e1b
+                    name=name)
958e1b
+                sizes.append('4 + arg%s_len' % name)
958e1b
+            else:
958e1b
+                sizes.append('8')
958e1b
+        sizestr = ' + '.join(sizes)
958e1b
+
958e1b
+        # Generate format string and value pairs for record header and arguments
958e1b
+        fields = [('8b', str(event_id)),
958e1b
+                  ('8b', 'gettimeofday_ns()'),
958e1b
+                  ('4b', sizestr),
958e1b
+                  ('4b', 'pid()')]
958e1b
+        for type_, name in e.args:
958e1b
+            name = stap_escape(name)
958e1b
+            if is_string(type_):
958e1b
+                fields.extend([('4b', 'arg%s_len' % name),
958e1b
+                               ('.*s', 'arg%s_len, arg%s_str' % (name, name))])
958e1b
+            else:
958e1b
+                fields.append(('8b', name))
958e1b
+
958e1b
+        # Emit the entire record in a single SystemTap printf()
958e1b
+        fmt_str = '%'.join(fmt for fmt, _ in fields)
958e1b
+        arg_str = ', '.join(arg for _, arg in fields)
958e1b
+        out('    printf("%%%(fmt_str)s", %(arg_str)s)',
958e1b
+            fmt_str=fmt_str, arg_str=arg_str)
958e1b
+
958e1b
+        out('}')
958e1b
+
958e1b
+    out()
958e1b
diff --git a/scripts/tracetool/format/simpletrace_stap.py b/scripts/tracetool/format/simpletrace_stap.py
958e1b
new file mode 100644
958e1b
index 0000000..b8daa03
958e1b
--- /dev/null
958e1b
+++ b/scripts/tracetool/format/simpletrace_stap.py
958e1b
@@ -0,0 +1,21 @@
958e1b
+#!/usr/bin/env python
958e1b
+# -*- coding: utf-8 -*-
958e1b
+
958e1b
+"""
958e1b
+Generate .stp file that outputs simpletrace binary traces (DTrace with SystemTAP only).
958e1b
+"""
958e1b
+
958e1b
+__author__     = "Stefan Hajnoczi <redhat.com>"
958e1b
+__copyright__  = "Copyright (C) 2014, Red Hat, Inc."
958e1b
+__license__    = "GPL version 2 or (at your option) any later version"
958e1b
+
958e1b
+__maintainer__ = "Stefan Hajnoczi"
958e1b
+__email__      = "stefanha@redhat.com"
958e1b
+
958e1b
+
958e1b
+from tracetool import out
958e1b
+
958e1b
+
958e1b
+def begin(events):
958e1b
+    out('/* This file is autogenerated by tracetool, do not edit. */',
958e1b
+        '')
958e1b
-- 
958e1b
1.8.3.1
958e1b