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) { |
