]>
git.proxmox.com Git - qemu.git/blob - scripts/tracetool/__init__.py
2 # -*- coding: utf-8 -*-
5 Machinery for generating tracing-related intermediate files.
8 __author__
= "Lluís Vilanova <vilanova@ac.upc.edu>"
9 __copyright__
= "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
10 __license__
= "GPL version 2 or (at your option) any later version"
12 __maintainer__
= "Stefan Hajnoczi"
13 __email__
= "stefanha@linux.vnet.ibm.com"
19 import tracetool
.format
20 import tracetool
.backend
23 def error_write(*lines
):
24 """Write a set of error lines."""
25 sys
.stderr
.writelines("\n".join(lines
) + "\n")
28 """Write a set of error lines and exit."""
33 def out(*lines
, **kwargs
):
34 """Write a set of output lines.
36 You can use kwargs as a shorthand for mapping variables when formating all
39 lines
= [ l
% kwargs
for l
in lines
]
40 sys
.stdout
.writelines("\n".join(lines
) + "\n")
44 """Event arguments description."""
46 def __init__(self
, args
):
51 List of (type, name) tuples.
57 """Build and Arguments instance from an argument string.
62 String describing the event arguments.
65 for arg
in arg_str
.split(","):
68 head
, sep
, tail
= parts
[-1].rpartition("*")
71 assert len(parts
) == 0 and sep
== ""
73 arg_type
= " ".join(parts
+ [ " ".join([head
, sep
]).strip() ]).strip()
74 res
.append((arg_type
, tail
))
78 """Iterate over the (type, name) pairs."""
79 return iter(self
._args
)
82 """Number of arguments."""
83 return len(self
._args
)
86 """String suitable for declaring function arguments."""
87 if len(self
._args
) == 0:
90 return ", ".join([ " ".join([t
, n
]) for t
,n
in self
._args
])
93 """Evaluable string representation for this object."""
94 return "Arguments(\"%s\")" % str(self
)
97 """List of argument names."""
98 return [ name
for _
, name
in self
._args
]
101 """List of argument types."""
102 return [ type_
for type_
, _
in self
._args
]
106 """Event description.
113 The event format string.
114 properties : set(str)
115 Properties of the event.
120 _CRE
= re
.compile("((?P<props>.*)\s+)?(?P<name>[^(\s]+)\((?P<args>[^)]*)\)\s*(?P<fmt>\".*)?")
122 _VALID_PROPS
= set(["disable"])
124 def __init__(self
, name
, props
, fmt
, args
):
133 Event printing format.
138 self
.properties
= props
142 unknown_props
= set(self
.properties
) - self
._VALID
_PROPS
143 if len(unknown_props
) > 0:
144 raise ValueError("Unknown properties: %s" % ", ".join(unknown_props
))
148 """Build an Event instance from a string.
153 Line describing the event.
155 m
= Event
._CRE
.match(line_str
)
157 groups
= m
.groupdict('')
159 name
= groups
["name"]
160 props
= groups
["props"].split()
162 args
= Arguments
.build(groups
["args"])
164 return Event(name
, props
, fmt
, args
)
167 """Evaluable string representation for this object."""
168 return "Event('%s %s(%s) %s')" % (" ".join(self
.properties
),
173 def _read_events(fobj
):
178 if line
.lstrip().startswith('#'):
180 res
.append(Event
.build(line
))
184 class TracetoolError (Exception):
185 """Exception for calls to generate."""
189 def try_import(mod_name
, attr_name
= None, attr_default
= None):
190 """Try to import a module and get an attribute from it.
196 attr_name : str, optional
197 Name of an attribute in the module.
198 attr_default : optional
199 Default value if the attribute does not exist in the module.
203 A pair indicating whether the module could be imported and the module or
204 object or attribute value.
207 module
= __import__(mod_name
, fromlist
=["__package__"])
208 if attr_name
is None:
210 return True, getattr(module
, str(attr_name
), attr_default
)
215 def generate(fevents
, format
, backend
,
216 binary
= None, probe_prefix
= None):
217 """Generate the output for the given (format, backend) pair.
222 Event description file.
228 See tracetool.backend.dtrace.BINARY.
229 probe_prefix : str or None
230 See tracetool.backend.dtrace.PROBEPREFIX.
232 # fix strange python error (UnboundLocalError tracetool)
237 raise TracetoolError("format not set")
238 mformat
= format
.replace("-", "_")
239 if not tracetool
.format
.exists(mformat
):
240 raise TracetoolError("unknown format: %s" % format
)
242 backend
= str(backend
)
243 if len(backend
) is 0:
244 raise TracetoolError("backend not set")
245 mbackend
= backend
.replace("-", "_")
246 if not tracetool
.backend
.exists(mbackend
):
247 raise TracetoolError("unknown backend: %s" % backend
)
249 if not tracetool
.backend
.compatible(mbackend
, mformat
):
250 raise TracetoolError("backend '%s' not compatible with format '%s'" %
253 import tracetool
.backend
.dtrace
254 tracetool
.backend
.dtrace
.BINARY
= binary
255 tracetool
.backend
.dtrace
.PROBEPREFIX
= probe_prefix
257 events
= _read_events(fevents
)
260 ( e
.properies
.add("disable") for e
in events
)
262 tracetool
.format
.generate_begin(mformat
, events
)
263 tracetool
.backend
.generate("nop", format
,
266 if "disable" in e
.properties
])
267 tracetool
.backend
.generate(backend
, format
,
270 if "disable" not in e
.properties
])
271 tracetool
.format
.generate_end(mformat
, events
)