ia64/xen-unstable

view tools/xentrace/xentrace_format @ 16389:270bd0fc3669

xentrace: Fix TypeError handling of xentrace_format.
Signed-off-by: Yosuke Iwamatsu <y-iwamatsu@ab.jp.nec.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Nov 16 17:05:20 2007 +0000 (2007-11-16)
parents ff99e8da117f
children 62c38443e9f7
line source
1 #!/usr/bin/env python
3 # by Mark Williamson, (C) 2004 Intel Research Cambridge
5 # Program for reformatting trace buffer output according to user-supplied rules
7 import re, sys, string, signal, struct, os, getopt
9 def usage():
10 print >> sys.stderr, \
11 "Usage: " + sys.argv[0] + """ defs-file
12 Parses trace data in binary format, as output by Xentrace and
13 reformats it according to the rules in a file of definitions. The
14 rules in this file should have the format ({ and } show grouping
15 and are not part of the syntax):
17 {event_id}{whitespace}{text format string}
19 The textual format string may include format specifiers, such as:
20 %(cpu)d, %(tsc)d, %(event)d, %(1)d, %(2)d, %(3)d, %(4)d, %(5)d
21 [ the 'd' format specifier outputs in decimal, alternatively 'x'
22 will output in hexadecimal and 'o' will output in octal ]
24 Which correspond to the CPU number, event ID, timestamp counter and
25 the 5 data fields from the trace record. There should be one such
26 rule for each type of event.
28 Depending on your system and the volume of trace buffer data,
29 this script may not be able to keep up with the output of xentrace
30 if it is piped directly. In these circumstances you should have
31 xentrace output to a file for processing off-line.
32 """
33 sys.exit(1)
35 def read_defs(defs_file):
36 defs = {}
38 fd = open(defs_file)
40 reg = re.compile('(\S+)\s+(\S.*)')
42 while True:
43 line = fd.readline()
44 if not line:
45 break
47 if line[0] == '#' or line[0] == '\n':
48 continue
50 m = reg.match(line)
52 if not m: print >> sys.stderr, "Bad format file" ; sys.exit(1)
54 defs[str(eval(m.group(1)))] = m.group(2)
56 return defs
58 def sighand(x,y):
59 global interrupted
60 interrupted = 1
62 ##### Main code
64 mhz = 0
66 if len(sys.argv) < 2:
67 usage()
69 try:
70 opts, arg = getopt.getopt(sys.argv[1:], "c:" )
72 for opt in opts:
73 if opt[0] == '-c' : mhz = int(opt[1])
75 except getopt.GetoptError:
76 usage()
78 signal.signal(signal.SIGTERM, sighand)
79 signal.signal(signal.SIGHUP, sighand)
80 signal.signal(signal.SIGINT, sighand)
82 interrupted = 0
84 defs = read_defs(arg[0])
86 # structure of trace record (as output by xentrace):
87 # HDR(I) {TSC(Q)} D1(I) D2(I) D3(I) D4(I) D5(I)
88 #
89 # HDR consists of EVENT:28:, n_data:3:, tsc_in:1:
90 # EVENT means Event ID
91 # n_data means number of data (like D1, D2, ...)
92 # tsc_in means TSC data exists(1) or not(0).
93 # if tsc_in == 0, TSC(Q) does not exists.
94 #
95 # CPU ID exists on trace data of EVENT=0x0001f003
96 #
97 HDRREC = "I"
98 TSCREC = "Q"
99 D1REC = "I"
100 D2REC = "II"
101 D3REC = "III"
102 D4REC = "IIII"
103 D5REC = "IIIII"
105 last_tsc = [0]
107 i=0
109 while not interrupted:
110 try:
111 i=i+1
112 line = sys.stdin.read(struct.calcsize(HDRREC))
113 if not line:
114 break
115 event = struct.unpack(HDRREC, line)[0]
116 n_data = event >> 28 & 0x7
117 tsc_in = event >> 31
119 d1 = 0
120 d2 = 0
121 d3 = 0
122 d4 = 0
123 d5 = 0
125 tsc = 0
127 if tsc_in == 1:
128 line = sys.stdin.read(struct.calcsize(TSCREC))
129 if not line:
130 break
131 tsc = struct.unpack(TSCREC, line)[0]
133 if n_data == 1:
134 line = sys.stdin.read(struct.calcsize(D1REC))
135 if not line:
136 break
137 (d1) = struct.unpack(D1REC, line)
138 if n_data == 2:
139 line = sys.stdin.read(struct.calcsize(D2REC))
140 if not line:
141 break
142 (d1, d2) = struct.unpack(D2REC, line)
143 if n_data == 3:
144 line = sys.stdin.read(struct.calcsize(D3REC))
145 if not line:
146 break
147 (d1, d2, d3) = struct.unpack(D3REC, line)
148 if n_data == 4:
149 line = sys.stdin.read(struct.calcsize(D4REC))
150 if not line:
151 break
152 (d1, d2, d3, d4) = struct.unpack(D4REC, line)
153 if n_data == 5:
154 line = sys.stdin.read(struct.calcsize(D5REC))
155 if not line:
156 break
157 (d1, d2, d3, d4, d5) = struct.unpack(D5REC, line)
159 # Event field is 28bit of 'uint32_t' in header, not 'long'.
160 event &= 0x0fffffff
161 if event == 0x1f003:
162 cpu = d1
165 #tsc = (tscH<<32) | tscL
167 #print i, tsc
169 if cpu >= len(last_tsc):
170 last_tsc += [0] * (cpu - len(last_tsc) + 1)
171 elif tsc < last_tsc[cpu] and tsc_in == 1:
172 print "TSC stepped backward cpu %d ! %d %d" % (cpu,tsc,last_tsc[cpu])
174 # provide relative TSC
175 if last_tsc[cpu] > 0 and tsc_in == 1:
176 reltsc = tsc - last_tsc[cpu]
177 else:
178 reltsc = 0
180 if tsc_in == 1:
181 last_tsc[cpu] = tsc
183 if mhz:
184 tsc = tsc / (mhz*1000000.0)
186 args = {'cpu' : cpu,
187 'tsc' : tsc,
188 'event' : event,
189 'reltsc': reltsc,
190 '1' : d1,
191 '2' : d2,
192 '3' : d3,
193 '4' : d4,
194 '5' : d5 }
196 try:
198 if defs.has_key(str(event)):
199 print defs[str(event)] % args
200 else:
201 if defs.has_key(str(0)): print defs[str(0)] % args
202 except TypeError:
203 if defs.has_key(str(event)):
204 print defs[str(event)]
205 print args
206 else:
207 if defs.has_key(str(0)):
208 print defs[str(0)]
209 print args
212 except IOError, struct.error: sys.exit()