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 21 22def generate(events, backend, group): 23 out('/* This file is autogenerated by tracetool, do not edit. */', 24 '', 25 'global event_name_to_id_map', 26 'global event_next_id', 27 'function simple_trace_map_event(name)', 28 '', 29 '{', 30 ' if (!([name] in event_name_to_id_map)) {', 31 ' event_name_to_id_map[name] = event_next_id', 32 ' name_len = strlen(name)', 33 ' printf("%%8b%%8b%%4b%%.*s", 0, ', 34 ' event_next_id, name_len, name_len, name)', 35 ' event_next_id = event_next_id + 1', 36 ' }', 37 ' return event_name_to_id_map[name]', 38 '}', 39 'probe begin', 40 '{', 41 ' printf("%%8b%%8b%%8b", 0xffffffffffffffff, 0xf2b177cb0aa429b4, 4)', 42 '}', 43 '') 44 45 for event_id, e in enumerate(events): 46 if 'disable' in e.properties: 47 continue 48 49 out('probe %(probeprefix)s.simpletrace.%(name)s = %(probeprefix)s.%(name)s ?', 50 '{', 51 ' id = simple_trace_map_event("%(name)s")', 52 probeprefix=probeprefix(), 53 name=e.name) 54 55 # Calculate record size 56 sizes = ['24'] # sizeof(TraceRecord) 57 for type_, name in e.args: 58 name = stap_escape(name) 59 if is_string(type_): 60 out(' try {', 61 ' arg%(name)s_str = %(name)s ? user_string_n(%(name)s, 512) : "<null>"', 62 ' } catch {}', 63 ' arg%(name)s_len = strlen(arg%(name)s_str)', 64 name=name) 65 sizes.append('4 + arg%s_len' % name) 66 else: 67 sizes.append('8') 68 sizestr = ' + '.join(sizes) 69 70 # Generate format string and value pairs for record header and arguments 71 fields = [('8b', 'id'), 72 ('8b', 'gettimeofday_ns()'), 73 ('4b', sizestr), 74 ('4b', 'pid()')] 75 for type_, name in e.args: 76 name = stap_escape(name) 77 if is_string(type_): 78 fields.extend([('4b', 'arg%s_len' % name), 79 ('.*s', 'arg%s_len, arg%s_str' % (name, name))]) 80 else: 81 fields.append(('8b', name)) 82 83 # Emit the entire record in a single SystemTap printf() 84 fmt_str = '%'.join(fmt for fmt, _ in fields) 85 arg_str = ', '.join(arg for _, arg in fields) 86 out(' printf("%%8b%%%(fmt_str)s", 1, %(arg_str)s)', 87 fmt_str=fmt_str, arg_str=arg_str) 88 89 out('}') 90 91 out() 92