Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 333936
b: refs/heads/master
c: ba3d7de
h: refs/heads/master
v: v3
  • Loading branch information
Arnaldo Carvalho de Melo committed Oct 2, 2012
1 parent 9de35a9 commit aff2616
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 46 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d6e66832a710c0e6d1376e8d39ee108636a177e7
refs/heads/master: ba3d7deeef7fafdab7814e298fa2db0fc63bb5d0
132 changes: 87 additions & 45 deletions trunk/tools/perf/builtin-trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,32 +114,109 @@ static size_t syscall__fprintf_args(struct syscall *sc, unsigned long *args, FIL
return printed;
}

typedef int (*tracepoint_handler)(struct trace *trace, struct perf_evsel *evsel,
struct perf_sample *sample);

static struct syscall *trace__syscall_info(struct trace *trace,
struct perf_evsel *evsel,
struct perf_sample *sample)
{
int id = perf_evsel__intval(evsel, sample, "id");

if (id < 0) {
printf("Invalid syscall %d id, skipping...\n", id);
return NULL;
}

if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) &&
trace__read_syscall_info(trace, id))
goto out_cant_read;

if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL))
goto out_cant_read;

return &trace->syscalls.table[id];

out_cant_read:
printf("Problems reading syscall %d information\n", id);
return NULL;
}

static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel,
struct perf_sample *sample)
{
void *args;
struct syscall *sc = trace__syscall_info(trace, evsel, sample);

if (sc == NULL)
return -1;

args = perf_evsel__rawptr(evsel, sample, "args");
if (args == NULL) {
printf("Problems reading syscall arguments\n");
return -1;
}

printf("%s(", sc->name);
syscall__fprintf_args(sc, args, stdout);

return 0;
}

static int trace__sys_exit(struct trace *trace, struct perf_evsel *evsel,
struct perf_sample *sample)
{
int ret;
struct syscall *sc = trace__syscall_info(trace, evsel, sample);

if (sc == NULL)
return -1;

ret = perf_evsel__intval(evsel, sample, "ret");

if (ret < 0 && sc->fmt && sc->fmt->errmsg) {
char bf[256];
const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
*e = audit_errno_to_name(-ret);

printf(") = -1 %s %s", e, emsg);
} else if (ret == 0 && sc->fmt && sc->fmt->timeout)
printf(") = 0 Timeout");
else
printf(") = %d", ret);

putchar('\n');
return 0;
}

static int trace__run(struct trace *trace)
{
struct perf_evlist *evlist = perf_evlist__new(NULL, NULL);
struct perf_evsel *evsel, *evsel_enter, *evsel_exit;
struct perf_evsel *evsel;
int err = -1, i, nr_events = 0, before;

if (evlist == NULL) {
printf("Not enough memory to run!\n");
goto out;
}

evsel_enter = perf_evsel__newtp("raw_syscalls", "sys_enter", 0);
if (evsel_enter == NULL) {
evsel = perf_evsel__newtp("raw_syscalls", "sys_enter", 0);
if (evsel == NULL) {
printf("Couldn't read the raw_syscalls:sys_enter tracepoint information!\n");
goto out_delete_evlist;
}

perf_evlist__add(evlist, evsel_enter);
evsel->handler.func = trace__sys_enter;
perf_evlist__add(evlist, evsel);

evsel_exit = perf_evsel__newtp("raw_syscalls", "sys_exit", 1);
if (evsel_exit == NULL) {
evsel = perf_evsel__newtp("raw_syscalls", "sys_exit", 1);
if (evsel == NULL) {
printf("Couldn't read the raw_syscalls:sys_exit tracepoint information!\n");
goto out_delete_evlist;
}

perf_evlist__add(evlist, evsel_exit);
evsel->handler.func = trace__sys_exit;
perf_evlist__add(evlist, evsel);

err = perf_evlist__create_maps(evlist, &trace->opts.target);
if (err < 0) {
Expand Down Expand Up @@ -170,9 +247,8 @@ static int trace__run(struct trace *trace)

while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
const u32 type = event->header.type;
struct syscall *sc;
tracepoint_handler handler;
struct perf_sample sample;
int id;

++nr_events;

Expand Down Expand Up @@ -200,45 +276,11 @@ static int trace__run(struct trace *trace)
continue;
}

id = perf_evsel__intval(evsel, &sample, "id");
if (id < 0) {
printf("Invalid syscall %d id, skipping...\n", id);
continue;
}

if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL) &&
trace__read_syscall_info(trace, id))
continue;

if ((id > trace->syscalls.max || trace->syscalls.table[id].name == NULL))
continue;

sc = &trace->syscalls.table[id];

if (evlist->threads->map[0] == -1 || evlist->threads->nr > 1)
printf("%d ", sample.tid);

if (evsel == evsel_enter) {
void *args = perf_evsel__rawptr(evsel, &sample, "args");

printf("%s(", sc->name);
syscall__fprintf_args(sc, args, stdout);
} else if (evsel == evsel_exit) {
int ret = perf_evsel__intval(evsel, &sample, "ret");

if (ret < 0 && sc->fmt && sc->fmt->errmsg) {
char bf[256];
const char *emsg = strerror_r(-ret, bf, sizeof(bf)),
*e = audit_errno_to_name(-ret);

printf(") = -1 %s %s", e, emsg);
} else if (ret == 0 && sc->fmt && sc->fmt->timeout)
printf(") = 0 Timeout");
else
printf(") = %d", ret);

putchar('\n');
}
handler = evsel->handler.func;
handler(trace, evsel, &sample);
}
}

Expand Down

0 comments on commit aff2616

Please sign in to comment.