1#!/usr/bin/python3 2# -*- coding: UTF-8 -*- 3 4import os 5import re 6import sys 7import string 8import signal 9import struct 10import getopt 11 12def usage(): 13 print >> sys.stderr, \ 14 """ 15 Usage: 16 acrntrace_format.py [options] [formats] [trace_data] 17 18 [options] 19 -h: print this message 20 21 Parses trace_data in binary format generated by acrntrace and 22 reformats it according to the rules in the [formats] file. 23 The rules in formats should have the format ({ and } show grouping 24 and are not part of the syntax): 25 26 {event_id}{whitespace}{text format string} 27 28 The textual format string may include format specifiers, such as 29 %(cpu)d, %(tsc)d, %(event)d, %(1)d, %(2)d, .... 30 The 'd' format specifier outputs in decimal, alternatively 'x' will 31 output in hexadecimal and 'o' will output in octal. 32 33 These respectively correspond to the CPU number (cpu), timestamp 34 counter (tsc), event ID (event) and the data logged in the trace file. 35 There can be only one such rule for each type of event. 36 """ 37 38def read_format(format_file): 39 formats = {} 40 41 fd = open(format_file) 42 43 reg = re.compile('(\S+)\s+(\S.*)') 44 45 while True: 46 line = fd.readline() 47 if not line: 48 break 49 50 if line[0] == '#' or line[0] == '\n': 51 continue 52 53 m = reg.match(line) 54 55 if not m: print >> sys.stderr, "Wrong format file"; sys.exit(1) 56 57 formats[str(eval(m.group(1)))] = m.group(2) 58 59 return formats 60 61exit = 0 62 63# structure of trace data (as output by acrntrace) 64# TSC(Q) HDR(Q) D1 D2 ... 65# HDR consists of event:48:, n_data:8:, cpu:8: 66# event means Event ID 67# n_data means number of data in trace entry (like D1, D2, ...) 68# cpu means cpu id this trace entry belong to 69TSCREC = "Q" 70HDRREC = "Q" 71D2REC = "QQ" 72D4REC = "IIII" 73D8REC = "BBBBBBBBBBBBBBBB" 74D16REC = "bbbbbbbbbbbbbbbb" 75 76def main_loop(formats, fd): 77 global exit 78 i = 0 79 80 81 while not exit: 82 try: 83 i = i + 1 84 85 line = fd.read(struct.calcsize(TSCREC)) 86 if not line: 87 break 88 tsc = struct.unpack(TSCREC, line)[0] 89 90 line = fd.read(struct.calcsize(HDRREC)) 91 if not line: 92 break 93 event = struct.unpack(HDRREC, line)[0] 94 n_data = event >> 48 & 0xff 95 cpu = event >> 56 96 event = event & 0xffffffffffff 97 98 d1 = 0 99 d2 = 0 100 d3 = 0 101 d4 = 0 102 d5 = 0 103 d6 = 0 104 d7 = 0 105 d8 = 0 106 d9 = 0 107 d10 = 0 108 d11 = 0 109 d12 = 0 110 d13 = 0 111 d14 = 0 112 d15 = 0 113 d16 = 0 114 115 if n_data == 2: 116 line = fd.read(struct.calcsize(D2REC)) 117 if not line: 118 break 119 (d1, d2) = struct.unpack(D2REC, line) 120 121 if n_data == 4: 122 line = fd.read(struct.calcsize(D4REC)) 123 if not line: 124 break 125 (d1, d2, d3, d4) = struct.unpack(D4REC, line) 126 127 if n_data == 8: 128 line = fd.read(struct.calcsize(D8REC)) 129 if not line: 130 break 131 # TRACE_6C using the first 6 data of fields_8. Actaully we have 132 # 16 data in every trace entry. 133 (d1, d2, d3, d4, d5, d6, d7, d8, 134 d9, d10, d11, d12, d13, d14, d15, d16) = struct.unpack(D8REC, line) 135 136 if n_data == 16: 137 line = fd.read(struct.calcsize(D16REC)) 138 if not line: 139 break 140 141 (d1, d2, d3, d4, d5, d6, d7, d8, 142 d9, d10, d11, d12, d13, d14, d15, d16) = struct.unpack(D16REC, line) 143 144 args = {'cpu' : cpu, 145 'tsc' : tsc, 146 'event' : event, 147 '1' : d1, 148 '2' : d2, 149 '3' : d3, 150 '4' : d4, 151 '5' : d5, 152 '6' : d6, 153 '7' : d7, 154 '8' : d8, 155 '9' : d9, 156 '10' : d10, 157 '11' : d11, 158 '12' : d12, 159 '13' : d13, 160 '14' : d14, 161 '15' : d15, 162 '16' : d16 } 163 164 try: 165 if str(event) in formats.keys(): 166 print (formats[str(event)] % args) 167 except TypeError: 168 if str(event) in formats.key(): 169 print (formats[str(event)]) 170 print (args) 171 172 except struct.error: 173 sys.exit() 174 175def main(argv): 176 try: 177 opts, arg = getopt.getopt(sys.argv[1:], "h") 178 179 for opt in opts: 180 if opt[0] == '-h': 181 usage() 182 sys.exit() 183 184 except getopt.GetoptError: 185 usage() 186 sys.exit(1) 187 188 try: 189 formats = read_format(arg[0]) 190 fd = open(arg[1], 'rb') 191 except IOError: 192 sys.exit(1) 193 194 main_loop(formats, fd) 195 196if __name__ == "__main__": 197 main(sys.argv[1:]) 198