aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/trace-event-info.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/trace-event-info.c')
-rw-r--r--tools/perf/util/trace-event-info.c380
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
53unsigned int page_size;
54
55static const char *output_file = "trace.info";
56static int output_fd; 46static int output_fd;
57 47
58struct event_list {
59 struct event_list *next;
60 const char *event;
61};
62
63struct events {
64 struct events *sibling;
65 struct events *children;
66 struct events *next;
67 char *name;
68};
69
70
71static 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
81static const char *find_debugfs(void) 49static 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
134static ssize_t calc_data_size;
135
136static 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
152int bigendian(void) 108int 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 */
162static void record_file(const char *file, size_t hdr_sz) 118static 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;
158out:
159 close(fd);
160 return err;
193} 161}
194 162
195static void read_header_files(void) 163static 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;
215out:
214 put_tracing_file(path); 216 put_tracing_file(path);
217 return err;
215} 218}
216 219
217static bool name_in_tp_list(char *sys, struct tracepoint_path *tps) 220static 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
228static void copy_event_system(const char *sys, struct tracepoint_path *tps) 231static 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;
297out:
274 closedir(dir); 298 closedir(dir);
299 return err;
275} 300}
276 301
277static void read_ftrace_files(struct tracepoint_path *tps) 302static 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
288static bool system_in_tp_list(char *sys, struct tracepoint_path *tps) 320static 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
299static void read_event_files(struct tracepoint_path *tps) 331static 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;
399out:
345 closedir(dir); 400 closedir(dir);
346 put_tracing_file(path); 401 put_tracing_file(path);
402
403 return err;
347} 404}
348 405
349static void read_proc_kallsyms(void) 406static 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
366static void read_ftrace_printk(void) 424static 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
383out: 447out:
384 put_tracing_file(path); 448 put_tracing_file(path);
449 return err;
450}
451
452static void
453put_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
387static struct tracepoint_path * 465static 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
407static void
408put_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
420bool have_tracepoints(struct list_head *pattrs) 488bool 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
431static void tracing_data_header(void) 499static 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
464struct tracing_data *tracing_data_get(struct list_head *pattrs, 540struct 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
600out:
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
520void tracing_data_put(struct tracing_data *tdata) 620int 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
530int read_tracing_data(int fd, struct list_head *pattrs) 633int 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}