aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-11-25 22:24:52 -0500
committerSteven Rostedt <rostedt@goodmis.org>2009-11-25 22:24:52 -0500
commit7fd032a55d1f903154ca712952871dd7a3449e64 (patch)
treeaae87d1acc52f1ad2692887d27e0f99c44bdce7d
parent4d03d560ff1913386f3b2f020a41751e2b7bcb0f (diff)
Convert libtracecmd to be more self sufficient
Convent the API to use the handler for tracecmd. Also convert the read code to not die on error. A library should not kill the app. Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--parse-events.c3
-rw-r--r--trace-cmd.h9
-rw-r--r--trace-input.c349
-rw-r--r--trace-local.h5
-rw-r--r--trace-read.c53
5 files changed, 306 insertions, 113 deletions
diff --git a/parse-events.c b/parse-events.c
index d27e7f1..df8c614 100644
--- a/parse-events.c
+++ b/parse-events.c
@@ -37,6 +37,9 @@ int header_page_size_size;
37int header_page_data_offset; 37int header_page_data_offset;
38int header_page_data_size; 38int header_page_data_size;
39 39
40int file_bigendian;
41int host_bigendian;
42
40int latency_format; 43int latency_format;
41 44
42int old_format; 45int old_format;
diff --git a/trace-cmd.h b/trace-cmd.h
index 4e1d900..223e12f 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -6,17 +6,10 @@
6extern int input_fd; 6extern int input_fd;
7extern const char *input_file; 7extern const char *input_file;
8 8
9extern unsigned int page_size;
10
11#ifndef PAGE_MASK 9#ifndef PAGE_MASK
12#define PAGE_MASK (page_size - 1) 10#define PAGE_MASK (page_size - 1)
13#endif 11#endif
14 12
15int read_trace_header(void);
16int read_trace_files(void);
17
18void trace_report(int argc, char **argv);
19
20void parse_cmdlines(char *file, int size); 13void parse_cmdlines(char *file, int size);
21void parse_proc_kallsyms(char *file, unsigned int size); 14void parse_proc_kallsyms(char *file, unsigned int size);
22void parse_ftrace_printk(char *file, unsigned int size); 15void parse_ftrace_printk(char *file, unsigned int size);
@@ -37,5 +30,7 @@ struct tracecmd_handle;
37 30
38struct tracecmd_handle *tracecmd_open(int fd); 31struct tracecmd_handle *tracecmd_open(int fd);
39int tracecmd_read_headers(struct tracecmd_handle *handle); 32int tracecmd_read_headers(struct tracecmd_handle *handle);
33int tracecmd_long_size(struct tracecmd_handle *handle);
34int tracecmd_page_size(struct tracecmd_handle *handle);
40 35
41#endif /* _TRACE_CMD_H */ 36#endif /* _TRACE_CMD_H */
diff --git a/trace-input.c b/trace-input.c
index e2c089b..5f28214 100644
--- a/trace-input.c
+++ b/trace-input.c
@@ -18,28 +18,46 @@
18 18
19#include "trace-cmd.h" 19#include "trace-cmd.h"
20 20
21extern int show_events;
22
23struct tracecmd_handle { 21struct tracecmd_handle {
24 int fd; 22 int fd;
23 int long_size;
24 int page_size;
25 int print_events;
25}; 26};
26 27
27int file_bigendian; 28static int do_read(struct tracecmd_handle *handle, void *data, int size)
28int host_bigendian;
29int long_size;
30
31int read_or_die(void *data, int size)
32{ 29{
30 int tot = 0;
33 int r; 31 int r;
34 32
35 r = read(input_fd, data, size); 33 do {
36 if (r != size) 34 r = read(handle->fd, data, size);
37 die("reading input file (size expected=%d received=%d)", 35 tot += r;
38 size, r); 36
39 return r; 37 if (!r)
38 break;
39 if (r < 0)
40 return r;
41 } while (tot != size);
42
43 return tot;
44}
45
46static int
47do_read_check(struct tracecmd_handle *handle, void *data, int size)
48{
49 int ret;
50
51 ret = do_read(handle, data, size);
52 if (ret < 0)
53 return ret;
54 if (ret != size)
55 return -1;
56
57 return 0;
40} 58}
41 59
42static char *read_string(void) 60static char *read_string(struct tracecmd_handle *handle)
43{ 61{
44 char buf[BUFSIZ]; 62 char buf[BUFSIZ];
45 char *str = NULL; 63 char *str = NULL;
@@ -48,12 +66,11 @@ static char *read_string(void)
48 int r; 66 int r;
49 67
50 for (;;) { 68 for (;;) {
51 r = read(input_fd, buf, BUFSIZ); 69 r = do_read(handle, buf, BUFSIZ);
52 if (r < 0) 70 if (r < 0)
53 die("reading input file"); 71 goto fail;
54
55 if (!r) 72 if (!r)
56 die("no data"); 73 goto fail;
57 74
58 for (i = 0; i < r; i++) { 75 for (i = 0; i < r; i++) {
59 if (!buf[i]) 76 if (!buf[i])
@@ -66,185 +83,307 @@ static char *read_string(void)
66 size += BUFSIZ; 83 size += BUFSIZ;
67 str = realloc(str, size); 84 str = realloc(str, size);
68 if (!str) 85 if (!str)
69 die("malloc of size %d", size); 86 return NULL;
70 memcpy(str + (size - BUFSIZ), buf, BUFSIZ); 87 memcpy(str + (size - BUFSIZ), buf, BUFSIZ);
71 } else { 88 } else {
72 size = BUFSIZ; 89 size = BUFSIZ;
73 str = malloc_or_die(size); 90 str = malloc(size);
91 if (!str)
92 return NULL;
74 memcpy(str, buf, size); 93 memcpy(str, buf, size);
75 } 94 }
76 } 95 }
77 96
78 /* move the file descriptor to the end of the string */ 97 /* move the file descriptor to the end of the string */
79 r = lseek(input_fd, -(r - (i+1)), SEEK_CUR); 98 r = lseek(handle->fd, -(r - (i+1)), SEEK_CUR);
80 if (r < 0) 99 if (r < 0)
81 die("lseek"); 100 goto fail;
82 101
83 if (str) { 102 if (str) {
84 size += i + 1; 103 size += i + 1;
85 str = realloc(str, size); 104 str = realloc(str, size);
86 if (!str) 105 if (!str)
87 die("malloc of size %d", size); 106 return NULL;
88 memcpy(str + (size - i), buf, i); 107 memcpy(str + (size - i), buf, i);
89 str[size] = 0; 108 str[size] = 0;
90 } else { 109 } else {
91 size = i + 1; 110 size = i + 1;
92 str = malloc_or_die(i); 111 str = malloc(i);
112 if (!str)
113 return NULL;
93 memcpy(str, buf, i); 114 memcpy(str, buf, i);
94 str[i] = 0; 115 str[i] = 0;
95 } 116 }
96 117
97 return str; 118 return str;
119
120 fail:
121 if (str)
122 free(str);
123 return NULL;
98} 124}
99 125
100unsigned int read4(void) 126static unsigned int read4(struct tracecmd_handle *handle)
101{ 127{
102 unsigned int data; 128 unsigned int data;
103 129
104 read_or_die(&data, 4); 130 if (do_read_check(handle, &data, 4))
131 return -1;
132
105 return __data2host4(data); 133 return __data2host4(data);
106} 134}
107 135
108unsigned long long read8(void) 136static unsigned long long read8(struct tracecmd_handle *handle)
109{ 137{
110 unsigned long long data; 138 unsigned long long data;
111 139
112 read_or_die(&data, 8); 140 if (do_read_check(handle, &data, 8))
141 return -1;
142
113 return __data2host8(data); 143 return __data2host8(data);
114} 144}
115 145
116static void read_header_files(void) 146static int read_header_files(struct tracecmd_handle *handle)
117{ 147{
118 unsigned long long size; 148 long long size;
119 char *header_page; 149 char *header;
120 char *header_event;
121 char buf[BUFSIZ]; 150 char buf[BUFSIZ];
122 151
123 read_or_die(buf, 12); 152 if (do_read_check(handle, buf, 12))
153 return -1;
154
124 if (memcmp(buf, "header_page", 12) != 0) 155 if (memcmp(buf, "header_page", 12) != 0)
125 die("did not read header page"); 156 return -1;
157
158 size = read8(handle);
159 if (size < 0)
160 return -1;
161
162 header = malloc(size);
163 if (!header)
164 return -1;
126 165
127 size = read8(); 166 if (do_read_check(handle, header, size))
128 header_page = malloc_or_die(size); 167 goto failed_read;
129 read_or_die(header_page, size); 168
130 pevent_parse_header_page(header_page, size); 169 pevent_parse_header_page(header, size);
131 free(header_page); 170 free(header);
132 171
133 /* 172 /*
134 * The size field in the page is of type long, 173 * The size field in the page is of type long,
135 * use that instead, since it represents the kernel. 174 * use that instead, since it represents the kernel.
136 */ 175 */
137 long_size = header_page_size_size; 176 handle->long_size = header_page_size_size;
177
178 if (do_read_check(handle, buf, 13))
179 return -1;
138 180
139 read_or_die(buf, 13);
140 if (memcmp(buf, "header_event", 13) != 0) 181 if (memcmp(buf, "header_event", 13) != 0)
141 die("did not read header event"); 182 return -1;
183
184 size = read8(handle);
185 if (size < 0)
186 return -1;
187
188 header = malloc(size);
189 if (!header)
190 return -1;
142 191
143 size = read8(); 192 if (do_read_check(handle, header, size))
144 header_event = malloc_or_die(size); 193 goto failed_read;
145 read_or_die(header_event, size); 194
146 free(header_event); 195 free(header);
196
197 return 0;
198
199 failed_read:
200 free(header);
201 return -1;
147} 202}
148 203
149static void read_ftrace_file(unsigned long long size) 204static int read_ftrace_file(struct tracecmd_handle *handle,
205 unsigned long long size)
150{ 206{
151 char *buf; 207 char *buf;
152 208
153 buf = malloc_or_die(size); 209 buf = malloc(size);
154 read_or_die(buf, size); 210 if (!buf)
211 return -1;
212 if (do_read_check(handle, buf, size)) {
213 free(buf);
214 return -1;
215 }
216
155 pevent_parse_event(buf, size, "ftrace"); 217 pevent_parse_event(buf, size, "ftrace");
156 free(buf); 218 free(buf);
219
220 return 0;
157} 221}
158 222
159static void read_event_file(char *system, unsigned long long size) 223static int read_event_file(struct tracecmd_handle *handle,
224 char *system, unsigned long long size)
160{ 225{
161 char *buf; 226 char *buf;
162 227
163 buf = malloc_or_die(size+1); 228 buf = malloc(size+1);
164 read_or_die(buf, size); 229 if (!buf)
230 return -1;
231
232 if (do_read_check(handle,buf, size)) {
233 free(buf);
234 return -1;
235 }
236
165 buf[size] = 0; 237 buf[size] = 0;
166 if (show_events) 238 if (handle->print_events)
167 printf("%s\n", buf); 239 printf("%s\n", buf);
168 pevent_parse_event(buf, size, system); 240 pevent_parse_event(buf, size, system);
169 free(buf); 241 free(buf);
242
243 return 0;
170} 244}
171 245
172static void read_ftrace_files(void) 246static int read_ftrace_files(struct tracecmd_handle *handle)
173{ 247{
174 unsigned long long size; 248 unsigned long long size;
175 int count; 249 int count;
250 int ret;
176 int i; 251 int i;
177 252
178 count = read4(); 253 count = read4(handle);
254 if (count < 0)
255 return -1;
179 256
180 for (i = 0; i < count; i++) { 257 for (i = 0; i < count; i++) {
181 size = read8(); 258 size = read8(handle);
182 read_ftrace_file(size); 259 if (size < 0)
260 return -1;
261 ret = read_ftrace_file(handle, size);
262 if (ret < 0)
263 return -1;
183 } 264 }
265
266 return 0;
184} 267}
185 268
186static void read_event_files(void) 269static int read_event_files(struct tracecmd_handle *handle)
187{ 270{
188 unsigned long long size; 271 unsigned long long size;
189 char *system; 272 char *system;
190 int systems; 273 int systems;
191 int count; 274 int count;
275 int ret;
192 int i,x; 276 int i,x;
193 277
194 systems = read4(); 278 systems = read4(handle);
279 if (systems < 0)
280 return -1;
195 281
196 for (i = 0; i < systems; i++) { 282 for (i = 0; i < systems; i++) {
197 system = read_string(); 283 system = read_string(handle);
284 if (!system)
285 return -1;
286
287 count = read4(handle);
288 if (count < 0)
289 goto failed;
198 290
199 count = read4();
200 for (x=0; x < count; x++) { 291 for (x=0; x < count; x++) {
201 size = read8(); 292 size = read8(handle);
202 read_event_file(system, size); 293 if (size < 0)
294 goto failed;
295
296 ret = read_event_file(handle, system, size);
297 if (ret < 0)
298 goto failed;
203 } 299 }
300 free(system);
204 } 301 }
302
303 return 0;
304
305 failed:
306 free(system);
307 return -1;
205} 308}
206 309
207static void read_proc_kallsyms(void) 310static int read_proc_kallsyms(struct tracecmd_handle *handle)
208{ 311{
209 unsigned int size; 312 int size;
210 char *buf; 313 char *buf;
211 314
212 size = read4(); 315 size = read4(handle);
213 if (!size) 316 if (!size)
214 return; 317 return 0; /* OK? */
215 318
216 buf = malloc_or_die(size); 319 if (size < 0)
217 read_or_die(buf, size); 320 return -1;
321
322 buf = malloc(size);
323 if (!buf)
324 return -1;
325 if (do_read_check(handle, buf, size)){
326 free(buf);
327 return -1;
328 }
218 329
219 parse_proc_kallsyms(buf, size); 330 parse_proc_kallsyms(buf, size);
220 331
221 free(buf); 332 free(buf);
333 return 0;
222} 334}
223 335
224static void read_ftrace_printk(void) 336static int read_ftrace_printk(struct tracecmd_handle *handle)
225{ 337{
226 unsigned int size; 338 int size;
227 char *buf; 339 char *buf;
228 340
229 size = read4(); 341 size = read4(handle);
230 if (!size) 342 if (!size)
231 return; 343 return 0; /* OK? */
232 344
233 buf = malloc_or_die(size); 345 if (size < 0)
234 read_or_die(buf, size); 346 return -1;
347
348 buf = malloc(size);
349 if (!buf)
350 return -1;
351 if (do_read_check(handle, buf, size)) {
352 free(buf);
353 return -1;
354 }
235 355
236 parse_ftrace_printk(buf, size); 356 parse_ftrace_printk(buf, size);
237 357
238 free(buf); 358 free(buf);
359
360 return 0;
239} 361}
240 362
241int read_trace_files(void) 363int tracecmd_read_headers(struct tracecmd_handle *handle)
242{ 364{
243 read_header_files(); 365 int ret;
244 read_ftrace_files(); 366
245 read_event_files(); 367 ret = read_header_files(handle);
246 read_proc_kallsyms(); 368 if (ret < 0)
247 read_ftrace_printk(); 369 return -1;
370
371 ret = read_ftrace_files(handle);
372 if (ret < 0)
373 return -1;
374
375 ret = read_event_files(handle);
376 if (ret < 0)
377 return -1;
378
379 ret = read_proc_kallsyms(handle);
380 if (ret < 0)
381 return -1;
382
383 ret = read_ftrace_printk(handle);
384 if (ret < 0)
385 return -1;
386
248 387
249 trace_load_plugins(); 388 trace_load_plugins();
250 389
@@ -264,30 +403,54 @@ struct tracecmd_handle *tracecmd_open(int fd)
264 403
265 handle->fd = fd; 404 handle->fd = fd;
266 405
267 input_fd = open(input_file, O_RDONLY); 406 if (do_read_check(handle, buf, 3))
268 if (input_fd < 0) 407 goto failed_read;
269 die("opening '%s'\n", input_file);
270 408
271 read_or_die(buf, 3);
272 if (memcmp(buf, test, 3) != 0) 409 if (memcmp(buf, test, 3) != 0)
273 die("not an trace data file"); 410 goto failed_read;
274 411
275 read_or_die(buf, 7); 412 if (do_read_check(handle, buf, 7))
413 goto failed_read;
276 if (memcmp(buf, "tracing", 7) != 0) 414 if (memcmp(buf, "tracing", 7) != 0)
277 die("not a trace file (missing tracing)"); 415 goto failed_read;
278 416
279 version = read_string(); 417 version = read_string(handle);
418 if (!version)
419 goto failed_read;
280 printf("version = %s\n", version); 420 printf("version = %s\n", version);
281 free(version); 421 free(version);
282 422
283 read_or_die(buf, 1); 423 if (do_read_check(handle, buf, 1))
424 goto failed_read;
425
426 /*
427 * TODO:
428 * Need to make these part of the handle.
429 * But they are currently used by parsevent.
430 * That may need a handler too.
431 */
284 file_bigendian = buf[0]; 432 file_bigendian = buf[0];
285 host_bigendian = bigendian(); 433 host_bigendian = bigendian();
286 434
287 read_or_die(buf, 1); 435 do_read_check(handle, buf, 1);
288 long_size = buf[0]; 436 handle->long_size = buf[0];
289 437
290 page_size = read4(); 438 handle->page_size = read4(handle);
291 439
292 return 0; 440 return handle;
441
442 failed_read:
443 free(handle);
444
445 return NULL;
446}
447
448int tracecmd_long_size(struct tracecmd_handle *handle)
449{
450 return handle->long_size;
451}
452
453int tracecmd_page_size(struct tracecmd_handle *handle)
454{
455 return handle->page_size;
293} 456}
diff --git a/trace-local.h b/trace-local.h
index d3fddff..83fe077 100644
--- a/trace-local.h
+++ b/trace-local.h
@@ -7,5 +7,10 @@
7 7
8void usage(char **argv); 8void usage(char **argv);
9 9
10struct tracecmd_handle *read_trace_header(void);
11int read_trace_files(void);
12
13void trace_report(int argc, char **argv);
14
10 15
11#endif /* __TRACE_LOCAL_H */ 16#endif /* __TRACE_LOCAL_H */
diff --git a/trace-read.c b/trace-read.c
index 395eeef..a3e5d66 100644
--- a/trace-read.c
+++ b/trace-read.c
@@ -38,6 +38,7 @@
38 38
39#include "trace-local.h" 39#include "trace-local.h"
40 40
41unsigned int page_size;
41int input_fd; 42int input_fd;
42const char *input_file = "trace.dat"; 43const char *input_file = "trace.dat";
43 44
@@ -415,12 +416,34 @@ static void read_rest(void)
415 } while (r > 0); 416 } while (r > 0);
416} 417}
417 418
418unsigned int read4(void); 419static int read_or_die(void *data, int size)
419unsigned long long read8(void); 420{
420int read_or_die(void *data, int size); 421 int r;
421extern int long_size; 422
423 r = read(input_fd, data, size);
424 if (r != size)
425 die("reading input file (size expected=%d received=%d)",
426 size, r);
427 return r;
428}
429
430static unsigned int read4(void)
431{
432 unsigned int data;
433
434 read_or_die(&data, 4);
435 return __data2host4(data);
436}
422 437
423static void read_data_info(void) 438static unsigned long long read8(void)
439{
440 unsigned long long data;
441
442 read_or_die(&data, 8);
443 return __data2host8(data);
444}
445
446static void read_data_info(struct tracecmd_handle *handle)
424{ 447{
425 unsigned long long ts; 448 unsigned long long ts;
426 unsigned long long size; 449 unsigned long long size;
@@ -439,7 +462,7 @@ static void read_data_info(void)
439 cpus = read4(); 462 cpus = read4();
440 printf("cpus=%d\n", cpus); 463 printf("cpus=%d\n", cpus);
441 464
442 parse_set_info(cpus, long_size); 465 parse_set_info(cpus, tracecmd_long_size(handle));
443 466
444 /* 467 /*
445 * Check if this is a latency report or not. 468 * Check if this is a latency report or not.
@@ -484,19 +507,18 @@ static void read_data_info(void)
484 } while (next >= 0); 507 } while (next >= 0);
485} 508}
486 509
487int read_trace_header(void) 510struct tracecmd_handle *read_trace_header(void)
488{ 511{
489 input_fd = open(input_file, O_RDONLY); 512 input_fd = open(input_file, O_RDONLY);
490 if (input_fd < 0) 513 if (input_fd < 0)
491 die("opening '%s'\n", input_file); 514 die("opening '%s'\n", input_file);
492 515
493 tracecmd_open(input_fd); 516 return tracecmd_open(input_fd);
494
495 return 0;
496} 517}
497 518
498void trace_report (int argc, char **argv) 519void trace_report (int argc, char **argv)
499{ 520{
521 struct tracecmd_handle *handle;
500 int show_funcs = 0; 522 int show_funcs = 0;
501 int show_endian = 0; 523 int show_endian = 0;
502 int show_page_size = 0; 524 int show_page_size = 0;
@@ -560,7 +582,11 @@ void trace_report (int argc, char **argv)
560 } 582 }
561 } 583 }
562 584
563 read_trace_header(); 585 handle = read_trace_header();
586 if (!handle)
587 die("error reading header");
588
589 page_size = tracecmd_page_size(handle);
564 590
565 if (show_page_size) { 591 if (show_page_size) {
566 printf("file page size is %d, and host page size is %d\n", 592 printf("file page size is %d, and host page size is %d\n",
@@ -576,7 +602,8 @@ void trace_report (int argc, char **argv)
576 return; 602 return;
577 } 603 }
578 604
579 read_trace_files(); 605 if (tracecmd_read_headers(handle) < 0)
606 return;
580 607
581 if (show_funcs) { 608 if (show_funcs) {
582 pevent_print_funcs(); 609 pevent_print_funcs();
@@ -590,7 +617,7 @@ void trace_report (int argc, char **argv)
590 if (show_events) 617 if (show_events)
591 return; 618 return;
592 619
593 read_data_info(); 620 read_data_info(handle);
594 621
595 return; 622 return;
596} 623}