aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-05-08 12:38:01 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-05-08 12:38:01 +0100
commit43cbeffb19877c62cbe0aaf08b2f235d98d71340 (patch)
tree90a1d70eb7a165a8ddc923169651da2ab68edaac
parent6b342cc9c872e82620fdd32730cd92affa8a19b3 (diff)
parente00e36fb913217d49f57cc19d8d605270dd82bc5 (diff)
Merge remote-tracking branch 'remotes/stefanha/tags/tracing-pull-request' into staging
Tracing pull request # gpg: Signature made Wed 07 May 2014 18:14:02 BST using RSA key ID 81AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" * remotes/stefanha/tags/tracing-pull-request: configure: Show trace output file conditionally trace: [tracetool] Minimize the amount of per-backend code trace: [simple] Bump up log version number trace: [tracetool] Change format docs to point to the generated file trace: [tracetool] Show list of frontends and backends sorted by name trace: [tracetool] Cosmetic changes trace: [tracetool] Spacing changes trace: [tracetool] Add methods 'Event.copy' and 'Arguments.copy' trace: [tracetool] Add method 'Event.api' to build event names Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rwxr-xr-xconfigure2
-rwxr-xr-xscripts/simpletrace.py16
-rw-r--r--scripts/tracetool/__init__.py53
-rw-r--r--scripts/tracetool/backend/__init__.py74
-rw-r--r--scripts/tracetool/backend/dtrace.py81
-rw-r--r--scripts/tracetool/backend/events.py23
-rw-r--r--scripts/tracetool/backend/ftrace.py56
-rw-r--r--scripts/tracetool/backend/simple.py132
-rw-r--r--scripts/tracetool/backend/stderr.py43
-rw-r--r--scripts/tracetool/backend/ust.py65
-rw-r--r--scripts/tracetool/format/__init__.py50
-rw-r--r--scripts/tracetool/format/c.py16
-rw-r--r--scripts/tracetool/format/d.py30
-rw-r--r--scripts/tracetool/format/events_c.py15
-rw-r--r--scripts/tracetool/format/events_h.py15
-rw-r--r--scripts/tracetool/format/h.py30
-rw-r--r--scripts/tracetool/format/stap.py42
-rw-r--r--scripts/tracetool/format/ust_events_c.py7
-rw-r--r--scripts/tracetool/format/ust_events_h.py42
-rw-r--r--trace/Makefile.objs4
-rw-r--r--trace/simple.c2
21 files changed, 364 insertions, 434 deletions
diff --git a/configure b/configure
index ac2fa159c6..46bc0c91f4 100755
--- a/configure
+++ b/configure
@@ -4153,7 +4153,9 @@ echo "libcap-ng support $cap_ng"
echo "vhost-net support $vhost_net"
echo "vhost-scsi support $vhost_scsi"
echo "Trace backend $trace_backend"
+if test "$trace_backend" = "simple"; then
echo "Trace output file $trace_file-<pid>"
+fi
if test "$spice" = "yes"; then
echo "spice support $spice ($spice_protocol_version/$spice_server_version)"
else
diff --git a/scripts/simpletrace.py b/scripts/simpletrace.py
index 8bbcb42cc4..800835a9d3 100755
--- a/scripts/simpletrace.py
+++ b/scripts/simpletrace.py
@@ -65,13 +65,13 @@ def read_trace_file(edict, fobj):
header[0] != header_event_id or \
header[1] != header_magic:
raise ValueError('Not a valid trace file!')
- if header[2] != 0 and \
- header[2] != 2:
- raise ValueError('Unknown version of tracelog format!')
log_version = header[2]
- if log_version == 0:
- raise ValueError('Older log format, not supported with this QEMU release!')
+ if log_version not in [0, 2, 3]:
+ raise ValueError('Unknown version of tracelog format!')
+ if log_version != 3:
+ raise ValueError('Log format %d not supported with this QEMU release!'
+ % log_version)
while True:
rec = read_record(edict, fobj)
@@ -109,14 +109,10 @@ def process(events, log, analyzer):
if isinstance(log, str):
log = open(log, 'rb')
- enabled_events = []
dropped_event = Event.build("Dropped_Event(uint64_t num_events_dropped)")
edict = {dropped_event_id: dropped_event}
- for e in events:
- if 'disable' not in e.properties:
- enabled_events.append(e)
- for num, event in enumerate(enabled_events):
+ for num, event in enumerate(events):
edict[num] = event
def build_fn(analyzer, event):
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 175df08005..eccf5524f3 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -6,7 +6,7 @@ Machinery for generating tracing-related intermediate files.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -52,6 +52,10 @@ class Arguments:
"""
self._args = args
+ def copy(self):
+ """Create a new copy."""
+ return Arguments(list(self._args))
+
@staticmethod
def build(arg_str):
"""Build and Arguments instance from an argument string.
@@ -144,7 +148,13 @@ class Event(object):
unknown_props = set(self.properties) - self._VALID_PROPS
if len(unknown_props) > 0:
- raise ValueError("Unknown properties: %s" % ", ".join(unknown_props))
+ raise ValueError("Unknown properties: %s"
+ % ", ".join(unknown_props))
+
+ def copy(self):
+ """Create a new copy."""
+ return Event(self.name, list(self.properties), self.fmt,
+ self.args.copy(), self)
@staticmethod
def build(line_str):
@@ -173,6 +183,14 @@ class Event(object):
self.args,
self.fmt)
+ QEMU_TRACE = "trace_%(name)s"
+
+ def api(self, fmt=None):
+ if fmt is None:
+ fmt = Event.QEMU_TRACE
+ return fmt % {"name": self.name}
+
+
def _read_events(fobj):
res = []
for line in fobj:
@@ -189,7 +207,7 @@ class TracetoolError (Exception):
pass
-def try_import(mod_name, attr_name = None, attr_default = None):
+def try_import(mod_name, attr_name=None, attr_default=None):
"""Try to import a module and get an attribute from it.
Parameters
@@ -216,7 +234,7 @@ def try_import(mod_name, attr_name = None, attr_default = None):
def generate(fevents, format, backend,
- binary = None, probe_prefix = None):
+ binary=None, probe_prefix=None):
"""Generate the output for the given (format, backend) pair.
Parameters
@@ -238,20 +256,17 @@ def generate(fevents, format, backend,
format = str(format)
if len(format) is 0:
raise TracetoolError("format not set")
- mformat = format.replace("-", "_")
- if not tracetool.format.exists(mformat):
+ if not tracetool.format.exists(format):
raise TracetoolError("unknown format: %s" % format)
+ format = format.replace("-", "_")
backend = str(backend)
if len(backend) is 0:
raise TracetoolError("backend not set")
- mbackend = backend.replace("-", "_")
- if not tracetool.backend.exists(mbackend):
+ if not tracetool.backend.exists(backend):
raise TracetoolError("unknown backend: %s" % backend)
-
- if not tracetool.backend.compatible(mbackend, mformat):
- raise TracetoolError("backend '%s' not compatible with format '%s'" %
- (backend, format))
+ backend = backend.replace("-", "_")
+ backend = tracetool.backend.Wrapper(backend, format)
import tracetool.backend.dtrace
tracetool.backend.dtrace.BINARY = binary
@@ -259,16 +274,4 @@ def generate(fevents, format, backend,
events = _read_events(fevents)
- if backend == "nop":
- ( e.properies.add("disable") for e in events )
-
- tracetool.format.generate_begin(mformat, events)
- tracetool.backend.generate("nop", format,
- [ e
- for e in events
- if "disable" in e.properties ])
- tracetool.backend.generate(backend, format,
- [ e
- for e in events
- if "disable" not in e.properties ])
- tracetool.format.generate_end(mformat, events)
+ tracetool.format.generate(events, format, backend)
diff --git a/scripts/tracetool/backend/__init__.py b/scripts/tracetool/backend/__init__.py
index f0314ee376..5e36f0415d 100644
--- a/scripts/tracetool/backend/__init__.py
+++ b/scripts/tracetool/backend/__init__.py
@@ -30,17 +30,24 @@ PUBLIC If exists and is set to 'True', the backend is considered "public".
Backend functions
-----------------
-======== =======================================================================
-Function Description
-======== =======================================================================
-<format> Called to generate the format- and backend-specific code for each of
- the specified events. If the function does not exist, the backend is
- considered not compatible with the given format.
-======== =======================================================================
+All the following functions are optional, and no output will be generated if
+they do not exist.
+
+=============================== ==============================================
+Function Description
+=============================== ==============================================
+generate_<format>_begin(events) Generate backend- and format-specific file
+ header contents.
+generate_<format>_end(events) Generate backend- and format-specific file
+ footer contents.
+generate_<format>(event) Generate backend- and format-specific contents
+ for the given event.
+=============================== ==============================================
+
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -59,7 +66,7 @@ def get_list(only_public = False):
for filename in os.listdir(tracetool.backend.__path__[0]):
if filename.endswith('.py') and filename != '__init__.py':
modnames.append(filename.rsplit('.', 1)[0])
- for modname in modnames:
+ for modname in sorted(modnames):
module = tracetool.try_import("tracetool.backend." + modname)
# just in case; should never fail unless non-module files are put there
@@ -91,39 +98,24 @@ def exists(name):
return tracetool.try_import("tracetool.backend." + name)[1]
-def compatible(backend, format):
- """Whether a backend is compatible with the given format."""
- if not exists(backend):
- raise ValueError("unknown backend: %s" % backend)
-
- backend = backend.replace("-", "_")
- format = format.replace("-", "_")
-
- if backend == "nop":
- return True
- else:
- func = tracetool.try_import("tracetool.backend." + backend,
- format, None)[1]
- return func is not None
-
-
-def _empty(events):
- pass
+class Wrapper:
+ def __init__(self, backend, format):
+ self._backend = backend.replace("-", "_")
+ self._format = format.replace("-", "_")
+ assert exists(self._backend)
+ assert tracetool.format.exists(self._format)
-def generate(backend, format, events):
- """Generate the per-event output for the given (backend, format) pair."""
- if not compatible(backend, format):
- raise ValueError("backend '%s' not compatible with format '%s'" %
- (backend, format))
+ def _run_function(self, name, *args, **kwargs):
+ func = tracetool.try_import("tracetool.backend." + self._backend,
+ name % self._format, None)[1]
+ if func is not None:
+ func(*args, **kwargs)
- backend = backend.replace("-", "_")
- format = format.replace("-", "_")
+ def generate_begin(self, events):
+ self._run_function("generate_%s_begin", events)
- if backend == "nop":
- func = tracetool.try_import("tracetool.format." + format,
- "nop", _empty)[1]
- else:
- func = tracetool.try_import("tracetool.backend." + backend,
- format, None)[1]
+ def generate(self, event):
+ self._run_function("generate_%s", event)
- func(events)
+ def generate_end(self, events):
+ self._run_function("generate_%s_end", events)
diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
index e31bc799f8..fabfe99881 100644
--- a/scripts/tracetool/backend/dtrace.py
+++ b/scripts/tracetool/backend/dtrace.py
@@ -6,7 +6,7 @@ DTrace/SystemTAP backend.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -21,7 +21,7 @@ PUBLIC = True
PROBEPREFIX = None
-def _probeprefix():
+def probeprefix():
if PROBEPREFIX is None:
raise ValueError("you must set PROBEPREFIX")
return PROBEPREFIX
@@ -29,81 +29,18 @@ def _probeprefix():
BINARY = None
-def _binary():
+def binary():
if BINARY is None:
raise ValueError("you must set BINARY")
return BINARY
-def c(events):
- pass
-
-
-def h(events):
+def generate_h_begin(events):
out('#include "trace/generated-tracers-dtrace.h"',
'')
- for e in events:
- out('static inline void trace_%(name)s(%(args)s) {',
- ' QEMU_%(uppername)s(%(argnames)s);',
- '}',
- name = e.name,
- args = e.args,
- uppername = e.name.upper(),
- argnames = ", ".join(e.args.names()),
- )
-
-
-def d(events):
- out('provider qemu {')
-
- for e in events:
- args = str(e.args)
-
- # DTrace provider syntax expects foo() for empty
- # params, not foo(void)
- if args == 'void':
- args = ''
-
- # Define prototype for probe arguments
- out('',
- 'probe %(name)s(%(args)s);',
- name = e.name,
- args = args,
- )
-
- out('',
- '};')
-
-
-# Technically 'self' is not used by systemtap yet, but
-# they recommended we keep it in the reserved list anyway
-RESERVED_WORDS = (
- 'break', 'catch', 'continue', 'delete', 'else', 'for',
- 'foreach', 'function', 'global', 'if', 'in', 'limit',
- 'long', 'next', 'probe', 'return', 'self', 'string',
- 'try', 'while'
- )
-
-def stap(events):
- for e in events:
- # Define prototype for probe arguments
- out('probe %(probeprefix)s.%(name)s = process("%(binary)s").mark("%(name)s")',
- '{',
- probeprefix = _probeprefix(),
- name = e.name,
- binary = _binary(),
- )
-
- i = 1
- if len(e.args) > 0:
- for name in e.args.names():
- # Append underscore to reserved keywords
- if name in RESERVED_WORDS:
- name += '_'
- out(' %s = $arg%d;' % (name, i))
- i += 1
-
- out('}')
-
- out()
+
+def generate_h(event):
+ out(' QEMU_%(uppername)s(%(argnames)s);',
+ uppername=event.name.upper(),
+ argnames=", ".join(event.args.names()))
diff --git a/scripts/tracetool/backend/events.py b/scripts/tracetool/backend/events.py
deleted file mode 100644
index 5afce3e8da..0000000000
--- a/scripts/tracetool/backend/events.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-Generic event description.
-
-This is a dummy backend to establish appropriate frontend/backend compatibility
-checks.
-"""
-
-__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
-__license__ = "GPL version 2 or (at your option) any later version"
-
-__maintainer__ = "Stefan Hajnoczi"
-__email__ = "stefanha@linux.vnet.ibm.com"
-
-
-def events_h(events):
- pass
-
-def events_c(events):
- pass
diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py
index 888c361aec..d798c71347 100644
--- a/scripts/tracetool/backend/ftrace.py
+++ b/scripts/tracetool/backend/ftrace.py
@@ -19,36 +19,30 @@ from tracetool import out
PUBLIC = True
-def c(events):
- pass
-
-def h(events):
+def generate_h_begin(events):
out('#include "trace/ftrace.h"',
'#include "trace/control.h"',
- '',
- )
-
- for e in events:
- argnames = ", ".join(e.args.names())
- if len(e.args) > 0:
- argnames = ", " + argnames
-
- out('static inline void trace_%(name)s(%(args)s)',
- '{',
- ' char ftrace_buf[MAX_TRACE_STRLEN];',
- ' int unused __attribute__ ((unused));',
- ' int trlen;',
- ' bool _state = trace_event_get_state(%(event_id)s);',
- ' if (_state) {',
- ' trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,',
- ' "%(name)s " %(fmt)s "\\n" %(argnames)s);',
- ' trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);',
- ' unused = write(trace_marker_fd, ftrace_buf, trlen);',
- ' }',
- '}',
- name = e.name,
- args = e.args,
- event_id = "TRACE_" + e.name.upper(),
- fmt = e.fmt.rstrip("\n"),
- argnames = argnames,
- )
+ '')
+
+
+def generate_h(event):
+ argnames = ", ".join(event.args.names())
+ if len(event.args) > 0:
+ argnames = ", " + argnames
+
+ out(' {',
+ ' char ftrace_buf[MAX_TRACE_STRLEN];',
+ ' int unused __attribute__ ((unused));',
+ ' int trlen;',
+ ' if (trace_event_get_state(%(event_id)s)) {',
+ ' trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,',
+ ' "%(name)s " %(fmt)s "\\n" %(argnames)s);',
+ ' trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);',
+ ' unused = write(trace_marker_fd, ftrace_buf, trlen);',
+ ' }',
+ ' }',
+ name=event.name,
+ args=event.args,
+ event_id="TRACE_" + event.name.upper(),
+ fmt=event.fmt.rstrip("\n"),
+ argnames=argnames)
diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py
index 3dde372e46..e8c2cd57e9 100644
--- a/scripts/tracetool/backend/simple.py
+++ b/scripts/tracetool/backend/simple.py
@@ -6,7 +6,7 @@ Simple built-in backend.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -26,76 +26,74 @@ def is_string(arg):
else:
return False
-def c(events):
+
+def generate_h_begin(events):
+ for event in events:
+ out('void _simple_%(api)s(%(args)s);',
+ api=event.api(),
+ args=event.args)
+ out('')
+
+
+def generate_h(event):
+ out(' _simple_%(api)s(%(args)s);',
+ api=event.api(),
+ args=", ".join(event.args.names()))
+
+
+def generate_c_begin(events):
out('#include "trace.h"',
'#include "trace/control.h"',
'#include "trace/simple.h"',
+ '')
+
+
+def generate_c(event):
+ out('void _simple_%(api)s(%(args)s)',
+ '{',
+ ' TraceBufferRecord rec;',
+ api=event.api(),
+ args=event.args)
+ sizes = []
+ for type_, name in event.args:
+ if is_string(type_):
+ out(' size_t arg%(name)s_len = %(name)s ? MIN(strlen(%(name)s), MAX_TRACE_STRLEN) : 0;',
+ name=name)
+ strsizeinfo = "4 + arg%s_len" % name
+ sizes.append(strsizeinfo)
+ else:
+ sizes.append("8")
+ sizestr = " + ".join(sizes)
+ if len(event.args) == 0:
+ sizestr = '0'
+
+
+ out('',
+ ' if (!trace_event_get_state(%(event_id)s)) {',
+ ' return;',
+ ' }',
'',
- )
-
- for num, event in enumerate(events):
- out('void trace_%(name)s(%(args)s)',
- '{',
- ' TraceBufferRecord rec;',
- name = event.name,
- args = event.args,
- )
- sizes = []
+ ' if (trace_record_start(&rec, %(event_id)s, %(size_str)s)) {',
+ ' return; /* Trace Buffer Full, Event Dropped ! */',
+ ' }',
+ event_id='TRACE_' + event.name.upper(),
+ size_str=sizestr)
+
+ if len(event.args) > 0:
for type_, name in event.args:
+ # string
if is_string(type_):
- out(' size_t arg%(name)s_len = %(name)s ? MIN(strlen(%(name)s), MAX_TRACE_STRLEN) : 0;',
- name = name,
- )
- strsizeinfo = "4 + arg%s_len" % name
- sizes.append(strsizeinfo)
+ out(' trace_record_write_str(&rec, %(name)s, arg%(name)s_len);',
+ name=name)
+ # pointer var (not string)
+ elif type_.endswith('*'):
+ out(' trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)%(name)s);',
+ name=name)
+ # primitive data type
else:
- sizes.append("8")
- sizestr = " + ".join(sizes)
- if len(event.args) == 0:
- sizestr = '0'
-
-
- out('',
- ' TraceEvent *eventp = trace_event_id(%(event_enum)s);',
- ' bool _state = trace_event_get_state_dynamic(eventp);',
- ' if (!_state) {',
- ' return;',
- ' }',
- '',
- ' if (trace_record_start(&rec, %(event_id)s, %(size_str)s)) {',
- ' return; /* Trace Buffer Full, Event Dropped ! */',
- ' }',
- event_enum = 'TRACE_' + event.name.upper(),
- event_id = num,
- size_str = sizestr,
- )
-
- if len(event.args) > 0:
- for type_, name in event.args:
- # string
- if is_string(type_):
- out(' trace_record_write_str(&rec, %(name)s, arg%(name)s_len);',
- name = name,
- )
- # pointer var (not string)
- elif type_.endswith('*'):
- out(' trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)%(name)s);',
- name = name,
- )
- # primitive data type
- else:
- out(' trace_record_write_u64(&rec, (uint64_t)%(name)s);',
- name = name,
- )
-
- out(' trace_record_finish(&rec);',
- '}',
- '')
-
-
-def h(events):
- for event in events:
- out('void trace_%(name)s(%(args)s);',
- name = event.name,
- args = event.args,
- )
+ out(' trace_record_write_u64(&rec, (uint64_t)%(name)s);',
+ name=name)
+
+ out(' trace_record_finish(&rec);',
+ '}',
+ '')
diff --git a/scripts/tracetool/backend/stderr.py b/scripts/tracetool/backend/stderr.py
index 6f93dbd1ae..2a1e9064c3 100644
--- a/scripts/tracetool/backend/stderr.py
+++ b/scripts/tracetool/backend/stderr.py
@@ -6,7 +6,7 @@ Stderr built-in backend.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -19,30 +19,21 @@ from tracetool import out
PUBLIC = True
-def c(events):
- pass
-
-def h(events):
+def generate_h_begin(events):
out('#include <stdio.h>',
'#include "trace/control.h"',
- '',
- )
-
- for e in events:
- argnames = ", ".join(e.args.names())
- if len(e.args) > 0:
- argnames = ", " + argnames
-
- out('static inline void trace_%(name)s(%(args)s)',
- '{',
- ' bool _state = trace_event_get_state(%(event_id)s);',
- ' if (_state) {',
- ' fprintf(stderr, "%(name)s " %(fmt)s "\\n" %(argnames)s);',
- ' }',
- '}',
- name = e.name,
- args = e.args,
- event_id = "TRACE_" + e.name.upper(),
- fmt = e.fmt.rstrip("\n"),
- argnames = argnames,
- )
+ '')
+
+
+def generate_h(event):
+ argnames = ", ".join(event.args.names())
+ if len(event.args) > 0:
+ argnames = ", " + argnames
+
+ out(' if (trace_event_get_state(%(event_id)s)) {',
+ ' fprintf(stderr, "%(name)s " %(fmt)s "\\n" %(argnames)s);',
+ ' }',
+ event_id="TRACE_" + event.name.upper(),
+ name=event.name,
+ fmt=event.fmt.rstrip("\n"),
+ argnames=argnames)
diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py
index 41c1c75b7c..2f8f44abde 100644
--- a/scripts/tracetool/backend/ust.py
+++ b/scripts/tracetool/backend/ust.py
@@ -6,7 +6,7 @@ LTTng User Space Tracing backend.
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -18,65 +18,18 @@ from tracetool import out
PUBLIC = True
-def c(events):
- pass
-
-def h(events):
+def generate_h_begin(events):
out('#include <lttng/tracepoint.h>',
'#include "trace/generated-ust-provider.h"',
'')
- for e in events:
- argnames = ", ".join(e.args.names())
- if len(e.args) > 0:
- argnames = ", " + argnames
-
- out('static inline void trace_%(name)s(%(args)s)',
- '{',
- ' tracepoint(qemu, %(name)s%(tp_args)s);',
- '}',
- '',
- name = e.name,
- args = e.args,
- tp_args = argnames,
- )
-
-def ust_events_c(events):
- pass
-
-def ust_events_h(events):
- for e in events:
- if len(e.args) > 0:
- out('TRACEPOINT_EVENT(',
- ' qemu,',
- ' %(name)s,',
- ' TP_ARGS(%(args)s),',
- ' TP_FIELDS(',
- name = e.name,
- args = ", ".join(", ".join(i) for i in e.args),
- )
- for t,n in e.args:
- if ('int' in t) or ('long' in t) or ('unsigned' in t) or ('size_t' in t):
- out(' ctf_integer(' + t + ', ' + n + ', ' + n + ')')
- elif ('double' in t) or ('float' in t):
- out(' ctf_float(' + t + ', ' + n + ', ' + n + ')')
- elif ('char *' in t) or ('char*' in t):
- out(' ctf_string(' + n + ', ' + n + ')')
- elif ('void *' in t) or ('void*' in t):
- out(' ctf_integer_hex(unsigned long, ' + n + ', ' + n + ')')
- out(' )',
- ')',
- '')
+def generate_h(event):
+ argnames = ", ".join(event.args.names())
+ if len(event.args) > 0:
+ argnames = ", " + argnames
- else:
- out('TRACEPOINT_EVENT(',
- ' qemu,',
- ' %(name)s,',
- ' TP_ARGS(void),',
- ' TP_FIELDS()',
- ')',
- '',
- name = e.name,
- ) \ No newline at end of file
+ out(' tracepoint(qemu, %(name)s%(tp_args)s);',
+ name=event.name,
+ tp_args=argnames)
diff --git a/scripts/tracetool/format/__init__.py b/scripts/tracetool/format/__init__.py
index 3c2a0d89e0..812570ff6f 100644
--- a/scripts/tracetool/format/__init__.py
+++ b/scripts/tracetool/format/__init__.py
@@ -20,21 +20,16 @@ All formats must generate their contents through the 'tracetool.out' routine.
Format functions
----------------
-All the following functions are optional, and no output will be generated if
-they do not exist.
-
-======== =======================================================================
+======== ==================================================================
Function Description
-======== =======================================================================
-begin Called to generate the format-specific file header.
-end Called to generate the format-specific file footer.
-nop Called to generate the per-event contents when the event is disabled or
- the selected backend is 'nop'.
-======== =======================================================================
+======== ==================================================================
+generate Called to generate a format-specific file.
+======== ==================================================================
+
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -53,7 +48,7 @@ def get_list():
for filename in os.listdir(tracetool.format.__path__[0]):
if filename.endswith('.py') and filename != '__init__.py':
modnames.append(filename.rsplit('.', 1)[0])
- for modname in modnames:
+ for modname in sorted(modnames):
module = tracetool.try_import("tracetool.format." + modname)
# just in case; should never fail unless non-module files are put there
@@ -79,25 +74,12 @@ def exists(name):
return tracetool.try_import("tracetool.format." + name)[1]
-def _empty(events):
- pass
-
-def generate_begin(name, events):
- """Generate the header of the format-specific file."""
- if not exists(name):
- raise ValueError("unknown format: %s" % name)
-
- name = name.replace("-", "_")
- func = tracetool.try_import("tracetool.format." + name,
- "begin", _empty)[1]
- func(events)
-
-def generate_end(name, events):
- """Generate the footer of the format-specific file."""
- if not exists(name):
- raise ValueError("unknown format: %s" % name)
-
- name = name.replace("-", "_")
- func = tracetool.try_import("tracetool.format." + name,
- "end", _empty)[1]
- func(events)
+def generate(events, format, backend):
+ if not exists(format):
+ raise ValueError("unknown format: %s" % format)
+ format = format.replace("-", "_")
+ func = tracetool.try_import("tracetool.format." + format,
+ "generate")[1]
+ if func is None:
+ raise AttributeError("format has no 'generate': %s" % format)
+ func(events, backend)
diff --git a/scripts/tracetool/format/c.py b/scripts/tracetool/format/c.py
index 35555aee1f..699598fb02 100644
--- a/scripts/tracetool/format/c.py
+++ b/scripts/tracetool/format/c.py
@@ -2,11 +2,11 @@
# -*- coding: utf-8 -*-
"""
-Generate .c file.
+trace/generated-tracers.c
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -16,5 +16,13 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
-def begin(events):
- out('/* This file is autogenerated by tracetool, do not edit. */')
+def generate(events, backend):
+ events = [e for e in events
+ if "disable" not in e.properties]
+
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '')
+ backend.generate_begin(events)
+ for event in events:
+ backend.generate(event)
+ backend.generate_end(events)
diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py
index a2d594773c..46eebb128b 100644
--- a/scripts/tracetool/format/d.py
+++ b/scripts/tracetool/format/d.py
@@ -2,11 +2,11 @@
# -*- coding: utf-8 -*-
"""
-Generate .d file (DTrace only).
+trace/generated-tracers.dtrace (DTrace only).
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -16,5 +16,27 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
-def begin(events):
- out('/* This file is autogenerated by tracetool, do not edit. */')
+def generate(events, backend):
+ events = [e for e in events
+ if "disable" not in e.properties]
+
+ out('/* This file is autogenerated by tracetool, do not edit. */'
+ '',
+ 'provider qemu {')
+
+ for e in events:
+ args = str(e.args)
+
+ # DTrace provider syntax expects foo() for empty
+ # params, not foo(void)
+ if args == 'void':
+ args = ''
+
+ # Define prototype for probe arguments
+ out('',
+ 'probe %(name)s(%(args)s);',
+ name=e.name,
+ args=args)
+
+ out('',
+ '};')
diff --git a/scripts/tracetool/format/events_c.py b/scripts/tracetool/format/events_c.py
index d670ec83d5..2d97fa310a 100644
--- a/scripts/tracetool/format/events_c.py
+++ b/scripts/tracetool/format/events_c.py
@@ -2,11 +2,11 @@
# -*- coding: utf-8 -*-
"""
-Generate .c for event description.
+trace/generated-events.c
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -16,14 +16,13 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
-def begin(events):
+def generate(events, backend):
out('/* This file is autogenerated by tracetool, do not edit. */',
'',
'#include "trace.h"',
'#include "trace/generated-events.h"',
'#include "trace/control.h"',
- '',
- )
+ '')
out('TraceEvent trace_events[TRACE_EVENT_COUNT] = {')
@@ -31,9 +30,7 @@ def begin(events):
out(' { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s, .dstate = 0 },',
id = "TRACE_" + e.name.upper(),
name = e.name,
- sstate = "TRACE_%s_ENABLED" % e.name.upper(),
- )
+ sstate = "TRACE_%s_ENABLED" % e.name.upper())
out('};',
- '',
- )
+ '')
diff --git a/scripts/tracetool/format/events_h.py b/scripts/tracetool/format/events_h.py
index d30ccea8a1..25d913bb25 100644
--- a/scripts/tracetool/format/events_h.py
+++ b/scripts/tracetool/format/events_h.py
@@ -2,11 +2,11 @@
# -*- coding: utf-8 -*-
"""
-Generate .h for event description.
+trace/generated-events.h
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -16,15 +16,14 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
-def begin(events):
+def generate(events, backend):
out('/* This file is autogenerated by tracetool, do not edit. */',
'',
'#ifndef TRACE__GENERATED_EVENTS_H',
'#define TRACE__GENERATED_EVENTS_H',
'',
'#include <stdbool.h>',
- ''
- )
+ '')
# event identifiers
out('typedef enum {')
@@ -33,8 +32,7 @@ def begin(events):
out(' TRACE_%s,' % e.name.upper())
out(' TRACE_EVENT_COUNT',
- '} TraceEventID;',
- )
+ '} TraceEventID;')
# static state
for e in events:
@@ -46,5 +44,4 @@ def begin(events):
out('#include "trace/event-internal.h"',
'',
- '#endif /* TRACE__GENERATED_EVENTS_H */',
- )
+ '#endif /* TRACE__GENERATED_EVENTS_H */')
diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
index 93132fceaf..9b3943002c 100644
--- a/scripts/tracetool/format/h.py
+++ b/scripts/tracetool/format/h.py
@@ -2,11 +2,11 @@
# -*- coding: utf-8 -*-
"""
-Generate .h file.
+trace/generated-tracers.h
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -16,23 +16,29 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
-def begin(events):
+def generate(events, backend):
out('/* This file is autogenerated by tracetool, do not edit. */',
'',
'#ifndef TRACE__GENERATED_TRACERS_H',
'#define TRACE__GENERATED_TRACERS_H',
'',
- '#include "qemu-common.h"')
+ '#include "qemu-common.h"',
+ '')
-def end(events):
- out('#endif /* TRACE__GENERATED_TRACERS_H */')
+ backend.generate_begin(events)
-def nop(events):
for e in events:
out('',
- 'static inline void trace_%(name)s(%(args)s)',
+ 'static inline void %(api)s(%(args)s)',
'{',
- '}',
- name = e.name,
- args = e.args,
- )
+ api=e.api(),
+ args=e.args)
+
+ if "disable" not in e.properties:
+ backend.generate(e)
+
+ out('}')
+
+ backend.generate_end(events)
+
+ out('#endif /* TRACE__GENERATED_TRACERS_H */')
diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py
index 50a4c69954..e24abf7f11 100644
--- a/scripts/tracetool/format/stap.py
+++ b/scripts/tracetool/format/stap.py
@@ -6,7 +6,7 @@ Generate .stp file (DTrace with SystemTAP only).
"""
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
-__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
+__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
@@ -14,7 +14,43 @@ __email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
+from tracetool.backend.dtrace import binary, probeprefix
-def begin(events):
- out('/* This file is autogenerated by tracetool, do not edit. */')
+# Technically 'self' is not used by systemtap yet, but
+# they recommended we keep it in the reserved list anyway
+RESERVED_WORDS = (
+ 'break', 'catch', 'continue', 'delete', 'else', 'for',
+ 'foreach', 'function', 'global', 'if', 'in', 'limit',
+ 'long', 'next', 'probe', 'return', 'self', 'string',
+ 'try', 'while'
+ )
+
+
+def generate(events, backend):
+ events = [e for e in events
+ if "disable" not in e.properties]
+
+ out('/* This file is autogenerated by tracetool, do not edit. */',
+ '')
+
+ for e in events:
+ # Define prototype for probe arguments
+ out('probe %(probeprefix)s.%(name)s = process("%(binary)s").mark("%(name)s")',
+ '{',
+ probeprefix=probeprefix(),
+ name=e.name,
+ binary=binary())
+
+ i = 1
+ if len(e.args) > 0:
+ for name in e.args.names():
+ # Append underscore to reserved keywords
+ if name in RESERVED_WORDS:
+ name += '_'
+ out(' %s = $arg%d;' % (name, i))
+ i += 1
+
+ out('}')
+
+ out()
diff --git a/scripts/tracetool/format/ust_events_c.py b/scripts/tracetool/format/ust_events_c.py
index 116e713225..bc970936be 100644
--- a/scripts/tracetool/format/ust_events_c.py
+++ b/scripts/tracetool/format/ust_events_c.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""
-Generate .c for LTTng ust event description.
+trace/generated-ust.c
"""
__author__ = "Mohamad Gebai <mohamad.gebai@polymtl.ca>"
@@ -16,7 +16,10 @@ __email__ = "stefanha@redhat.com"
from tracetool import out
-def begin(events):
+def generate(events, backend):
+ events = [e for e in events
+ if "disabled" not in e.properties]
+
out('/* This file is autogenerated by tracetool, do not edit. */',
'',
'#define TRACEPOINT_DEFINE',
diff --git a/scripts/tracetool/format/ust_events_h.py b/scripts/tracetool/format/ust_events_h.py
index f206eca6ec..5102565470 100644
--- a/scripts/tracetool/format/ust_events_h.py
+++ b/scripts/tracetool/format/ust_events_h.py
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
"""
-Generate .h for LTTng ust event description.
+trace/generated-ust-provider.h
"""
__author__ = "Mohamad Gebai <mohamad.gebai@polymtl.ca>"
@@ -16,7 +16,10 @@ __email__ = "stefanha@redhat.com"
from tracetool import out
-def begin(events):
+def generate(events, backend):
+ events = [e for e in events
+ if "disabled" not in e.properties]
+
out('/* This file is autogenerated by tracetool, do not edit. */',
'',
'#undef TRACEPOINT_PROVIDER',
@@ -50,7 +53,40 @@ def begin(events):
'#endif',
'')
-def end(events):
+ for e in events:
+ if len(e.args) > 0:
+ out('TRACEPOINT_EVENT(',
+ ' qemu,',
+ ' %(name)s,',
+ ' TP_ARGS(%(args)s),',
+ ' TP_FIELDS(',
+ name=e.name,
+ args=", ".join(", ".join(i) for i in e.args))
+
+ for t, n in e.args:
+ if ('int' in t) or ('long' in t) or ('unsigned' in t) or ('size_t' in t):
+ out(' ctf_integer(' + t + ', ' + n + ', ' + n + ')')
+ elif ('double' in t) or ('float' in t):
+ out(' ctf_float(' + t + ', ' + n + ', ' + n + ')')
+ elif ('char *' in t) or ('char*' in t):
+ out(' ctf_string(' + n + ', ' + n + ')')
+ elif ('void *' in t) or ('void*' in t):
+ out(' ctf_integer_hex(unsigned long, ' + n + ', ' + n + ')')
+
+ out(' )',
+ ')',
+ '')
+
+ else:
+ out('TRACEPOINT_EVENT(',
+ ' qemu,',
+ ' %(name)s,',
+ ' TP_ARGS(void),',
+ ' TP_FIELDS()',
+ ')',
+ '',
+ name=e.name)
+
out('#endif /* TRACE__GENERATED_UST_H */',
'',
'/* This part must be outside ifdef protection */',
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index d321946d38..6a30467096 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -31,7 +31,7 @@ $(obj)/generated-events.h: $(obj)/generated-events.h-timestamp
$(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events
$(call quiet-command,$(TRACETOOL) \
--format=events-h \
- --backend=events \
+ --backend=$(TRACE_BACKEND) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
@@ -39,7 +39,7 @@ $(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/conf
$(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events
$(call quiet-command,$(TRACETOOL) \
--format=events-c \
- --backend=events \
+ --backend=$(TRACE_BACKEND) \
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
diff --git a/trace/simple.c b/trace/simple.c
index aaa010ee2b..bb0b52ce02 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -28,7 +28,7 @@
#define HEADER_MAGIC 0xf2b177cb0aa429b4ULL
/** Trace file version number, bump if format changes */
-#define HEADER_VERSION 2
+#define HEADER_VERSION 3
/** Records were dropped event ID */
#define DROPPED_EVENT_ID (~(uint64_t)0 - 1)