diff options
Diffstat (limited to 'tools/perf/util/trace-event-read.c')
-rw-r--r-- | tools/perf/util/trace-event-read.c | 473 |
1 files changed, 177 insertions, 296 deletions
diff --git a/tools/perf/util/trace-event-read.c b/tools/perf/util/trace-event-read.c index 3741572696af..af215c0d2379 100644 --- a/tools/perf/util/trace-event-read.c +++ b/tools/perf/util/trace-event-read.c | |||
@@ -18,8 +18,6 @@ | |||
18 | * | 18 | * |
19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
20 | */ | 20 | */ |
21 | #define _FILE_OFFSET_BITS 64 | ||
22 | |||
23 | #include <dirent.h> | 21 | #include <dirent.h> |
24 | #include <stdio.h> | 22 | #include <stdio.h> |
25 | #include <stdlib.h> | 23 | #include <stdlib.h> |
@@ -41,26 +39,14 @@ | |||
41 | 39 | ||
42 | static int input_fd; | 40 | static int input_fd; |
43 | 41 | ||
44 | static int read_page; | ||
45 | |||
46 | int file_bigendian; | 42 | int file_bigendian; |
47 | int host_bigendian; | 43 | int host_bigendian; |
48 | static int long_size; | 44 | static int long_size; |
49 | 45 | ||
50 | static ssize_t calc_data_size; | 46 | static ssize_t trace_data_size; |
51 | static bool repipe; | 47 | static bool repipe; |
52 | 48 | ||
53 | static void *malloc_or_die(int size) | 49 | static int __do_read(int fd, void *buf, int size) |
54 | { | ||
55 | void *ret; | ||
56 | |||
57 | ret = malloc(size); | ||
58 | if (!ret) | ||
59 | die("malloc"); | ||
60 | return ret; | ||
61 | } | ||
62 | |||
63 | static int do_read(int fd, void *buf, int size) | ||
64 | { | 50 | { |
65 | int rsize = size; | 51 | int rsize = size; |
66 | 52 | ||
@@ -73,8 +59,10 @@ static int do_read(int fd, void *buf, int size) | |||
73 | if (repipe) { | 59 | if (repipe) { |
74 | int retw = write(STDOUT_FILENO, buf, ret); | 60 | int retw = write(STDOUT_FILENO, buf, ret); |
75 | 61 | ||
76 | if (retw <= 0 || retw != ret) | 62 | if (retw <= 0 || retw != ret) { |
77 | die("repiping input file"); | 63 | pr_debug("repiping input file"); |
64 | return -1; | ||
65 | } | ||
78 | } | 66 | } |
79 | 67 | ||
80 | size -= ret; | 68 | size -= ret; |
@@ -84,17 +72,18 @@ static int do_read(int fd, void *buf, int size) | |||
84 | return rsize; | 72 | return rsize; |
85 | } | 73 | } |
86 | 74 | ||
87 | static int read_or_die(void *data, int size) | 75 | static int do_read(void *data, int size) |
88 | { | 76 | { |
89 | int r; | 77 | int r; |
90 | 78 | ||
91 | r = do_read(input_fd, data, size); | 79 | r = __do_read(input_fd, data, size); |
92 | if (r <= 0) | 80 | if (r <= 0) { |
93 | die("reading input file (size expected=%d received=%d)", | 81 | pr_debug("reading input file (size expected=%d received=%d)", |
94 | size, r); | 82 | size, r); |
83 | return -1; | ||
84 | } | ||
95 | 85 | ||
96 | if (calc_data_size) | 86 | trace_data_size += r; |
97 | calc_data_size += r; | ||
98 | 87 | ||
99 | return r; | 88 | return r; |
100 | } | 89 | } |
@@ -107,7 +96,7 @@ static void skip(int size) | |||
107 | 96 | ||
108 | while (size) { | 97 | while (size) { |
109 | r = size > BUFSIZ ? BUFSIZ : size; | 98 | r = size > BUFSIZ ? BUFSIZ : size; |
110 | read_or_die(buf, r); | 99 | do_read(buf, r); |
111 | size -= r; | 100 | size -= r; |
112 | }; | 101 | }; |
113 | } | 102 | } |
@@ -116,7 +105,8 @@ static unsigned int read4(struct pevent *pevent) | |||
116 | { | 105 | { |
117 | unsigned int data; | 106 | unsigned int data; |
118 | 107 | ||
119 | read_or_die(&data, 4); | 108 | if (do_read(&data, 4) < 0) |
109 | return 0; | ||
120 | return __data2host4(pevent, data); | 110 | return __data2host4(pevent, data); |
121 | } | 111 | } |
122 | 112 | ||
@@ -124,7 +114,8 @@ static unsigned long long read8(struct pevent *pevent) | |||
124 | { | 114 | { |
125 | unsigned long long data; | 115 | unsigned long long data; |
126 | 116 | ||
127 | read_or_die(&data, 8); | 117 | if (do_read(&data, 8) < 0) |
118 | return 0; | ||
128 | return __data2host8(pevent, data); | 119 | return __data2host8(pevent, data); |
129 | } | 120 | } |
130 | 121 | ||
@@ -138,17 +129,23 @@ static char *read_string(void) | |||
138 | 129 | ||
139 | for (;;) { | 130 | for (;;) { |
140 | r = read(input_fd, &c, 1); | 131 | r = read(input_fd, &c, 1); |
141 | if (r < 0) | 132 | if (r < 0) { |
142 | die("reading input file"); | 133 | pr_debug("reading input file"); |
134 | goto out; | ||
135 | } | ||
143 | 136 | ||
144 | if (!r) | 137 | if (!r) { |
145 | die("no data"); | 138 | pr_debug("no data"); |
139 | goto out; | ||
140 | } | ||
146 | 141 | ||
147 | if (repipe) { | 142 | if (repipe) { |
148 | int retw = write(STDOUT_FILENO, &c, 1); | 143 | int retw = write(STDOUT_FILENO, &c, 1); |
149 | 144 | ||
150 | if (retw <= 0 || retw != r) | 145 | if (retw <= 0 || retw != r) { |
151 | die("repiping input file string"); | 146 | pr_debug("repiping input file string"); |
147 | goto out; | ||
148 | } | ||
152 | } | 149 | } |
153 | 150 | ||
154 | buf[size++] = c; | 151 | buf[size++] = c; |
@@ -157,60 +154,79 @@ static char *read_string(void) | |||
157 | break; | 154 | break; |
158 | } | 155 | } |
159 | 156 | ||
160 | if (calc_data_size) | 157 | trace_data_size += size; |
161 | calc_data_size += size; | ||
162 | |||
163 | str = malloc_or_die(size); | ||
164 | memcpy(str, buf, size); | ||
165 | 158 | ||
159 | str = malloc(size); | ||
160 | if (str) | ||
161 | memcpy(str, buf, size); | ||
162 | out: | ||
166 | return str; | 163 | return str; |
167 | } | 164 | } |
168 | 165 | ||
169 | static void read_proc_kallsyms(struct pevent *pevent) | 166 | static int read_proc_kallsyms(struct pevent *pevent) |
170 | { | 167 | { |
171 | unsigned int size; | 168 | unsigned int size; |
172 | char *buf; | 169 | char *buf; |
173 | 170 | ||
174 | size = read4(pevent); | 171 | size = read4(pevent); |
175 | if (!size) | 172 | if (!size) |
176 | return; | 173 | return 0; |
174 | |||
175 | buf = malloc(size + 1); | ||
176 | if (buf == NULL) | ||
177 | return -1; | ||
177 | 178 | ||
178 | buf = malloc_or_die(size + 1); | 179 | if (do_read(buf, size) < 0) { |
179 | read_or_die(buf, size); | 180 | free(buf); |
181 | return -1; | ||
182 | } | ||
180 | buf[size] = '\0'; | 183 | buf[size] = '\0'; |
181 | 184 | ||
182 | parse_proc_kallsyms(pevent, buf, size); | 185 | parse_proc_kallsyms(pevent, buf, size); |
183 | 186 | ||
184 | free(buf); | 187 | free(buf); |
188 | return 0; | ||
185 | } | 189 | } |
186 | 190 | ||
187 | static void read_ftrace_printk(struct pevent *pevent) | 191 | static int read_ftrace_printk(struct pevent *pevent) |
188 | { | 192 | { |
189 | unsigned int size; | 193 | unsigned int size; |
190 | char *buf; | 194 | char *buf; |
191 | 195 | ||
196 | /* it can have 0 size */ | ||
192 | size = read4(pevent); | 197 | size = read4(pevent); |
193 | if (!size) | 198 | if (!size) |
194 | return; | 199 | return 0; |
200 | |||
201 | buf = malloc(size); | ||
202 | if (buf == NULL) | ||
203 | return -1; | ||
195 | 204 | ||
196 | buf = malloc_or_die(size); | 205 | if (do_read(buf, size) < 0) { |
197 | read_or_die(buf, size); | 206 | free(buf); |
207 | return -1; | ||
208 | } | ||
198 | 209 | ||
199 | parse_ftrace_printk(pevent, buf, size); | 210 | parse_ftrace_printk(pevent, buf, size); |
200 | 211 | ||
201 | free(buf); | 212 | free(buf); |
213 | return 0; | ||
202 | } | 214 | } |
203 | 215 | ||
204 | static void read_header_files(struct pevent *pevent) | 216 | static int read_header_files(struct pevent *pevent) |
205 | { | 217 | { |
206 | unsigned long long size; | 218 | unsigned long long size; |
207 | char *header_event; | 219 | char *header_event; |
208 | char buf[BUFSIZ]; | 220 | char buf[BUFSIZ]; |
221 | int ret = 0; | ||
209 | 222 | ||
210 | read_or_die(buf, 12); | 223 | if (do_read(buf, 12) < 0) |
224 | return -1; | ||
211 | 225 | ||
212 | if (memcmp(buf, "header_page", 12) != 0) | 226 | if (memcmp(buf, "header_page", 12) != 0) { |
213 | die("did not read header page"); | 227 | pr_debug("did not read header page"); |
228 | return -1; | ||
229 | } | ||
214 | 230 | ||
215 | size = read8(pevent); | 231 | size = read8(pevent); |
216 | skip(size); | 232 | skip(size); |
@@ -221,269 +237,107 @@ static void read_header_files(struct pevent *pevent) | |||
221 | */ | 237 | */ |
222 | long_size = header_page_size_size; | 238 | long_size = header_page_size_size; |
223 | 239 | ||
224 | read_or_die(buf, 13); | 240 | if (do_read(buf, 13) < 0) |
225 | if (memcmp(buf, "header_event", 13) != 0) | 241 | return -1; |
226 | die("did not read header event"); | 242 | |
243 | if (memcmp(buf, "header_event", 13) != 0) { | ||
244 | pr_debug("did not read header event"); | ||
245 | return -1; | ||
246 | } | ||
227 | 247 | ||
228 | size = read8(pevent); | 248 | size = read8(pevent); |
229 | header_event = malloc_or_die(size); | 249 | header_event = malloc(size); |
230 | read_or_die(header_event, size); | 250 | if (header_event == NULL) |
251 | return -1; | ||
252 | |||
253 | if (do_read(header_event, size) < 0) | ||
254 | ret = -1; | ||
255 | |||
231 | free(header_event); | 256 | free(header_event); |
257 | return ret; | ||
232 | } | 258 | } |
233 | 259 | ||
234 | static void read_ftrace_file(struct pevent *pevent, unsigned long long size) | 260 | static int read_ftrace_file(struct pevent *pevent, unsigned long long size) |
235 | { | 261 | { |
236 | char *buf; | 262 | char *buf; |
237 | 263 | ||
238 | buf = malloc_or_die(size); | 264 | buf = malloc(size); |
239 | read_or_die(buf, size); | 265 | if (buf == NULL) |
266 | return -1; | ||
267 | |||
268 | if (do_read(buf, size) < 0) { | ||
269 | free(buf); | ||
270 | return -1; | ||
271 | } | ||
272 | |||
240 | parse_ftrace_file(pevent, buf, size); | 273 | parse_ftrace_file(pevent, buf, size); |
241 | free(buf); | 274 | free(buf); |
275 | return 0; | ||
242 | } | 276 | } |
243 | 277 | ||
244 | static void read_event_file(struct pevent *pevent, char *sys, | 278 | static int read_event_file(struct pevent *pevent, char *sys, |
245 | unsigned long long size) | 279 | unsigned long long size) |
246 | { | 280 | { |
247 | char *buf; | 281 | char *buf; |
248 | 282 | ||
249 | buf = malloc_or_die(size); | 283 | buf = malloc(size); |
250 | read_or_die(buf, size); | 284 | if (buf == NULL) |
285 | return -1; | ||
286 | |||
287 | if (do_read(buf, size) < 0) { | ||
288 | free(buf); | ||
289 | return -1; | ||
290 | } | ||
291 | |||
251 | parse_event_file(pevent, buf, size, sys); | 292 | parse_event_file(pevent, buf, size, sys); |
252 | free(buf); | 293 | free(buf); |
294 | return 0; | ||
253 | } | 295 | } |
254 | 296 | ||
255 | static void read_ftrace_files(struct pevent *pevent) | 297 | static int read_ftrace_files(struct pevent *pevent) |
256 | { | 298 | { |
257 | unsigned long long size; | 299 | unsigned long long size; |
258 | int count; | 300 | int count; |
259 | int i; | 301 | int i; |
302 | int ret; | ||
260 | 303 | ||
261 | count = read4(pevent); | 304 | count = read4(pevent); |
262 | 305 | ||
263 | for (i = 0; i < count; i++) { | 306 | for (i = 0; i < count; i++) { |
264 | size = read8(pevent); | 307 | size = read8(pevent); |
265 | read_ftrace_file(pevent, size); | 308 | ret = read_ftrace_file(pevent, size); |
309 | if (ret) | ||
310 | return ret; | ||
266 | } | 311 | } |
312 | return 0; | ||
267 | } | 313 | } |
268 | 314 | ||
269 | static void read_event_files(struct pevent *pevent) | 315 | static int read_event_files(struct pevent *pevent) |
270 | { | 316 | { |
271 | unsigned long long size; | 317 | unsigned long long size; |
272 | char *sys; | 318 | char *sys; |
273 | int systems; | 319 | int systems; |
274 | int count; | 320 | int count; |
275 | int i,x; | 321 | int i,x; |
322 | int ret; | ||
276 | 323 | ||
277 | systems = read4(pevent); | 324 | systems = read4(pevent); |
278 | 325 | ||
279 | for (i = 0; i < systems; i++) { | 326 | for (i = 0; i < systems; i++) { |
280 | sys = read_string(); | 327 | sys = read_string(); |
328 | if (sys == NULL) | ||
329 | return -1; | ||
281 | 330 | ||
282 | count = read4(pevent); | 331 | count = read4(pevent); |
332 | |||
283 | for (x=0; x < count; x++) { | 333 | for (x=0; x < count; x++) { |
284 | size = read8(pevent); | 334 | size = read8(pevent); |
285 | read_event_file(pevent, sys, size); | 335 | ret = read_event_file(pevent, sys, size); |
336 | if (ret) | ||
337 | return ret; | ||
286 | } | 338 | } |
287 | } | 339 | } |
288 | } | 340 | return 0; |
289 | |||
290 | struct cpu_data { | ||
291 | unsigned long long offset; | ||
292 | unsigned long long size; | ||
293 | unsigned long long timestamp; | ||
294 | struct pevent_record *next; | ||
295 | char *page; | ||
296 | int cpu; | ||
297 | int index; | ||
298 | int page_size; | ||
299 | }; | ||
300 | |||
301 | static struct cpu_data *cpu_data; | ||
302 | |||
303 | static void update_cpu_data_index(int cpu) | ||
304 | { | ||
305 | cpu_data[cpu].offset += page_size; | ||
306 | cpu_data[cpu].size -= page_size; | ||
307 | cpu_data[cpu].index = 0; | ||
308 | } | ||
309 | |||
310 | static void get_next_page(int cpu) | ||
311 | { | ||
312 | off_t save_seek; | ||
313 | off_t ret; | ||
314 | |||
315 | if (!cpu_data[cpu].page) | ||
316 | return; | ||
317 | |||
318 | if (read_page) { | ||
319 | if (cpu_data[cpu].size <= page_size) { | ||
320 | free(cpu_data[cpu].page); | ||
321 | cpu_data[cpu].page = NULL; | ||
322 | return; | ||
323 | } | ||
324 | |||
325 | update_cpu_data_index(cpu); | ||
326 | |||
327 | /* other parts of the code may expect the pointer to not move */ | ||
328 | save_seek = lseek(input_fd, 0, SEEK_CUR); | ||
329 | |||
330 | ret = lseek(input_fd, cpu_data[cpu].offset, SEEK_SET); | ||
331 | if (ret == (off_t)-1) | ||
332 | die("failed to lseek"); | ||
333 | ret = read(input_fd, cpu_data[cpu].page, page_size); | ||
334 | if (ret < 0) | ||
335 | die("failed to read page"); | ||
336 | |||
337 | /* reset the file pointer back */ | ||
338 | lseek(input_fd, save_seek, SEEK_SET); | ||
339 | |||
340 | return; | ||
341 | } | ||
342 | |||
343 | munmap(cpu_data[cpu].page, page_size); | ||
344 | cpu_data[cpu].page = NULL; | ||
345 | |||
346 | if (cpu_data[cpu].size <= page_size) | ||
347 | return; | ||
348 | |||
349 | update_cpu_data_index(cpu); | ||
350 | |||
351 | cpu_data[cpu].page = mmap(NULL, page_size, PROT_READ, MAP_PRIVATE, | ||
352 | input_fd, cpu_data[cpu].offset); | ||
353 | if (cpu_data[cpu].page == MAP_FAILED) | ||
354 | die("failed to mmap cpu %d at offset 0x%llx", | ||
355 | cpu, cpu_data[cpu].offset); | ||
356 | } | ||
357 | |||
358 | static unsigned int type_len4host(unsigned int type_len_ts) | ||
359 | { | ||
360 | if (file_bigendian) | ||
361 | return (type_len_ts >> 27) & ((1 << 5) - 1); | ||
362 | else | ||
363 | return type_len_ts & ((1 << 5) - 1); | ||
364 | } | ||
365 | |||
366 | static unsigned int ts4host(unsigned int type_len_ts) | ||
367 | { | ||
368 | if (file_bigendian) | ||
369 | return type_len_ts & ((1 << 27) - 1); | ||
370 | else | ||
371 | return type_len_ts >> 5; | ||
372 | } | ||
373 | |||
374 | static int calc_index(void *ptr, int cpu) | ||
375 | { | ||
376 | return (unsigned long)ptr - (unsigned long)cpu_data[cpu].page; | ||
377 | } | ||
378 | |||
379 | struct pevent_record *trace_peek_data(struct pevent *pevent, int cpu) | ||
380 | { | ||
381 | struct pevent_record *data; | ||
382 | void *page = cpu_data[cpu].page; | ||
383 | int idx = cpu_data[cpu].index; | ||
384 | void *ptr = page + idx; | ||
385 | unsigned long long extend; | ||
386 | unsigned int type_len_ts; | ||
387 | unsigned int type_len; | ||
388 | unsigned int delta; | ||
389 | unsigned int length = 0; | ||
390 | |||
391 | if (cpu_data[cpu].next) | ||
392 | return cpu_data[cpu].next; | ||
393 | |||
394 | if (!page) | ||
395 | return NULL; | ||
396 | |||
397 | if (!idx) { | ||
398 | /* FIXME: handle header page */ | ||
399 | if (header_page_ts_size != 8) | ||
400 | die("expected a long long type for timestamp"); | ||
401 | cpu_data[cpu].timestamp = data2host8(pevent, ptr); | ||
402 | ptr += 8; | ||
403 | switch (header_page_size_size) { | ||
404 | case 4: | ||
405 | cpu_data[cpu].page_size = data2host4(pevent, ptr); | ||
406 | ptr += 4; | ||
407 | break; | ||
408 | case 8: | ||
409 | cpu_data[cpu].page_size = data2host8(pevent, ptr); | ||
410 | ptr += 8; | ||
411 | break; | ||
412 | default: | ||
413 | die("bad long size"); | ||
414 | } | ||
415 | ptr = cpu_data[cpu].page + header_page_data_offset; | ||
416 | } | ||
417 | |||
418 | read_again: | ||
419 | idx = calc_index(ptr, cpu); | ||
420 | |||
421 | if (idx >= cpu_data[cpu].page_size) { | ||
422 | get_next_page(cpu); | ||
423 | return trace_peek_data(pevent, cpu); | ||
424 | } | ||
425 | |||
426 | type_len_ts = data2host4(pevent, ptr); | ||
427 | ptr += 4; | ||
428 | |||
429 | type_len = type_len4host(type_len_ts); | ||
430 | delta = ts4host(type_len_ts); | ||
431 | |||
432 | switch (type_len) { | ||
433 | case RINGBUF_TYPE_PADDING: | ||
434 | if (!delta) | ||
435 | die("error, hit unexpected end of page"); | ||
436 | length = data2host4(pevent, ptr); | ||
437 | ptr += 4; | ||
438 | length *= 4; | ||
439 | ptr += length; | ||
440 | goto read_again; | ||
441 | |||
442 | case RINGBUF_TYPE_TIME_EXTEND: | ||
443 | extend = data2host4(pevent, ptr); | ||
444 | ptr += 4; | ||
445 | extend <<= TS_SHIFT; | ||
446 | extend += delta; | ||
447 | cpu_data[cpu].timestamp += extend; | ||
448 | goto read_again; | ||
449 | |||
450 | case RINGBUF_TYPE_TIME_STAMP: | ||
451 | ptr += 12; | ||
452 | break; | ||
453 | case 0: | ||
454 | length = data2host4(pevent, ptr); | ||
455 | ptr += 4; | ||
456 | die("here! length=%d", length); | ||
457 | break; | ||
458 | default: | ||
459 | length = type_len * 4; | ||
460 | break; | ||
461 | } | ||
462 | |||
463 | cpu_data[cpu].timestamp += delta; | ||
464 | |||
465 | data = malloc_or_die(sizeof(*data)); | ||
466 | memset(data, 0, sizeof(*data)); | ||
467 | |||
468 | data->ts = cpu_data[cpu].timestamp; | ||
469 | data->size = length; | ||
470 | data->data = ptr; | ||
471 | ptr += length; | ||
472 | |||
473 | cpu_data[cpu].index = calc_index(ptr, cpu); | ||
474 | cpu_data[cpu].next = data; | ||
475 | |||
476 | return data; | ||
477 | } | ||
478 | |||
479 | struct pevent_record *trace_read_data(struct pevent *pevent, int cpu) | ||
480 | { | ||
481 | struct pevent_record *data; | ||
482 | |||
483 | data = trace_peek_data(pevent, cpu); | ||
484 | cpu_data[cpu].next = NULL; | ||
485 | |||
486 | return data; | ||
487 | } | 341 | } |
488 | 342 | ||
489 | ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe) | 343 | ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe) |
@@ -494,58 +348,85 @@ ssize_t trace_report(int fd, struct pevent **ppevent, bool __repipe) | |||
494 | int show_version = 0; | 348 | int show_version = 0; |
495 | int show_funcs = 0; | 349 | int show_funcs = 0; |
496 | int show_printk = 0; | 350 | int show_printk = 0; |
497 | ssize_t size; | 351 | ssize_t size = -1; |
352 | struct pevent *pevent; | ||
353 | int err; | ||
498 | 354 | ||
499 | calc_data_size = 1; | 355 | *ppevent = NULL; |
500 | repipe = __repipe; | ||
501 | 356 | ||
357 | repipe = __repipe; | ||
502 | input_fd = fd; | 358 | input_fd = fd; |
503 | 359 | ||
504 | read_or_die(buf, 3); | 360 | if (do_read(buf, 3) < 0) |
505 | if (memcmp(buf, test, 3) != 0) | 361 | return -1; |
506 | die("no trace data in the file"); | 362 | if (memcmp(buf, test, 3) != 0) { |
363 | pr_debug("no trace data in the file"); | ||
364 | return -1; | ||
365 | } | ||
507 | 366 | ||
508 | read_or_die(buf, 7); | 367 | if (do_read(buf, 7) < 0) |
509 | if (memcmp(buf, "tracing", 7) != 0) | 368 | return -1; |
510 | die("not a trace file (missing 'tracing' tag)"); | 369 | if (memcmp(buf, "tracing", 7) != 0) { |
370 | pr_debug("not a trace file (missing 'tracing' tag)"); | ||
371 | return -1; | ||
372 | } | ||
511 | 373 | ||
512 | version = read_string(); | 374 | version = read_string(); |
375 | if (version == NULL) | ||
376 | return -1; | ||
513 | if (show_version) | 377 | if (show_version) |
514 | printf("version = %s\n", version); | 378 | printf("version = %s\n", version); |
515 | free(version); | 379 | free(version); |
516 | 380 | ||
517 | read_or_die(buf, 1); | 381 | if (do_read(buf, 1) < 0) |
382 | return -1; | ||
518 | file_bigendian = buf[0]; | 383 | file_bigendian = buf[0]; |
519 | host_bigendian = bigendian(); | 384 | host_bigendian = bigendian(); |
520 | 385 | ||
521 | *ppevent = read_trace_init(file_bigendian, host_bigendian); | 386 | pevent = read_trace_init(file_bigendian, host_bigendian); |
522 | if (*ppevent == NULL) | 387 | if (pevent == NULL) { |
523 | die("read_trace_init failed"); | 388 | pr_debug("read_trace_init failed"); |
389 | goto out; | ||
390 | } | ||
524 | 391 | ||
525 | read_or_die(buf, 1); | 392 | if (do_read(buf, 1) < 0) |
393 | goto out; | ||
526 | long_size = buf[0]; | 394 | long_size = buf[0]; |
527 | 395 | ||
528 | page_size = read4(*ppevent); | 396 | page_size = read4(pevent); |
529 | 397 | if (!page_size) | |
530 | read_header_files(*ppevent); | 398 | goto out; |
531 | 399 | ||
532 | read_ftrace_files(*ppevent); | 400 | err = read_header_files(pevent); |
533 | read_event_files(*ppevent); | 401 | if (err) |
534 | read_proc_kallsyms(*ppevent); | 402 | goto out; |
535 | read_ftrace_printk(*ppevent); | 403 | err = read_ftrace_files(pevent); |
536 | 404 | if (err) | |
537 | size = calc_data_size - 1; | 405 | goto out; |
538 | calc_data_size = 0; | 406 | err = read_event_files(pevent); |
407 | if (err) | ||
408 | goto out; | ||
409 | err = read_proc_kallsyms(pevent); | ||
410 | if (err) | ||
411 | goto out; | ||
412 | err = read_ftrace_printk(pevent); | ||
413 | if (err) | ||
414 | goto out; | ||
415 | |||
416 | size = trace_data_size; | ||
539 | repipe = false; | 417 | repipe = false; |
540 | 418 | ||
541 | if (show_funcs) { | 419 | if (show_funcs) { |
542 | pevent_print_funcs(*ppevent); | 420 | pevent_print_funcs(pevent); |
543 | return size; | 421 | } else if (show_printk) { |
544 | } | 422 | pevent_print_printk(pevent); |
545 | if (show_printk) { | ||
546 | pevent_print_printk(*ppevent); | ||
547 | return size; | ||
548 | } | 423 | } |
549 | 424 | ||
425 | *ppevent = pevent; | ||
426 | pevent = NULL; | ||
427 | |||
428 | out: | ||
429 | if (pevent) | ||
430 | pevent_free(pevent); | ||
550 | return size; | 431 | return size; |
551 | } | 432 | } |