summaryrefslogtreecommitdiff
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 @@
#include "../perf.h"
#include "trace-event.h"
-#include "debugfs.h"
+#include <lk/debugfs.h>
#include "evsel.h"
#define VERSION "0.5"
-#define TRACE_CTRL "tracing_on"
-#define TRACE "trace"
-#define AVAILABLE "available_tracers"
-#define CURRENT "current_tracer"
-#define ITER_CTRL "trace_options"
-#define MAX_LATENCY "tracing_max_latency"
-
-unsigned int page_size;
-
-static const char *output_file = "trace.info";
static int output_fd;
-struct event_list {
- struct event_list *next;
- const char *event;
-};
-
-struct events {
- struct events *sibling;
- struct events *children;
- struct events *next;
- char *name;
-};
-
-
-static void *malloc_or_die(unsigned int size)
-{
- void *data;
-
- data = malloc(size);
- if (!data)
- die("malloc");
- return data;
-}
static const char *find_debugfs(void)
{
- const char *path = debugfs_mount(NULL);
+ const char *path = perf_debugfs_mount(NULL);
if (!path)
- die("Your kernel not support debugfs filesystem");
+ pr_debug("Your kernel does not support the debugfs filesystem");
return path;
}
@@ -102,8 +70,12 @@ static const char *find_tracing_dir(void)
return tracing;
debugfs = find_debugfs();
+ if (!debugfs)
+ return NULL;
- tracing = malloc_or_die(strlen(debugfs) + 9);
+ tracing = malloc(strlen(debugfs) + 9);
+ if (!tracing)
+ return NULL;
sprintf(tracing, "%s/tracing", debugfs);
@@ -120,7 +92,9 @@ static char *get_tracing_file(const char *name)
if (!tracing)
return NULL;
- file = malloc_or_die(strlen(tracing) + strlen(name) + 2);
+ file = malloc(strlen(tracing) + strlen(name) + 2);
+ if (!file)
+ return NULL;
sprintf(file, "%s/%s", tracing, name);
return file;
@@ -131,24 +105,6 @@ static void put_tracing_file(char *file)
free(file);
}
-static ssize_t calc_data_size;
-
-static ssize_t write_or_die(const void *buf, size_t len)
-{
- int ret;
-
- if (calc_data_size) {
- calc_data_size += len;
- return len;
- }
-
- ret = write(output_fd, buf, len);
- if (ret < 0)
- die("writing to '%s'", output_file);
-
- return ret;
-}
-
int bigendian(void)
{
unsigned char str[] = { 0x1, 0x2, 0x3, 0x4, 0x0, 0x0, 0x0, 0x0};
@@ -159,59 +115,106 @@ int bigendian(void)
}
/* unfortunately, you can not stat debugfs or proc files for size */
-static void record_file(const char *file, size_t hdr_sz)
+static int record_file(const char *file, ssize_t hdr_sz)
{
unsigned long long size = 0;
char buf[BUFSIZ], *sizep;
off_t hdr_pos = lseek(output_fd, 0, SEEK_CUR);
int r, fd;
+ int err = -EIO;
fd = open(file, O_RDONLY);
- if (fd < 0)
- die("Can't read '%s'", file);
+ if (fd < 0) {
+ pr_debug("Can't read '%s'", file);
+ return -errno;
+ }
/* put in zeros for file size, then fill true size later */
- if (hdr_sz)
- write_or_die(&size, hdr_sz);
+ if (hdr_sz) {
+ if (write(output_fd, &size, hdr_sz) != hdr_sz)
+ goto out;
+ }
do {
r = read(fd, buf, BUFSIZ);
if (r > 0) {
size += r;
- write_or_die(buf, r);
+ if (write(output_fd, buf, r) != r)
+ goto out;
}
} while (r > 0);
- close(fd);
/* ugh, handle big-endian hdr_size == 4 */
sizep = (char*)&size;
if (bigendian())
sizep += sizeof(u64) - hdr_sz;
- if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0)
- die("writing to %s", output_file);
+ if (hdr_sz && pwrite(output_fd, sizep, hdr_sz, hdr_pos) < 0) {
+ pr_debug("writing file size failed\n");
+ goto out;
+ }
+
+ err = 0;
+out:
+ close(fd);
+ return err;
}
-static void read_header_files(void)
+static int read_header_files(void)
{
char *path;
struct stat st;
+ int err = -EIO;
path = get_tracing_file("events/header_page");
- if (stat(path, &st) < 0)
- die("can't read '%s'", path);
+ if (!path) {
+ pr_debug("can't get tracing/events/header_page");
+ return -ENOMEM;
+ }
+
+ if (stat(path, &st) < 0) {
+ pr_debug("can't read '%s'", path);
+ goto out;
+ }
+
+ if (write(output_fd, "header_page", 12) != 12) {
+ pr_debug("can't write header_page\n");
+ goto out;
+ }
+
+ if (record_file(path, 8) < 0) {
+ pr_debug("can't record header_page file\n");
+ goto out;
+ }
- write_or_die("header_page", 12);
- record_file(path, 8);
put_tracing_file(path);
path = get_tracing_file("events/header_event");
- if (stat(path, &st) < 0)
- die("can't read '%s'", path);
+ if (!path) {
+ pr_debug("can't get tracing/events/header_event");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ if (stat(path, &st) < 0) {
+ pr_debug("can't read '%s'", path);
+ goto out;
+ }
- write_or_die("header_event", 13);
- record_file(path, 8);
+ if (write(output_fd, "header_event", 13) != 13) {
+ pr_debug("can't write header_event\n");
+ goto out;
+ }
+
+ if (record_file(path, 8) < 0) {
+ pr_debug("can't record header_event file\n");
+ goto out;
+ }
+
+ err = 0;
+out:
put_tracing_file(path);
+ return err;
}
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)
return false;
}
-static void copy_event_system(const char *sys, struct tracepoint_path *tps)
+static int copy_event_system(const char *sys, struct tracepoint_path *tps)
{
struct dirent *dent;
struct stat st;
@@ -233,10 +236,13 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps)
DIR *dir;
int count = 0;
int ret;
+ int err;
dir = opendir(sys);
- if (!dir)
- die("can't read directory '%s'", sys);
+ if (!dir) {
+ pr_debug("can't read directory '%s'", sys);
+ return -errno;
+ }
while ((dent = readdir(dir))) {
if (dent->d_type != DT_DIR ||
@@ -244,7 +250,11 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps)
strcmp(dent->d_name, "..") == 0 ||
!name_in_tp_list(dent->d_name, tps))
continue;
- format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10);
+ format = malloc(strlen(sys) + strlen(dent->d_name) + 10);
+ if (!format) {
+ err = -ENOMEM;
+ goto out;
+ }
sprintf(format, "%s/%s/format", sys, dent->d_name);
ret = stat(format, &st);
free(format);
@@ -253,7 +263,11 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps)
count++;
}
- write_or_die(&count, 4);
+ if (write(output_fd, &count, 4) != 4) {
+ err = -EIO;
+ pr_debug("can't write count\n");
+ goto out;
+ }
rewinddir(dir);
while ((dent = readdir(dir))) {
@@ -262,27 +276,45 @@ static void copy_event_system(const char *sys, struct tracepoint_path *tps)
strcmp(dent->d_name, "..") == 0 ||
!name_in_tp_list(dent->d_name, tps))
continue;
- format = malloc_or_die(strlen(sys) + strlen(dent->d_name) + 10);
+ format = malloc(strlen(sys) + strlen(dent->d_name) + 10);
+ if (!format) {
+ err = -ENOMEM;
+ goto out;
+ }
sprintf(format, "%s/%s/format", sys, dent->d_name);
ret = stat(format, &st);
- if (ret >= 0)
- record_file(format, 8);
-
+ if (ret >= 0) {
+ err = record_file(format, 8);
+ if (err) {
+ free(format);
+ goto out;
+ }
+ }
free(format);
}
+ err = 0;
+out:
closedir(dir);
+ return err;
}
-static void read_ftrace_files(struct tracepoint_path *tps)
+static int read_ftrace_files(struct tracepoint_path *tps)
{
char *path;
+ int ret;
path = get_tracing_file("events/ftrace");
+ if (!path) {
+ pr_debug("can't get tracing/events/ftrace");
+ return -ENOMEM;
+ }
- copy_event_system(path, tps);
+ ret = copy_event_system(path, tps);
put_tracing_file(path);
+
+ return ret;
}
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)
return false;
}
-static void read_event_files(struct tracepoint_path *tps)
+static int read_event_files(struct tracepoint_path *tps)
{
struct dirent *dent;
struct stat st;
@@ -305,12 +337,20 @@ static void read_event_files(struct tracepoint_path *tps)
DIR *dir;
int count = 0;
int ret;
+ int err;
path = get_tracing_file("events");
+ if (!path) {
+ pr_debug("can't get tracing/events");
+ return -ENOMEM;
+ }
dir = opendir(path);
- if (!dir)
- die("can't read directory '%s'", path);
+ if (!dir) {
+ err = -errno;
+ pr_debug("can't read directory '%s'", path);
+ goto out;
+ }
while ((dent = readdir(dir))) {
if (dent->d_type != DT_DIR ||
@@ -322,7 +362,11 @@ static void read_event_files(struct tracepoint_path *tps)
count++;
}
- write_or_die(&count, 4);
+ if (write(output_fd, &count, 4) != 4) {
+ err = -EIO;
+ pr_debug("can't write count\n");
+ goto out;
+ }
rewinddir(dir);
while ((dent = readdir(dir))) {
@@ -332,56 +376,90 @@ static void read_event_files(struct tracepoint_path *tps)
strcmp(dent->d_name, "ftrace") == 0 ||
!system_in_tp_list(dent->d_name, tps))
continue;
- sys = malloc_or_die(strlen(path) + strlen(dent->d_name) + 2);
+ sys = malloc(strlen(path) + strlen(dent->d_name) + 2);
+ if (!sys) {
+ err = -ENOMEM;
+ goto out;
+ }
sprintf(sys, "%s/%s", path, dent->d_name);
ret = stat(sys, &st);
if (ret >= 0) {
- write_or_die(dent->d_name, strlen(dent->d_name) + 1);
- copy_event_system(sys, tps);
+ ssize_t size = strlen(dent->d_name) + 1;
+
+ if (write(output_fd, dent->d_name, size) != size ||
+ copy_event_system(sys, tps) < 0) {
+ err = -EIO;
+ free(sys);
+ goto out;
+ }
}
free(sys);
}
-
+ err = 0;
+out:
closedir(dir);
put_tracing_file(path);
+
+ return err;
}
-static void read_proc_kallsyms(void)
+static int read_proc_kallsyms(void)
{
unsigned int size;
const char *path = "/proc/kallsyms";
struct stat st;
- int ret;
+ int ret, err = 0;
ret = stat(path, &st);
if (ret < 0) {
/* not found */
size = 0;
- write_or_die(&size, 4);
- return;
+ if (write(output_fd, &size, 4) != 4)
+ err = -EIO;
+ return err;
}
- record_file(path, 4);
+ return record_file(path, 4);
}
-static void read_ftrace_printk(void)
+static int read_ftrace_printk(void)
{
unsigned int size;
char *path;
struct stat st;
- int ret;
+ int ret, err = 0;
path = get_tracing_file("printk_formats");
+ if (!path) {
+ pr_debug("can't get tracing/printk_formats");
+ return -ENOMEM;
+ }
+
ret = stat(path, &st);
if (ret < 0) {
/* not found */
size = 0;
- write_or_die(&size, 4);
+ if (write(output_fd, &size, 4) != 4)
+ err = -EIO;
goto out;
}
- record_file(path, 4);
+ err = record_file(path, 4);
out:
put_tracing_file(path);
+ return err;
+}
+
+static void
+put_tracepoints_path(struct tracepoint_path *tps)
+{
+ while (tps) {
+ struct tracepoint_path *t = tps;
+
+ tps = tps->next;
+ free(t->name);
+ free(t->system);
+ free(t);
+ }
}
static struct tracepoint_path *
@@ -396,27 +474,17 @@ get_tracepoints_path(struct list_head *pattrs)
continue;
++nr_tracepoints;
ppath->next = tracepoint_id_to_path(pos->attr.config);
- if (!ppath->next)
- die("%s\n", "No memory to alloc tracepoints list");
+ if (!ppath->next) {
+ pr_debug("No memory to alloc tracepoints list\n");
+ put_tracepoints_path(&path);
+ return NULL;
+ }
ppath = ppath->next;
}
return nr_tracepoints > 0 ? path.next : NULL;
}
-static void
-put_tracepoints_path(struct tracepoint_path *tps)
-{
- while (tps) {
- struct tracepoint_path *t = tps;
-
- tps = tps->next;
- free(t->name);
- free(t->system);
- free(t);
- }
-}
-
bool have_tracepoints(struct list_head *pattrs)
{
struct perf_evsel *pos;
@@ -428,9 +496,10 @@ bool have_tracepoints(struct list_head *pattrs)
return false;
}
-static void tracing_data_header(void)
+static int tracing_data_header(void)
{
char buf[20];
+ ssize_t size;
/* just guessing this is someone's birthday.. ;) */
buf[0] = 23;
@@ -438,9 +507,12 @@ static void tracing_data_header(void)
buf[2] = 68;
memcpy(buf + 3, "tracing", 7);
- write_or_die(buf, 10);
+ if (write(output_fd, buf, 10) != 10)
+ return -1;
- write_or_die(VERSION, strlen(VERSION) + 1);
+ size = strlen(VERSION) + 1;
+ if (write(output_fd, VERSION, size) != size)
+ return -1;
/* save endian */
if (bigendian())
@@ -450,15 +522,19 @@ static void tracing_data_header(void)
read_trace_init(buf[0], buf[0]);
- write_or_die(buf, 1);
+ if (write(output_fd, buf, 1) != 1)
+ return -1;
/* save size of long */
buf[0] = sizeof(long);
- write_or_die(buf, 1);
+ if (write(output_fd, buf, 1) != 1)
+ return -1;
/* save page_size */
- page_size = sysconf(_SC_PAGESIZE);
- write_or_die(&page_size, 4);
+ if (write(output_fd, &page_size, 4) != 4)
+ return -1;
+
+ return 0;
}
struct tracing_data *tracing_data_get(struct list_head *pattrs,
@@ -466,6 +542,7 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
{
struct tracepoint_path *tps;
struct tracing_data *tdata;
+ int err;
output_fd = fd;
@@ -473,7 +550,10 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
if (!tps)
return NULL;
- tdata = malloc_or_die(sizeof(*tdata));
+ tdata = malloc(sizeof(*tdata));
+ if (!tdata)
+ return NULL;
+
tdata->temp = temp;
tdata->size = 0;
@@ -482,12 +562,16 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
snprintf(tdata->temp_file, sizeof(tdata->temp_file),
"/tmp/perf-XXXXXX");
- if (!mkstemp(tdata->temp_file))
- die("Can't make temp file");
+ if (!mkstemp(tdata->temp_file)) {
+ pr_debug("Can't make temp file");
+ return NULL;
+ }
temp_fd = open(tdata->temp_file, O_RDWR);
- if (temp_fd < 0)
- die("Can't read '%s'", tdata->temp_file);
+ if (temp_fd < 0) {
+ pr_debug("Can't read '%s'", tdata->temp_file);
+ return NULL;
+ }
/*
* Set the temp file the default output, so all the
@@ -496,13 +580,24 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
output_fd = temp_fd;
}
- tracing_data_header();
- read_header_files();
- read_ftrace_files(tps);
- read_event_files(tps);
- read_proc_kallsyms();
- read_ftrace_printk();
+ err = tracing_data_header();
+ if (err)
+ goto out;
+ err = read_header_files();
+ if (err)
+ goto out;
+ err = read_ftrace_files(tps);
+ if (err)
+ goto out;
+ err = read_event_files(tps);
+ if (err)
+ goto out;
+ err = read_proc_kallsyms();
+ if (err)
+ goto out;
+ err = read_ftrace_printk();
+out:
/*
* All tracing data are stored by now, we can restore
* the default output file in case we used temp file.
@@ -513,22 +608,31 @@ struct tracing_data *tracing_data_get(struct list_head *pattrs,
output_fd = fd;
}
+ if (err) {
+ free(tdata);
+ tdata = NULL;
+ }
+
put_tracepoints_path(tps);
return tdata;
}
-void tracing_data_put(struct tracing_data *tdata)
+int tracing_data_put(struct tracing_data *tdata)
{
+ int err = 0;
+
if (tdata->temp) {
- record_file(tdata->temp_file, 0);
+ err = record_file(tdata->temp_file, 0);
unlink(tdata->temp_file);
}
free(tdata);
+ return err;
}
int read_tracing_data(int fd, struct list_head *pattrs)
{
+ int err;
struct tracing_data *tdata;
/*
@@ -539,6 +643,6 @@ int read_tracing_data(int fd, struct list_head *pattrs)
if (!tdata)
return -ENOMEM;
- tracing_data_put(tdata);
- return 0;
+ err = tracing_data_put(tdata);
+ return err;
}