10 static struct syscall_fmt {
16 { .name =
"arch_prctl", .errmsg =
true, .alias =
"prctl", },
17 { .name =
"fstat", .errmsg =
true, .alias =
"newfstat", },
18 { .name =
"fstatat", .errmsg =
true, .alias =
"newfstatat", },
19 { .name =
"futex", .errmsg =
true, },
20 { .name =
"poll", .errmsg =
true, .timeout =
true, },
21 { .name =
"ppoll", .errmsg =
true, .timeout =
true, },
22 { .name =
"read", .errmsg =
true, },
23 { .name =
"recvfrom", .errmsg =
true, },
24 { .name =
"select", .errmsg =
true, .timeout =
true, },
25 { .name =
"stat", .errmsg =
true, .alias =
"newstat", },
28 static int syscall_fmt__cmp(
const void *
name,
const void *fmtp)
30 const struct syscall_fmt *
fmt = fmtp;
31 return strcmp(name, fmt->name);
34 static struct syscall_fmt *syscall_fmt__find(
const char *
name)
37 return bsearch(name, syscall_fmts, nmemb,
sizeof(
struct syscall_fmt), syscall_fmt__cmp);
43 struct syscall_fmt *
fmt;
55 static int trace__read_syscall_info(
struct trace *
trace,
int id)
59 const char *name = audit_syscall_to_name(
id, trace->
audit_machine);
67 if (nsyscalls ==
NULL)
72 (
id - trace->
syscalls.max) *
sizeof(*sc));
74 memset(nsyscalls, 0, (
id + 1) *
sizeof(*sc));
83 sc->
fmt = syscall_fmt__find(sc->
name);
85 snprintf(tp_name,
sizeof(tp_name),
"sys_enter_%s", sc->
name);
89 snprintf(tp_name,
sizeof(tp_name),
"sys_enter_%s", sc->
fmt->alias);
96 static size_t syscall__fprintf_args(
struct syscall *sc,
unsigned long *args, FILE *
fp)
104 for (field = sc->
tp_format->format.fields->next; field; field = field->
next) {
105 printed +=
fprintf(fp,
"%s%s: %ld", printed ?
", " :
"",
106 field->
name, args[i++]);
110 printed +=
fprintf(fp,
"%sarg%d: %ld", printed ?
", " :
"", i, args[i]);
121 static struct syscall *trace__syscall_info(
struct trace *trace,
128 printf(
"Invalid syscall %d id, skipping...\n",
id);
133 trace__read_syscall_info(trace,
id))
142 printf(
"Problems reading syscall %d information\n",
id);
146 static int trace__sys_enter(
struct trace *trace,
struct perf_evsel *evsel,
150 struct syscall *sc = trace__syscall_info(trace, evsel, sample);
157 printf(
"Problems reading syscall arguments\n");
162 syscall__fprintf_args(sc, args, stdout);
167 static int trace__sys_exit(
struct trace *trace,
struct perf_evsel *evsel,
171 struct syscall *sc = trace__syscall_info(trace, evsel, sample);
178 if (ret < 0 && sc->
fmt && sc->
fmt->errmsg) {
180 const char *emsg = strerror_r(-ret, bf,
sizeof(bf)),
181 *
e = audit_errno_to_name(-ret);
183 printf(
") = -1 %s %s",
e, emsg);
184 }
else if (ret == 0 && sc->
fmt && sc->
fmt->timeout)
193 static int trace__run(
struct trace *trace)
197 int err = -1,
i, nr_events = 0, before;
199 if (evlist ==
NULL) {
200 printf(
"Not enough memory to run!\n");
206 printf(
"Couldn't read the raw_syscalls tracepoints information!\n");
207 goto out_delete_evlist;
212 printf(
"Problems parsing the target to trace, check your options!\n");
213 goto out_delete_evlist;
221 goto out_delete_evlist;
227 goto out_delete_evlist;
234 for (i = 0; i < evlist->
nr_mmaps; i++) {
238 const u32 type =
event->header.type;
251 printf(
"Unexpected %s event, skipping...\n",
258 printf(
"Can't parse sample, err = %d, skipping...\n", err);
272 printf(
"%s sample with no payload for tid: %d, cpu %d, raw_size=%d, skipping...\n",
279 handler(trace, evsel, &sample);
283 if (nr_events == before)
296 const char *
const trace_usage[] = {
297 "perf trace [<options>]",
300 struct trace trace = {
316 const struct option trace_options[] = {
318 "trace events on existing process id"),
320 "trace events on existing thread id"),
322 "system-wide collection from all CPUs"),
324 "list of cpus to monitor"),
326 "child tasks do not inherit counters"),
328 "number of mmap data pages"),
335 argc =
parse_options(argc, argv, trace_options, trace_usage, 0);
347 return trace__run(&trace);