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