#!/usr/bin/env python # -*- coding: utf-8 -*- """ Generate .stp file that outputs simpletrace binary traces (DTrace with SystemTAP only). """ __author__ = "Stefan Hajnoczi " __copyright__ = "Copyright (C) 2014, Red Hat, Inc." __license__ = "GPL version 2 or (at your option) any later version" __maintainer__ = "Stefan Hajnoczi" __email__ = "stefanha@redhat.com" from tracetool import out from tracetool.backend.dtrace import binary, probeprefix from tracetool.backend.simple import is_string from tracetool.format.stap import stap_escape def generate(events, backend, group): out('/* This file is autogenerated by tracetool, do not edit. */', '', 'global event_name_to_id_map', 'global event_next_id', 'function simple_trace_map_event(name)', '', '{', ' if (!([name] in event_name_to_id_map)) {', ' event_name_to_id_map[name] = event_next_id', ' name_len = strlen(name)', ' printf("%%8b%%8b%%4b%%.*s", 0, ', ' event_next_id, name_len, name_len, name)', ' event_next_id = event_next_id + 1', ' }', ' return event_name_to_id_map[name]', '}', 'probe begin', '{', ' printf("%%8b%%8b%%8b", 0xffffffffffffffff, 0xf2b177cb0aa429b4, 4)', '}', '') for event_id, e in enumerate(events): if 'disable' in e.properties: continue out('probe %(probeprefix)s.simpletrace.%(name)s = %(probeprefix)s.%(name)s ?', '{', ' id = simple_trace_map_event("%(name)s")', probeprefix=probeprefix(), name=e.name) # Calculate record size sizes = ['24'] # sizeof(TraceRecord) for type_, name in e.args: name = stap_escape(name) if is_string(type_): out(' try {', ' arg%(name)s_str = %(name)s ? user_string_n(%(name)s, 512) : ""', ' } catch {}', ' arg%(name)s_len = strlen(arg%(name)s_str)', name=name) sizes.append('4 + arg%s_len' % name) else: sizes.append('8') sizestr = ' + '.join(sizes) # Generate format string and value pairs for record header and arguments fields = [('8b', 'id'), ('8b', 'gettimeofday_ns()'), ('4b', sizestr), ('4b', 'pid()')] for type_, name in e.args: name = stap_escape(name) if is_string(type_): fields.extend([('4b', 'arg%s_len' % name), ('.*s', 'arg%s_len, arg%s_str' % (name, name))]) else: fields.append(('8b', name)) # Emit the entire record in a single SystemTap printf() fmt_str = '%'.join(fmt for fmt, _ in fields) arg_str = ', '.join(arg for _, arg in fields) out(' printf("%%8b%%%(fmt_str)s", 1, %(arg_str)s)', fmt_str=fmt_str, arg_str=arg_str) out('}') out()