tracetool: Add support for the 'dtrace' backend

Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
This commit is contained in:
Lluís Vilanova 2012-04-03 20:48:12 +02:00 committed by Stefan Hajnoczi
parent fbc54b9412
commit 52ef093ace
5 changed files with 178 additions and 2 deletions

View File

@ -44,6 +44,11 @@ Options:
--help This help message. --help This help message.
--list-backends Print list of available backends. --list-backends Print list of available backends.
--check-backend Check if the given backend is valid. --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, "script" : _SCRIPT,
"backends" : backend_descr, "backends" : backend_descr,
@ -71,6 +76,10 @@ def main(args):
check_backend = False check_backend = False
arg_backend = "" arg_backend = ""
arg_format = "" arg_format = ""
binary = None
target_type = None
target_arch = None
probe_prefix = None
for opt, arg in opts: for opt, arg in opts:
if opt == "--help": if opt == "--help":
error_opt() error_opt()
@ -87,6 +96,15 @@ def main(args):
elif opt == "--check-backend": elif opt == "--check-backend":
check_backend = True 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: else:
error_opt("unhandled option: %s" % opt) error_opt("unhandled option: %s" % opt)
@ -99,8 +117,20 @@ def main(args):
else: else:
sys.exit(1) sys.exit(1)
if arg_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 ])
try: try:
tracetool.generate(sys.stdin, arg_format, arg_backend) tracetool.generate(sys.stdin, arg_format, arg_backend,
binary = binary, probe_prefix = probe_prefix)
except tracetool.TracetoolError as e: except tracetool.TracetoolError as e:
error_opt(str(e)) error_opt(str(e))

View File

@ -212,7 +212,8 @@ def try_import(mod_name, attr_name = None, attr_default = None):
return False, None return False, None
def generate(fevents, format, backend): def generate(fevents, format, backend,
binary = None, probe_prefix = None):
"""Generate the output for the given (format, backend) pair. """Generate the output for the given (format, backend) pair.
Parameters Parameters
@ -223,6 +224,10 @@ def generate(fevents, format, backend):
Output format name. Output format name.
backend : str backend : str
Output backend name. Output backend name.
binary : str or None
See tracetool.backend.dtrace.BINARY.
probe_prefix : str or None
See tracetool.backend.dtrace.PROBEPREFIX.
""" """
# fix strange python error (UnboundLocalError tracetool) # fix strange python error (UnboundLocalError tracetool)
import tracetool import tracetool
@ -245,6 +250,10 @@ def generate(fevents, format, backend):
raise TracetoolError("backend '%s' not compatible with format '%s'" % raise TracetoolError("backend '%s' not compatible with format '%s'" %
(backend, format)) (backend, format))
import tracetool.backend.dtrace
tracetool.backend.dtrace.BINARY = binary
tracetool.backend.dtrace.PROBEPREFIX = probe_prefix
events = _read_events(fevents) events = _read_events(fevents)
if backend == "nop": if backend == "nop":

View File

@ -0,0 +1,97 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
DTrace/SystemTAP backend.
"""
__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"
from tracetool import out
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 = 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('',
'};')
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()

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Generate .d file (DTrace only).
"""
__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"
from tracetool import out
def begin(events):
out('/* This file is autogenerated by tracetool, do not edit. */')

View File

@ -0,0 +1,20 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
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>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "stefanha@linux.vnet.ibm.com"
from tracetool import out
def begin(events):
out('/* This file is autogenerated by tracetool, do not edit. */')