|
|
1.1 ! root 1: #!/usr/bin/env python ! 2: # ! 3: # Pretty-printer for simple trace backend binary trace files ! 4: # ! 5: # Copyright IBM, Corp. 2010 ! 6: # ! 7: # This work is licensed under the terms of the GNU GPL, version 2. See ! 8: # the COPYING file in the top-level directory. ! 9: # ! 10: # For help see docs/tracing.txt ! 11: ! 12: import sys ! 13: import struct ! 14: import re ! 15: ! 16: header_event_id = 0xffffffffffffffff ! 17: header_magic = 0xf2b177cb0aa429b4 ! 18: header_version = 0 ! 19: ! 20: trace_fmt = '=QQQQQQQQ' ! 21: trace_len = struct.calcsize(trace_fmt) ! 22: event_re = re.compile(r'(disable\s+)?([a-zA-Z0-9_]+)\(([^)]*)\).*') ! 23: ! 24: def err(msg): ! 25: sys.stderr.write(msg + '\n') ! 26: sys.exit(1) ! 27: ! 28: def parse_events(fobj): ! 29: """Parse a trace-events file.""" ! 30: ! 31: def get_argnames(args): ! 32: """Extract argument names from a parameter list.""" ! 33: return tuple(arg.split()[-1].lstrip('*') for arg in args.split(',')) ! 34: ! 35: events = {} ! 36: event_num = 0 ! 37: for line in fobj: ! 38: m = event_re.match(line.strip()) ! 39: if m is None: ! 40: continue ! 41: ! 42: disable, name, args = m.groups() ! 43: events[event_num] = (name,) + get_argnames(args) ! 44: event_num += 1 ! 45: return events ! 46: ! 47: def read_record(fobj): ! 48: """Deserialize a trace record from a file.""" ! 49: s = fobj.read(trace_len) ! 50: if len(s) != trace_len: ! 51: return None ! 52: return struct.unpack(trace_fmt, s) ! 53: ! 54: def read_trace_file(fobj): ! 55: """Deserialize trace records from a file.""" ! 56: header = read_record(fobj) ! 57: if header is None or \ ! 58: header[0] != header_event_id or \ ! 59: header[1] != header_magic or \ ! 60: header[2] != header_version: ! 61: err('not a trace file or incompatible version') ! 62: ! 63: while True: ! 64: rec = read_record(fobj) ! 65: if rec is None: ! 66: break ! 67: ! 68: yield rec ! 69: ! 70: class Formatter(object): ! 71: def __init__(self, events): ! 72: self.events = events ! 73: self.last_timestamp = None ! 74: ! 75: def format_record(self, rec): ! 76: if self.last_timestamp is None: ! 77: self.last_timestamp = rec[1] ! 78: delta_ns = rec[1] - self.last_timestamp ! 79: self.last_timestamp = rec[1] ! 80: ! 81: event = self.events[rec[0]] ! 82: fields = [event[0], '%0.3f' % (delta_ns / 1000.0)] ! 83: for i in xrange(1, len(event)): ! 84: fields.append('%s=0x%x' % (event[i], rec[i + 1])) ! 85: return ' '.join(fields) ! 86: ! 87: if len(sys.argv) != 3: ! 88: err('usage: %s <trace-events> <trace-file>' % sys.argv[0]) ! 89: ! 90: events = parse_events(open(sys.argv[1], 'r')) ! 91: formatter = Formatter(events) ! 92: for rec in read_trace_file(open(sys.argv[2], 'rb')): ! 93: print formatter.format_record(rec)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.