Skip to content

Commit

Permalink
trace: add tracetool simpletrace_stap format
Browse files Browse the repository at this point in the history
This new tracetool "format" generates a SystemTap .stp file that outputs
simpletrace binary trace data.

In contrast to simpletrace or ftrace, SystemTap does not define its own
trace format.  All output from SystemTap is generated by .stp files.
This patch lets us generate a .stp file that outputs in the simpletrace
binary format.

This makes it possible to reuse simpletrace.py to analyze traces
recorded using SystemTap.  The simpletrace binary format is especially
useful for long-running traces like flight-recorder mode where string
formatting can be expensive.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Aug 12, 2014
1 parent a76ccf3 commit 3f8b112
Showing 1 changed file with 71 additions and 0 deletions.
71 changes: 71 additions & 0 deletions scripts/tracetool/format/simpletrace_stap.py
@@ -0,0 +1,71 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Generate .stp file that outputs simpletrace binary traces (DTrace with SystemTAP only).
"""

__author__ = "Stefan Hajnoczi <redhat.com>"
__copyright__ = "Copyright (C) 2014, Red Hat, Inc."
__license__ = "GPL version 2 or (at your option) any later version"

__maintainer__ = "Stefan Hajnoczi"
__email__ = "stefanha@redhat.com"


from tracetool import out
from tracetool.backend.dtrace import binary, probeprefix
from tracetool.backend.simple import is_string
from tracetool.format.stap import stap_escape


def generate(events, backend):
out('/* This file is autogenerated by tracetool, do not edit. */',
'')

for event_id, e in enumerate(events):
if 'disable' in e.properties:
continue

out('probe %(probeprefix)s.simpletrace.%(name)s = %(probeprefix)s.%(name)s ?',
'{',
probeprefix=probeprefix(),
name=e.name)

# Calculate record size
sizes = ['24'] # sizeof(TraceRecord)
for type_, name in e.args:
name = stap_escape(name)
if is_string(type_):
out(' try {',
' arg%(name)s_str = %(name)s ? user_string_n(%(name)s, 512) : "<null>"',
' } catch {}',
' arg%(name)s_len = strlen(arg%(name)s_str)',
name=name)
sizes.append('4 + arg%s_len' % name)
else:
sizes.append('8')
sizestr = ' + '.join(sizes)

# Generate format string and value pairs for record header and arguments
fields = [('8b', str(event_id)),
('8b', 'gettimeofday_ns()'),
('4b', sizestr),
('4b', 'pid()')]
for type_, name in e.args:
name = stap_escape(name)
if is_string(type_):
fields.extend([('4b', 'arg%s_len' % name),
('.*s', 'arg%s_len, arg%s_str' % (name, name))])
else:
fields.append(('8b', name))

# Emit the entire record in a single SystemTap printf()
fmt_str = '%'.join(fmt for fmt, _ in fields)
arg_str = ', '.join(arg for _, arg in fields)
out(' printf("%%%(fmt_str)s", %(arg_str)s)',
fmt_str=fmt_str, arg_str=arg_str)

out('}')

out()

0 comments on commit 3f8b112

Please sign in to comment.