1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4""" 5Generate .stp file that outputs simpletrace binary traces (DTrace with SystemTAP only). 6""" 7 8__author__ = "Stefan Hajnoczi <redhat.com>" 9__copyright__ = "Copyright (C) 2014, Red Hat, Inc." 10__license__ = "GPL version 2 or (at your option) any later version" 11 12__maintainer__ = "Stefan Hajnoczi" 13__email__ = "stefanha@redhat.com" 14 15 16from tracetool import out 17from tracetool.backend.dtrace import binary, probeprefix 18from tracetool.backend.simple import is_string 19from tracetool.format.stap import stap_escape 20 21def global_var_name(name): 22 return probeprefix().replace(".", "_") + "_" + name 23 24def generate(events, backend, group): 25 id_map = global_var_name("event_name_to_id_map") 26 next_id = global_var_name("event_next_id") 27 map_func = global_var_name("simple_trace_map_event") 28 out('/* This file is autogenerated by tracetool, do not edit. */', 29 '', 30 'global %(id_map)s', 31 'global %(next_id)s', 32 'function %(map_func)s(name)', 33 '', 34 '{', 35 ' if (!([name] in %(id_map)s)) {', 36 ' %(id_map)s[name] = %(next_id)s', 37 ' name_len = strlen(name)', 38 ' printf("%%8b%%8b%%4b%%.*s", 0, ', 39 ' %(next_id)s, name_len, name_len, name)', 40 ' %(next_id)s = %(next_id)s + 1', 41 ' }', 42 ' return %(id_map)s[name]', 43 '}', 44 'probe begin', 45 '{', 46 ' printf("%%8b%%8b%%8b", 0xffffffffffffffff, 0xf2b177cb0aa429b4, 4)', 47 '}', 48 '', 49 id_map=id_map, 50 next_id=next_id, 51 map_func=map_func) 52 53 for event_id, e in enumerate(events): 54 if 'disable' in e.properties: 55 continue 56 57 out('probe %(probeprefix)s.simpletrace.%(name)s = %(probeprefix)s.%(name)s ?', 58 '{', 59 ' id = %(map_func)s("%(name)s")', 60 probeprefix=probeprefix(), 61 map_func=map_func, 62 name=e.name) 63 64 # Calculate record size 65 sizes = ['24'] # sizeof(TraceRecord) 66 for type_, name in e.args: 67 name = stap_escape(name) 68 if is_string(type_): 69 out(' try {', 70 ' arg%(name)s_str = %(name)s ? user_string_n(%(name)s, 512) : "<null>"', 71 ' } catch {}', 72 ' arg%(name)s_len = strlen(arg%(name)s_str)', 73 name=name) 74 sizes.append('4 + arg%s_len' % name) 75 else: 76 sizes.append('8') 77 sizestr = ' + '.join(sizes) 78 79 # Generate format string and value pairs for record header and arguments 80 fields = [('8b', 'id'), 81 ('8b', 'gettimeofday_ns()'), 82 ('4b', sizestr), 83 ('4b', 'pid()')] 84 for type_, name in e.args: 85 name = stap_escape(name) 86 if is_string(type_): 87 fields.extend([('4b', 'arg%s_len' % name), 88 ('.*s', 'arg%s_len, arg%s_str' % (name, name))]) 89 else: 90 fields.append(('8b', name)) 91 92 # Emit the entire record in a single SystemTap printf() 93 fmt_str = '%'.join(fmt for fmt, _ in fields) 94 arg_str = ', '.join(arg for _, arg in fields) 95 out(' printf("%%8b%%%(fmt_str)s", 1, %(arg_str)s)', 96 fmt_str=fmt_str, arg_str=arg_str) 97 98 out('}') 99 100 out() 101