diff options
Diffstat (limited to 'tools/perf/util/trace-event-info.c')
-rw-r--r-- | tools/perf/util/trace-event-info.c | 380 |
1 files changed, 242 insertions, 138 deletions
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index a8d81c35ef66..3917eb9a8479 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c | |||
@@ -38,52 +38,20 @@ | |||
38 | 38 | ||
39 | #include "../perf.h" | 39 | #include "../perf.h" |
40 | #include "trace-event.h" | 40 | #include "trace-event.h" |
41 | #include "debugfs.h" | 41 | #include <lk/debugfs.h> |
42 | #include "evsel.h" | 42 | #include "evsel.h" |
43 | 43 | ||
44 | #define VERSION "0.5" | 44 | #define VERSION "0.5" |
45 | 45 | ||
46 | #define TRACE_CTRL "tracing_on" | ||
47 | #define TRACE "trace" | ||
48 | #define AVAILABLE "available_tracers" | ||
49 | #define CURRENT "current_tracer" | ||
50 | #define ITER_CTRL "trace_options" | ||
51 | #define MAX_LATENCY "tracing_max_latency" | ||
52 | |||
53 | unsigned int page_size; | ||
54 | |||
55 | static const char *output_file = "trace.info"; | ||
56 | static int output_fd; | 46 | static int output_fd; |
57 | 47 | ||
58 | struct event_list { | ||
59 | struct event_list *next; | ||
60 | const char *event; | ||
61 | }; | ||
62 | |||
63 | struct events { | ||
64 | struct events *sibling; | ||
65 | struct events *children; | ||
66 | struct events *next; | ||
67 | char *name; | ||
68 | }; | ||
69 | |||
70 | |||
71 | static void *malloc_or_die(unsigned int size) | ||
72 | { | ||
73 | void *data; | ||
74 | |||
75 | data = malloc(size); | ||
76 | if (!data) | ||
77 | die("malloc"); | ||
78 | return data; | ||
79 | } | ||
80 | 48 | ||
81 | static const char *find_debugfs(void) | 49 | static const char *find_debugfs(void) |
82 | { | 50 | { |
83 | const char *path = debugfs_mount(NULL); | 51 | const char *path = perf_debugfs_mount(NULL); |
84 | 52 | ||
85 | if (!path) | 53 | if (!path) |
86 | die("Your kernel not support debugfs filesystem"); | 54 | pr_debug("Your kernel does not support the debugfs filesystem"); |
87 | 55 | ||
88 | return path; | 56 | return path; |
89 | } | 57 | } |
@@ -102,8 +70,12 @@ static const char *find_tracing_dir(void) | |||
102 | return tracing; | 70 | return tracing; |
103 | 71 | ||
104 | debugfs = find_debugfs(); | 72 | debugfs = find_debugfs(); |
73 | if (!debugfs) | ||
74 | return NULL; | ||
105 | 75 | ||
106 | tracing = malloc_or_die(strlen(debugfs) + 9); | 76 | tracing = malloc(strlen(debugfs) + 9); |
77 | if (!tracing) | ||
78 | return NULL; | ||
107 | 79 | ||
108 | sprintf(tracing, "%s/tracing", debugfs); | 80 | sprintf(tracing, "%s/tracing", debugfs); |
109 | 81 | ||
@@ -120,7 +92,9 @@ static char *get_tracing_file(const char *name) | |||
120 | if (!tracing) | 92 | if (!tracing) |
121 | return NULL; | 93 | return NULL; |
122 | 94 | ||
123 | file = malloc_or_die(strlen(tracing) + strlen(name) + 2); | 95 | file = malloc(strlen(tracing) + strlen(name) + 2); |
96 | if (!file) | ||
97 | return NULL; | ||
124 | 98 | ||
125 | sprintf(file, "%s/%s", tracing, name); | 99 | sprintf(file, "%s/%s", tracing, name); |
126 | return file; | 100 | return file; |
@@ -131,24 +105,6 @@ static void put_tracing_file(char *file) | |||
131 | free(file); | 105 | free(file); |
132 | } | 106 | } |
133 | 107 | ||
134 | static ssize_t calc_data_size; | ||
135 | |||
136 | static ssize_t write_or_die(const void *buf, size_t len) | ||
137 | { | ||
138 | int ret; | ||
139 | |||
140 | if (calc_data_size) { | ||
141 | calc_data_size += len; | ||
142 | return len; | ||
143 | } | ||
144 | |||
145 | ret = write(output_fd, buf, len); | ||
146 | if (ret < 0) | ||
147 | die("writing to '%s'", output_file); | ||
148 | |||
149 | return ret; | ||
150 | } | ||
151 | |||
152 | int bigendian(void) | 108 | int bigendian(void) |
153 | { | 109 | { |
154 | unsigned char str[] = { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0}; | 110 | unsigned char str[] = { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0}; |
@@ -159,59 +115,106 @@ int bigendian(void) | |||
159 | } | 115 | } |
160 | 116 | ||
161 | /* unfortunately, you can not stat debugfs or proc files for size */ | 117 | /* unfortunately, you can not stat debugfs or proc files for size */ |
162 | static void record_file(const char *file, size_t hdr_sz) | 118 | static int record_file(const char *file, ssize_t hdr_sz) |
163 | { | 119 | { |
164 | unsigned long long size = 0; | 120 | unsigned long long size = 0; |
165 | char buf[BUFSIZ], *sizep; | 121 | char buf[BUFSIZ], *sizep; |
166 | off_t hdr_pos = lseek(output_fd, 0, SEEK_CUR); | 122 | off_t hdr_pos = lseek(output_fd, 0, SEEK_CUR); |
167 | int r, fd; | 123 | int r, fd; |
124 | int err = -EIO; | ||
168 | 125 | ||
169 | fd = open(file, O_RDONLY); | 126 | fd = open(file, O_RDONLY); |
170 | if (fd < 0) | 127 | if (fd < 0) { |
171 | die("Can't read '%s'", file); | 128 | pr_debug("Can't read '%s'", file); |
129 | return -errno; | ||
130 | } | ||
172 | 131 | ||
173 | /* put in zeros for file size, then fill true size later */ | 132 | /* put in zeros for file size, then fill true size later */ |
174 | if (hdr_sz) | 133 | if (hdr_sz) { |
175 | write_or_die(&size, hdr_sz); | 134 | if (write(output_fd, &size, hdr_sz) != hdr_sz) |
135 | goto out; | ||
136 | } | ||
176 | 137 | ||
177 | do { | 138 | do { |
178 | r = read(fd, buf, BUFSIZ); | 139 | r = read(fd, buf, BUFSIZ); |
179 | if (r > 0) { | 140 | if (r > 0) { |
180 | size += r; | 141 | size += r; |
181 | write_or_die(buf, r); | 142 | if (write(output_fd, buf, r) != r) |
143 | goto out; | ||
182 | } | 144 | } |
183 | } while (r > 0); | 145 | } while (r > 0); |
184 | close(fd); | ||
185 | 146 | ||
186 | /* ugh, handle big-endian hdr_size == 4 */ | 147 | /* ugh, handle big-endian hdr_size == 4 */ |
187 | sizep = (char*)&size; | 148 | sizep = (char*)&size; |
188 | if (bigendian()) | 149 | if (bigendian()) |
189 | sizep += sizeof(u64) - hdr_sz; | 150 | sizep += sizeof(u64) - hdr_sz; |
190 | 151 | ||
191 | if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) | 152 | if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) { |
192 | die("writing to %s", output_file); | 153 | pr_debug("writing file size failed\n"); |
154 | goto out; | ||
155 | } | ||
156 | |||
157 | err = 0; | ||
158 | out: | ||
159 | close(fd); | ||
160 | return err; | ||
193 | } | 161 | } |
194 | 162 | ||
195 | static void read_header_files(void) | 163 | static int read_header_files(void) |
196 | { | 164 | { |
197 | char *path; | 165 | char *path; |
198 | struct stat st; | 166 | struct stat st; |
167 | int err = -EIO; | ||
199 | 168 | ||
200 | path = get_tracing_file("events/header_page"); | 169 | path = get_tracing_file("events/header_page"); |
201 | if (stat(path, &st) < 0) | 170 | if (!path) { |
202 | die("can't read '%s'", path); | 171 | pr_debug("can't get tracing/events/header_page"); |
172 | return -ENOMEM; | ||
173 | } | ||
174 | |||
175 | if (stat(path, &st) < 0) { | ||
176 | pr_debug("can't read '%s'", path); | ||
177 | goto out; | ||
178 | } | ||
179 | |||
180 | if (write(output_fd, "header_page", 12) != 12) { | ||
181 | pr_debug("can't write header_page\n"); | ||
182 | goto out; | ||
183 | } | ||
184 | |||
185 | if (record_file(path, 8) < 0) { | ||
186 | pr_debug("can't record header_page file\n"); | ||
187 | goto out; | ||
188 | } | ||
203 | 189 | ||
204 | write_or_die("header_page", 12); | ||
205 | record_file(path, 8); | ||
206 | put_tracing_file(path); | 190 | put_tracing_file(path); |
207 | 191 | ||
208 | path = get_tracing_file("events/header_event"); | 192 | path = get_tracing_file("events/header_event"); |
209 | if (stat(path, &st) < 0) | 193 | if (!path) { |
210 | die("can't read '%s'", path); | 194 | pr_debug("can't get tracing/events/header_event"); |
195 | err = -ENOMEM; | ||
196 | goto out; | ||
197 | } | ||
198 | |||
199 | if (stat(path, &st) < 0) { | ||
200 | pr_debug("can't read '%s'", path); | ||
201 | goto out; | ||
202 | } | ||
211 | 203 | ||
212 | write_or_die("header_event", 13); | 204 | if (write(output_fd, "header_event", 13) != 13) { |
213 | record_file(path, 8); | 205 | pr_debug("can't write header_event\n"); |
206 | goto out; | ||
207 | } | ||
208 | |||
209 | if (record_file(path, 8) < 0) { | ||
210 | pr_debug("can't record header_event file\n"); | ||
211 | goto out; | ||
212 | } | ||
213 | |||
214 | err = 0; | ||
215 | out: | ||
214 | put_tracing_file(path); | 216 | put_tracing_file(path); |
217 | return err; | ||
215 | } | 218 | } |
216 | 219 | ||
217 | static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) | 220 | static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) |
@@ -225,7 +228,7 @@ static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) | |||
225 | return false; | 228 | return false; |
226 | } | 229 | } |
227 | 230 | ||
228 | static void copy_event_system(const char *sys, struct tracepoint_path *tps) | 231 | static int copy_event_system(const char *sys, struct tracepoint_path *tps) |
229 | { | 232 | { |
230 | struct dirent *dent; | 233 | struct dirent *dent; |
231 | struct stat st; | 234 | struct stat st; |
@@ -233,10 +236,13 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps) | |||
233 | DIR *dir; | 236 | DIR *dir; |
234 | int count = 0; | 237 | int count = 0; |
235 | int ret; | 238 | int ret; |
239 | int err; | ||
236 | 240 | ||
237 | dir = opendir(sys); | 241 | dir = opendir(sys); |
238 | if (!dir) | 242 | if (!dir) { |
239 | die("can't read directory '%s'", sys); | 243 | pr_debug("can't read directory '%s'", sys); |
244 | return -errno; | ||
245 | } | ||
240 | 246 | ||
241 | while ((dent = readdir(dir))) { | 247 | while ((dent = readdir(dir))) { |
242 | if (dent->d_type != DT_DIR || | 248 | if (dent->d_type != DT_DIR || |
@@ -244,7 +250,11 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps) | |||
244 | strcmp(dent->d_name, "..") == 0 || | 250 | strcmp(dent->d_name, "..") == 0 || |
245 | !name_in_tp_list(dent->d_name, tps)) | 251 | !name_in_tp_list(dent->d_name, tps)) |
246 | continue; | 252 | continue; |
247 | format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10); | 253 | format = malloc(strlen(sys) + strlen(dent->d_name) + 10); |
254 | if (!format) { | ||
255 | err = -ENOMEM; | ||
256 | goto out; | ||
257 | } | ||
248 | sprintf(format, "%s/%s/format", sys, dent->d_name); | 258 | sprintf(format, "%s/%s/format", sys, dent->d_name); |
249 | ret = stat(format, &st); | 259 | ret = stat(format, &st); |
250 | free(format); | 260 | free(format); |
@@ -253,7 +263,11 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps) | |||
253 | count++; | 263 | count++; |
254 | } | 264 | } |
255 | 265 | ||
256 | write_or_die(&count, 4); | 266 | if (write(output_fd, &count, 4) != 4) { |
267 | err = -EIO; | ||
268 | pr_debug("can't write count\n"); | ||
269 | goto out; | ||
270 | } | ||
257 | 271 | ||
258 | rewinddir(dir); | 272 | rewinddir(dir); |
259 | while ((dent = readdir(dir))) { | 273 | while ((dent = readdir(dir))) { |
@@ -262,27 +276,45 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps) | |||
262 | strcmp(dent->d_name, "..") == 0 || | 276 | strcmp(dent->d_name, "..") == 0 || |
263 | !name_in_tp_list(dent->d_name, tps)) | 277 | !name_in_tp_list(dent->d_name, tps)) |
264 | continue; | 278 | continue; |
265 | format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10); | 279 | format = malloc(strlen(sys) + strlen(dent->d_name) + 10); |
280 | if (!format) { | ||
281 | err = -ENOMEM; | ||
282 | goto out; | ||
283 | } | ||
266 | sprintf(format, "%s/%s/format", sys, dent->d_name); | 284 | sprintf(format, "%s/%s/format", sys, dent->d_name); |
267 | ret = stat(format, &st); | 285 | ret = stat(format, &st); |
268 | 286 | ||
269 | if (ret >= 0) | 287 | if (ret >= 0) { |
270 | record_file(format, 8); | 288 | err = record_file(format, 8); |
271 | 289 | if (err) { | |
290 | free(format); | ||
291 | goto out; | ||
292 | } | ||
293 | } | ||
272 | free(format); | 294 | free(format); |
273 | } | 295 | } |
296 | err = 0; | ||
297 | out: | ||
274 | closedir(dir); | 298 | closedir(dir); |
299 | return err; | ||
275 | } | 300 | } |
276 | 301 | ||
277 | static void read_ftrace_files(struct tracepoint_path *tps) | 302 | static int read_ftrace_files(struct tracepoint_path *tps) |
278 | { | 303 | { |
279 | char *path; | 304 | char *path; |
305 | int ret; | ||
280 | 306 | ||
281 | path = get_tracing_file("events/ftrace"); | 307 | path = get_tracing_file("events/ftrace"); |
308 | if (!path) { | ||
309 | pr_debug("can't get tracing/events/ftrace"); | ||
310 | return -ENOMEM; | ||
311 | } | ||
282 | 312 | ||
283 | copy_event_system(path, tps); | 313 | ret = copy_event_system(path, tps); |
284 | 314 | ||
285 | put_tracing_file(path); | 315 | put_tracing_file(path); |
316 | |||
317 | return ret; | ||
286 | } | 318 | } |
287 | 319 | ||
288 | static bool system_in_tp_list(char *sys, struct tracepoint_path *tps) | 320 | static bool system_in_tp_list(char *sys, struct tracepoint_path *tps) |
@@ -296,7 +328,7 @@ static bool system_in_tp_list(char *sys, struct tracepoint_path *tps) | |||
296 | return false; | 328 | return false; |
297 | } | 329 | } |
298 | 330 | ||
299 | static void read_event_files(struct tracepoint_path *tps) | 331 | static int read_event_files(struct tracepoint_path *tps) |
300 | { | 332 | { |
301 | struct dirent *dent; | 333 | struct dirent *dent; |
302 | struct stat st; | 334 | struct stat st; |
@@ -305,12 +337,20 @@ static void read_event_files(struct tracepoint_path *tps) | |||
305 | DIR *dir; | 337 | DIR *dir; |
306 | int count = 0; | 338 | int count = 0; |
307 | int ret; | 339 | int ret; |
340 | int err; | ||
308 | 341 | ||
309 | path = get_tracing_file("events"); | 342 | path = get_tracing_file("events"); |
343 | if (!path) { | ||
344 | pr_debug("can't get tracing/events"); | ||
345 | return -ENOMEM; | ||
346 | } | ||
310 | 347 | ||
311 | dir = opendir(path); | 348 | dir = opendir(path); |
312 | if (!dir) | 349 | if (!dir) { |
313 | die("can't read directory '%s'", path); | 350 | err = -errno; |
351 | pr_debug("can't read directory '%s'", path); | ||
352 | goto out; | ||
353 | } | ||
314 | 354 | ||
315 | while ((dent = readdir(dir))) { | 355 | while ((dent = readdir(dir))) { |
316 | if (dent->d_type != DT_DIR || | 356 | if (dent->d_type != DT_DIR || |
@@ -322,7 +362,11 @@ static void read_event_files(struct tracepoint_path *tps) | |||
322 | count++; | 362 | count++; |
323 | } | 363 | } |
324 | 364 | ||
325 | write_or_die(&count, 4); | 365 | if (write(output_fd, &count, 4) != 4) { |
366 | err = -EIO; | ||
367 | pr_debug("can't write count\n"); | ||
368 | goto out; | ||
369 | } | ||
326 | 370 | ||
327 | rewinddir(dir); | 371 | rewinddir(dir); |
328 | while ((dent = readdir(dir))) { | 372 | while ((dent = readdir(dir))) { |
@@ -332,56 +376,90 @@ static void read_event_files(struct tracepoint_path *tps) | |||
332 | strcmp(dent->d_name, "ftrace") == 0 || | 376 | strcmp(dent->d_name, "ftrace") == 0 || |
333 | !system_in_tp_list(dent->d_name, tps)) | 377 | !system_in_tp_list(dent->d_name, tps)) |
334 | continue; | 378 | continue; |
335 | sys = malloc_or_die(strlen(path) + strlen(dent->d_name) + 2); | 379 | sys = malloc(strlen(path) + strlen(dent->d_name) + 2); |
380 | if (!sys) { | ||
381 | err = -ENOMEM; | ||
382 | goto out; | ||
383 | } | ||
336 | sprintf(sys, "%s/%s", path, dent->d_name); | 384 | sprintf(sys, "%s/%s", path, dent->d_name); |
337 | ret = stat(sys, &st); | 385 | ret = stat(sys, &st); |
338 | if (ret >= 0) { | 386 | if (ret >= 0) { |
339 | write_or_die(dent->d_name, strlen(dent->d_name) + 1); | 387 | ssize_t size = strlen(dent->d_name) + 1; |
340 | copy_event_system(sys, tps); | 388 | |
389 | if (write(output_fd, dent->d_name, size) != size || | ||
390 | copy_event_system(sys, tps) < 0) { | ||
391 | err = -EIO; | ||
392 | free(sys); | ||
393 | goto out; | ||
394 | } | ||
341 | } | 395 | } |
342 | free(sys); | 396 | free(sys); |
343 | } | 397 | } |
344 | 398 | err = 0; | |
399 | out: | ||
345 | closedir(dir); | 400 | closedir(dir); |
346 | put_tracing_file(path); | 401 | put_tracing_file(path); |
402 | |||
403 | return err; | ||
347 | } | 404 | } |
348 | 405 | ||
349 | static void read_proc_kallsyms(void) | 406 | static int read_proc_kallsyms(void) |
350 | { | 407 | { |
351 | unsigned int size; | 408 | unsigned int size; |
352 | const char *path = "/proc/kallsyms"; | 409 | const char *path = "/proc/kallsyms"; |
353 | struct stat st; | 410 | struct stat st; |
354 | int ret; | 411 | int ret, err = 0; |
355 | 412 | ||
356 | ret = stat(path, &st); | 413 | ret = stat(path, &st); |
357 | if (ret < 0) { | 414 | if (ret < 0) { |
358 | /* not found */ | 415 | /* not found */ |
359 | size = 0; | 416 | size = 0; |
360 | write_or_die(&size, 4); | 417 | if (write(output_fd, &size, 4) != 4) |
361 | return; | 418 | err = -EIO; |
419 | return err; | ||
362 | } | 420 | } |
363 | record_file(path, 4); | 421 | return record_file(path, 4); |
364 | } | 422 | } |
365 | 423 | ||
366 | static void read_ftrace_printk(void) | 424 | static int read_ftrace_printk(void) |
367 | { | 425 | { |
368 | unsigned int size; | 426 | unsigned int size; |
369 | char *path; | 427 | char *path; |
370 | struct stat st; | 428 | struct stat st; |
371 | int ret; | 429 | int ret, err = 0; |
372 | 430 | ||
373 | path = get_tracing_file("printk_formats"); | 431 | path = get_tracing_file("printk_formats"); |
432 | if (!path) { | ||
433 | pr_debug("can't get tracing/printk_formats"); | ||
434 | return -ENOMEM; | ||
435 | } | ||
436 | |||
374 | ret = stat(path, &st); | 437 | ret = stat(path, &st); |
375 | if (ret < 0) { | 438 | if (ret < 0) { |
376 | /* not found */ | 439 | /* not found */ |
377 | size = 0; | 440 | size = 0; |
378 | write_or_die(&size, 4); | 441 | if (write(output_fd, &size, 4) != 4) |
442 | err = -EIO; | ||
379 | goto out; | 443 | goto out; |
380 | } | 444 | } |
381 | record_file(path, 4); | 445 | err = record_file(path, 4); |
382 | 446 | ||
383 | out: | 447 | out: |
384 | put_tracing_file(path); | 448 | put_tracing_file(path); |
449 | return err; | ||
450 | } | ||
451 | |||
452 | static void | ||
453 | put_tracepoints_path(struct tracepoint_path *tps) | ||
454 | { | ||
455 | while (tps) { | ||
456 | struct tracepoint_path *t = tps; | ||
457 | |||
458 | tps = tps->next; | ||
459 | free(t->name); | ||
460 | free(t->system); | ||
461 | free(t); | ||
462 | } | ||
385 | } | 463 | } |
386 | 464 | ||
387 | static struct tracepoint_path * | 465 | static struct tracepoint_path * |
@@ -396,27 +474,17 @@ get_tracepoints_path(struct list_head *pattrs) | |||
396 | continue; | 474 | continue; |
397 | ++nr_tracepoints; | 475 | ++nr_tracepoints; |
398 | ppath->next = tracepoint_id_to_path(pos->attr.config); | 476 | ppath->next = tracepoint_id_to_path(pos->attr.config); |
399 | if (!ppath->next) | 477 | if (!ppath->next) { |
400 | die("%s\n", "No memory to alloc tracepoints list"); | 478 | pr_debug("No memory to alloc tracepoints list\n"); |
479 | put_tracepoints_path(&path); | ||
480 | return NULL; | ||
481 | } | ||
401 | ppath = ppath->next; | 482 | ppath = ppath->next; |
402 | } | 483 | } |
403 | 484 | ||
404 | return nr_tracepoints > 0 ? path.next : NULL; | 485 | return nr_tracepoints > 0 ? path.next : NULL; |
405 | } | 486 | } |
406 | 487 | ||
407 | static void | ||
408 | put_tracepoints_path(struct tracepoint_path *tps) | ||
409 | { | ||
410 | while (tps) { | ||
411 | struct tracepoint_path *t = tps; | ||
412 | |||
413 | tps = tps->next; | ||
414 | free(t->name); | ||
415 | free(t->system); | ||
416 | free(t); | ||
417 | } | ||
418 | } | ||
419 | |||
420 | bool have_tracepoints(struct list_head *pattrs) | 488 | bool have_tracepoints(struct list_head *pattrs) |
421 | { | 489 | { |
422 | struct perf_evsel *pos; | 490 | struct perf_evsel *pos; |
@@ -428,9 +496,10 @@ bool have_tracepoints(struct list_head *pattrs) | |||
428 | return false; | 496 | return false; |
429 | } | 497 | } |
430 | 498 | ||
431 | static void tracing_data_header(void) | 499 | static int tracing_data_header(void) |
432 | { | 500 | { |
433 | char buf[20]; | 501 | char buf[20]; |
502 | ssize_t size; | ||
434 | 503 | ||
435 | /* just guessing this is someone's birthday.. ;) */ | 504 | /* just guessing this is someone's birthday.. ;) */ |
436 | buf[0] = 23; | 505 | buf[0] = 23; |
@@ -438,9 +507,12 @@ static void tracing_data_header(void) | |||
438 | buf[2] = 68; | 507 | buf[2] = 68; |
439 | memcpy(buf + 3, "tracing", 7); | 508 | memcpy(buf + 3, "tracing", 7); |
440 | 509 | ||
441 | write_or_die(buf, 10); | 510 | if (write(output_fd, buf, 10) != 10) |
511 | return -1; | ||
442 | 512 | ||
443 | write_or_die(VERSION, strlen(VERSION) + 1); | 513 | size = strlen(VERSION) + 1; |
514 | if (write(output_fd, VERSION, size) != size) | ||
515 | return -1; | ||
444 | 516 | ||
445 | /* save endian */ | 517 | /* save endian */ |
446 | if (bigendian()) | 518 | if (bigendian()) |
@@ -450,15 +522,19 @@ static void tracing_data_header(void) | |||
450 | 522 | ||
451 | read_trace_init(buf[0], buf[0]); | 523 | read_trace_init(buf[0], buf[0]); |
452 | 524 | ||
453 | write_or_die(buf, 1); | 525 | if (write(output_fd, buf, 1) != 1) |
526 | return -1; | ||
454 | 527 | ||
455 | /* save size of long */ | 528 | /* save size of long */ |
456 | buf[0] = sizeof(long); | 529 | buf[0] = sizeof(long); |
457 | write_or_die(buf, 1); | 530 | if (write(output_fd, buf, 1) != 1) |
531 | return -1; | ||
458 | 532 | ||
459 | /* save page_size */ | 533 | /* save page_size */ |
460 | page_size = sysconf(_SC_PAGESIZE); | 534 | if (write(output_fd, &page_size, 4) != 4) |
461 | write_or_die(&page_size, 4); | 535 | return -1; |
536 | |||
537 | return 0; | ||
462 | } | 538 | } |
463 | 539 | ||
464 | struct tracing_data *tracing_data_get(struct list_head *pattrs, | 540 | struct tracing_data *tracing_data_get(struct list_head *pattrs, |
@@ -466,6 +542,7 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs, | |||
466 | { | 542 | { |
467 | struct tracepoint_path *tps; | 543 | struct tracepoint_path *tps; |
468 | struct tracing_data *tdata; | 544 | struct tracing_data *tdata; |
545 | int err; | ||
469 | 546 | ||
470 | output_fd = fd; | 547 | output_fd = fd; |
471 | 548 | ||
@@ -473,7 +550,10 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs, | |||
473 | if (!tps) | 550 | if (!tps) |
474 | return NULL; | 551 | return NULL; |
475 | 552 | ||
476 | tdata = malloc_or_die(sizeof(*tdata)); | 553 | tdata = malloc(sizeof(*tdata)); |
554 | if (!tdata) | ||
555 | return NULL; | ||
556 | |||
477 | tdata->temp = temp; | 557 | tdata->temp = temp; |
478 | tdata->size = 0; | 558 | tdata->size = 0; |
479 | 559 | ||
@@ -482,12 +562,16 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs, | |||
482 | 562 | ||
483 | snprintf(tdata->temp_file, sizeof(tdata->temp_file), | 563 | snprintf(tdata->temp_file, sizeof(tdata->temp_file), |
484 | "/tmp/perf-XXXXXX"); | 564 | "/tmp/perf-XXXXXX"); |
485 | if (!mkstemp(tdata->temp_file)) | 565 | if (!mkstemp(tdata->temp_file)) { |
486 | die("Can't make temp file"); | 566 | pr_debug("Can't make temp file"); |
567 | return NULL; | ||
568 | } | ||
487 | 569 | ||
488 | temp_fd = open(tdata->temp_file, O_RDWR); | 570 | temp_fd = open(tdata->temp_file, O_RDWR); |
489 | if (temp_fd < 0) | 571 | if (temp_fd < 0) { |
490 | die("Can't read '%s'", tdata->temp_file); | 572 | pr_debug("Can't read '%s'", tdata->temp_file); |
573 | return NULL; | ||
574 | } | ||
491 | 575 | ||
492 | /* | 576 | /* |
493 | * Set the temp file the default output, so all the | 577 | * Set the temp file the default output, so all the |
@@ -496,13 +580,24 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs, | |||
496 | output_fd = temp_fd; | 580 | output_fd = temp_fd; |
497 | } | 581 | } |
498 | 582 | ||
499 | tracing_data_header(); | 583 | err = tracing_data_header(); |
500 | read_header_files(); | 584 | if (err) |
501 | read_ftrace_files(tps); | 585 | goto out; |
502 | read_event_files(tps); | 586 | err = read_header_files(); |
503 | read_proc_kallsyms(); | 587 | if (err) |
504 | read_ftrace_printk(); | 588 | goto out; |
589 | err = read_ftrace_files(tps); | ||
590 | if (err) | ||
591 | goto out; | ||
592 | err = read_event_files(tps); | ||
593 | if (err) | ||
594 | goto out; | ||
595 | err = read_proc_kallsyms(); | ||
596 | if (err) | ||
597 | goto out; | ||
598 | err = read_ftrace_printk(); | ||
505 | 599 | ||
600 | out: | ||
506 | /* | 601 | /* |
507 | * All tracing data are stored by now, we can restore | 602 | * All tracing data are stored by now, we can restore |
508 | * the default output file in case we used temp file. | 603 | * the default output file in case we used temp file. |
@@ -513,22 +608,31 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs, | |||
513 | output_fd = fd; | 608 | output_fd = fd; |
514 | } | 609 | } |
515 | 610 | ||
611 | if (err) { | ||
612 | free(tdata); | ||
613 | tdata = NULL; | ||
614 | } | ||
615 | |||
516 | put_tracepoints_path(tps); | 616 | put_tracepoints_path(tps); |
517 | return tdata; | 617 | return tdata; |
518 | } | 618 | } |
519 | 619 | ||
520 | void tracing_data_put(struct tracing_data *tdata) | 620 | int tracing_data_put(struct tracing_data *tdata) |
521 | { | 621 | { |
622 | int err = 0; | ||
623 | |||
522 | if (tdata->temp) { | 624 | if (tdata->temp) { |
523 | record_file(tdata->temp_file, 0); | 625 | err = record_file(tdata->temp_file, 0); |
524 | unlink(tdata->temp_file); | 626 | unlink(tdata->temp_file); |
525 | } | 627 | } |
526 | 628 | ||
527 | free(tdata); | 629 | free(tdata); |
630 | return err; | ||
528 | } | 631 | } |
529 | 632 | ||
530 | int read_tracing_data(int fd, struct list_head *pattrs) | 633 | int read_tracing_data(int fd, struct list_head *pattrs) |
531 | { | 634 | { |
635 | int err; | ||
532 | struct tracing_data *tdata; | 636 | struct tracing_data *tdata; |
533 | 637 | ||
534 | /* | 638 | /* |
@@ -539,6 +643,6 @@ int read_tracing_data(int fd, struct list_head *pattrs) | |||
539 | if (!tdata) | 643 | if (!tdata) |
540 | return -ENOMEM; | 644 | return -ENOMEM; |
541 | 645 | ||
542 | tracing_data_put(tdata); | 646 | err = tracing_data_put(tdata); |
543 | return 0; | 647 | return err; |
544 | } | 648 | } |