aboutsummaryrefslogtreecommitdiffstats
path: root/trace-input.c
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 /trace-input.c
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>
Diffstat (limited to 'trace-input.c')
-rw-r--r--trace-input.c349
1 files changed, 256 insertions, 93 deletions
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}