Signed-off-by: Lluís Vilanova <vilan...@ac.upc.edu> --- scripts/tracetool.py | 31 ++++++++++ scripts/tracetool/__init__.py | 8 +++ scripts/tracetool/backend/dtrace.py | 104 +++++++++++++++++++++++++++++++++++ scripts/tracetool/format/d.py | 20 +++++++ scripts/tracetool/format/stap.py | 20 +++++++ 5 files changed, 183 insertions(+), 0 deletions(-) create mode 100644 scripts/tracetool/backend/dtrace.py create mode 100644 scripts/tracetool/format/d.py create mode 100644 scripts/tracetool/format/stap.py
diff --git a/scripts/tracetool.py b/scripts/tracetool.py index 22623ae..2dd9da0 100755 --- a/scripts/tracetool.py +++ b/scripts/tracetool.py @@ -44,6 +44,11 @@ Options: --help This help message. --list-backends Print list of available backends. --check-backend Check if the given backend is valid. + --binary <path> Full path to QEMU binary. + --target-type <type> QEMU emulator target type ('system' or 'user'). + --target-arch <arch> QEMU emulator target arch. + --probe-prefix <prefix> Prefix for dtrace probe names + (default: qemu-<target-type>-<target-arch>).\ """ % { "script" : _SCRIPT, "backends" : backend_descr, @@ -71,6 +76,10 @@ def main(args): check_backend = False arg_backend = "" arg_format = "" + binary = None + target_type = None + target_arch = None + probe_prefix = None for opt, arg in opts: if opt == "--help": error_opt() @@ -87,6 +96,15 @@ def main(args): elif opt == "--check-backend": check_backend = True + elif opt == "--binary": + binary = arg + elif opt == '--target-type': + target_type = arg + elif opt == '--target-arch': + target_arch = arg + elif opt == '--probe-prefix': + probe_prefix = arg + else: error_opt("unhandled option: %s" % opt) @@ -101,6 +119,19 @@ def main(args): kwargs = {} + if format == "stap": + if binary is None: + error_opt("--binary is required for SystemTAP tapset generator") + if probe_prefix is None and target_type is None: + error_opt("--target-type is required for SystemTAP tapset generator") + if probe_prefix is None and target_arch is None: + error_opt("--target-arch is required for SystemTAP tapset generator") + + if probe_prefix is None: + probe_prefix = ".".join([ "qemu", target_type, target_arch ]) + kwargs["binary"] = binary + kwargs["probe_prefix"] = probe_prefix + try: tracetool.generate(sys.stdin, arg_format, arg_backend, **kwargs) except tracetool.TracetoolError as e: diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py index 345b666..5c87583 100644 --- a/scripts/tracetool/__init__.py +++ b/scripts/tracetool/__init__.py @@ -164,6 +164,9 @@ def try_import(mod_name, attr_name = None, attr_default = None): def generate(fevents, format, backend, **options): """Generate the output for the given (format, backend) pair.""" + binary = options.pop("binary", None) + probe_prefix = options.pop("probe_prefix", None) + if len(options) > 0: raise ValueError("unknown options: " + ", ".join(options)) @@ -185,6 +188,11 @@ def generate(fevents, format, backend, **options): raise TracetoolError("backend '%s' not compatible with format '%s'" % (backend, format)) + if backend == "dtrace": + import tracetool.backend.dtrace + tracetool.backend.dtrace.BINARY = binary + tracetool.backend.dtrace.PROBEPREFIX = probe_prefix + events = _read_events(fevents) if backend == "nop": diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py new file mode 100644 index 0000000..7c2051c --- /dev/null +++ b/scripts/tracetool/backend/dtrace.py @@ -0,0 +1,104 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +DTrace/SystemTAP backend. +""" + +__author__ = "Lluís Vilanova <vilan...@ac.upc.edu>" +__copyright__ = "Copyright 2012, Lluís Vilanova <vilan...@ac.upc.edu>" +__license__ = "GPL version 2 or (at your option) any later version" + +__maintainer__ = "Stefan Hajnoczi" +__email__ = "stefa...@linux.vnet.ibm.com" + + +from tracetool import out + + +PUBLIC = True + + +PROBEPREFIX = None + +def _probeprefix(): + if PROBEPREFIX is None: + raise ValueError("you must set PROBEPREFIX") + return PROBEPREFIX + + +BINARY = None + +def _binary(): + if BINARY is None: + raise ValueError("you must set BINARY") + return BINARY + + +def c(events): + pass + + +def h(events): + out('#include "trace-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 = 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('', + '};') + + +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(): + # 'limit' is a reserved keyword + if name == 'limit': + name = '_limit' + out(' %s = $arg%d;' % (name.lstrip(), i)) + i += 1 + + out('}') + + out() diff --git a/scripts/tracetool/format/d.py b/scripts/tracetool/format/d.py new file mode 100644 index 0000000..a2d5947 --- /dev/null +++ b/scripts/tracetool/format/d.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Generate .d file (DTrace only). +""" + +__author__ = "Lluís Vilanova <vilan...@ac.upc.edu>" +__copyright__ = "Copyright 2012, Lluís Vilanova <vilan...@ac.upc.edu>" +__license__ = "GPL version 2 or (at your option) any later version" + +__maintainer__ = "Stefan Hajnoczi" +__email__ = "stefa...@linux.vnet.ibm.com" + + +from tracetool import out + + +def begin(events): + out('/* This file is autogenerated by tracetool, do not edit. */') diff --git a/scripts/tracetool/format/stap.py b/scripts/tracetool/format/stap.py new file mode 100644 index 0000000..50a4c69 --- /dev/null +++ b/scripts/tracetool/format/stap.py @@ -0,0 +1,20 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +Generate .stp file (DTrace with SystemTAP only). +""" + +__author__ = "Lluís Vilanova <vilan...@ac.upc.edu>" +__copyright__ = "Copyright 2012, Lluís Vilanova <vilan...@ac.upc.edu>" +__license__ = "GPL version 2 or (at your option) any later version" + +__maintainer__ = "Stefan Hajnoczi" +__email__ = "stefa...@linux.vnet.ibm.com" + + +from tracetool import out + + +def begin(events): + out('/* This file is autogenerated by tracetool, do not edit. */')