diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-08-23 17:14:48 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-08-26 16:25:47 -0400 |
commit | 13d4ff3eb36474728be2acfa773b31ff39f3ea4d (patch) | |
tree | 2635d824bb6fc1f8f03aae0fd77d45b380826d76 /tools | |
parent | adaa18bf5d9128c4a34f5350b1d46555a949ebc4 (diff) |
perf trace: Introduce syscall arg formatters
Starting with one for printing pointers in hexadecimal, using the
information in the syscall tracepoint format.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-c4y4jy7qqkn8wsd8q6j1g7zh@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-trace.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index c3caabbe18fa..86568ed53ac4 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -12,6 +12,11 @@ | |||
12 | #include <libaudit.h> | 12 | #include <libaudit.h> |
13 | #include <stdlib.h> | 13 | #include <stdlib.h> |
14 | 14 | ||
15 | static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, unsigned long arg) | ||
16 | { | ||
17 | return scnprintf(bf, size, "%#lx", arg); | ||
18 | } | ||
19 | |||
15 | static struct syscall_fmt { | 20 | static struct syscall_fmt { |
16 | const char *name; | 21 | const char *name; |
17 | const char *alias; | 22 | const char *alias; |
@@ -51,6 +56,7 @@ struct syscall { | |||
51 | const char *name; | 56 | const char *name; |
52 | bool filtered; | 57 | bool filtered; |
53 | struct syscall_fmt *fmt; | 58 | struct syscall_fmt *fmt; |
59 | size_t (**arg_scnprintf)(char *bf, size_t size, unsigned long arg); | ||
54 | }; | 60 | }; |
55 | 61 | ||
56 | static size_t fprintf_duration(unsigned long t, FILE *fp) | 62 | static size_t fprintf_duration(unsigned long t, FILE *fp) |
@@ -207,6 +213,24 @@ static int trace__symbols_init(struct trace *trace, struct perf_evlist *evlist) | |||
207 | return err; | 213 | return err; |
208 | } | 214 | } |
209 | 215 | ||
216 | static int syscall__set_arg_fmts(struct syscall *sc) | ||
217 | { | ||
218 | struct format_field *field; | ||
219 | int idx = 0; | ||
220 | |||
221 | sc->arg_scnprintf = calloc(sc->tp_format->format.nr_fields - 1, sizeof(void *)); | ||
222 | if (sc->arg_scnprintf == NULL) | ||
223 | return -1; | ||
224 | |||
225 | for (field = sc->tp_format->format.fields->next; field; field = field->next) { | ||
226 | if (field->flags & FIELD_IS_POINTER) | ||
227 | sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex; | ||
228 | ++idx; | ||
229 | } | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
210 | static int trace__read_syscall_info(struct trace *trace, int id) | 234 | static int trace__read_syscall_info(struct trace *trace, int id) |
211 | { | 235 | { |
212 | char tp_name[128]; | 236 | char tp_name[128]; |
@@ -259,7 +283,10 @@ static int trace__read_syscall_info(struct trace *trace, int id) | |||
259 | sc->tp_format = event_format__new("syscalls", tp_name); | 283 | sc->tp_format = event_format__new("syscalls", tp_name); |
260 | } | 284 | } |
261 | 285 | ||
262 | return sc->tp_format != NULL ? 0 : -1; | 286 | if (sc->tp_format == NULL) |
287 | return -1; | ||
288 | |||
289 | return syscall__set_arg_fmts(sc); | ||
263 | } | 290 | } |
264 | 291 | ||
265 | static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, | 292 | static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, |
@@ -273,8 +300,14 @@ static size_t syscall__scnprintf_args(struct syscall *sc, char *bf, size_t size, | |||
273 | 300 | ||
274 | for (field = sc->tp_format->format.fields->next; field; field = field->next) { | 301 | for (field = sc->tp_format->format.fields->next; field; field = field->next) { |
275 | printed += scnprintf(bf + printed, size - printed, | 302 | printed += scnprintf(bf + printed, size - printed, |
276 | "%s%s: %ld", printed ? ", " : "", | 303 | "%s%s: ", printed ? ", " : "", field->name); |
277 | field->name, args[i++]); | 304 | |
305 | if (sc->arg_scnprintf && sc->arg_scnprintf[i]) | ||
306 | printed += sc->arg_scnprintf[i](bf + printed, size - printed, args[i]); | ||
307 | else | ||
308 | printed += scnprintf(bf + printed, size - printed, | ||
309 | "%ld", args[i]); | ||
310 | ++i; | ||
278 | } | 311 | } |
279 | } else { | 312 | } else { |
280 | while (i < 6) { | 313 | while (i < 6) { |