diff options
-rwxr-xr-x | configure | 2 | ||||
-rwxr-xr-x | scripts/simpletrace.py | 16 | ||||
-rw-r--r-- | scripts/tracetool/__init__.py | 53 | ||||
-rw-r--r-- | scripts/tracetool/backend/__init__.py | 74 | ||||
-rw-r--r-- | scripts/tracetool/backend/dtrace.py | 81 | ||||
-rw-r--r-- | scripts/tracetool/backend/events.py | 23 | ||||
-rw-r--r-- | scripts/tracetool/backend/ftrace.py | 56 | ||||
-rw-r--r-- | scripts/tracetool/backend/simple.py | 132 | ||||
-rw-r--r-- | scripts/tracetool/backend/stderr.py | 43 | ||||
-rw-r--r-- | scripts/tracetool/backend/ust.py | 65 | ||||
-rw-r--r-- | scripts/tracetool/format/__init__.py | 50 | ||||
-rw-r--r-- | scripts/tracetool/format/c.py | 16 | ||||
-rw-r--r-- | scripts/tracetool/format/d.py | 30 | ||||
-rw-r--r-- | scripts/tracetool/format/events_c.py | 15 | ||||
-rw-r--r-- | scripts/tracetool/format/events_h.py | 15 | ||||
-rw-r--r-- | scripts/tracetool/format/h.py | 30 | ||||
-rw-r--r-- | scripts/tracetool/format/stap.py | 42 | ||||
-rw-r--r-- | scripts/tracetool/format/ust_events_c.py | 7 | ||||
-rw-r--r-- | scripts/tracetool/format/ust_events_h.py | 42 | ||||
-rw-r--r-- | trace/Makefile.objs | 4 | ||||
-rw-r--r-- | trace/simple.c | 2 |
21 files changed, 364 insertions, 434 deletions
@@ -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) |