diff options
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 @@ #include <libaudit.h> #include <stdlib.h> +static size_t syscall_arg__scnprintf_hex(char *bf, size_t size, unsigned long arg) +{ + return scnprintf(bf, size, "%#lx", arg); +} + static struct syscall_fmt { const char *name; const char *alias; @@ -51,6 +56,7 @@ struct syscall { const char *name; bool filtered; struct syscall_fmt *fmt; + size_t (**arg_scnprintf)(char *bf, size_t size, unsigned long arg); }; 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) return err; } +static int syscall__set_arg_fmts(struct syscall *sc) +{ + struct format_field *field; + int idx = 0; + + sc->arg_scnprintf = calloc(sc->tp_format->format.nr_fields - 1, sizeof(void *)); + if (sc->arg_scnprintf == NULL) + return -1; + + for (field = sc->tp_format->format.fields->next; field; field = field->next) { + if (field->flags & FIELD_IS_POINTER) + sc->arg_scnprintf[idx] = syscall_arg__scnprintf_hex; + ++idx; + } + + return 0; +} + static int trace__read_syscall_info(struct trace *trace, int id) { char tp_name[128]; @@ -259,7 +283,10 @@ static int trace__read_syscall_info(struct trace *trace, int id) sc->tp_format = event_format__new("syscalls", tp_name); } - return sc->tp_format != NULL ? 0 : -1; + if (sc->tp_format == NULL) + return -1; + + return syscall__set_arg_fmts(sc); } 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, for (field = sc->tp_format->format.fields->next; field; field = field->next) { printed += scnprintf(bf + printed, size - printed, - "%s%s: %ld", printed ? ", " : "", - field->name, args[i++]); + "%s%s: ", printed ? ", " : "", field->name); + + if (sc->arg_scnprintf && sc->arg_scnprintf[i]) + printed += sc->arg_scnprintf[i](bf + printed, size - printed, args[i]); + else + printed += scnprintf(bf + printed, size - printed, + "%ld", args[i]); + ++i; } } else { while (i < 6) { |