diff options
author | Masami Hiramatsu <mhiramat@redhat.com> | 2010-04-12 13:16:53 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-04-14 16:26:04 -0400 |
commit | 48481938b02471d505296d7557ed296eb093d496 (patch) | |
tree | 7549d861d76621d1e3d2ddd75eae4575901f1fd0 /tools/perf/util/probe-event.c | |
parent | fcd1498405c2c88ac632e7c3c3fce3213d9196db (diff) |
perf probe: Support argument name
Set given names to event arguments. The syntax is same as kprobe-tracer,
you can add 'NAME=' right before each argument.
e.g.
./perf probe vfs_read foo=file
then, 'foo' is set to the argument name as below.
./perf probe -l
probe:vfs_read (on vfs_read@linux-2.6-tip/fs/read_write.c with foo)
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
LKML-Reference: <20100412171653.3790.74624.stgit@localhost6.localdomain6>
Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r-- | tools/perf/util/probe-event.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 3fc0be741b8e..ab6f53deabad 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -437,22 +437,28 @@ static void parse_perf_probe_point(char *arg, struct perf_probe_event *pev) | |||
437 | /* Parse perf-probe event argument */ | 437 | /* Parse perf-probe event argument */ |
438 | static void parse_perf_probe_arg(const char *str, struct perf_probe_arg *arg) | 438 | static void parse_perf_probe_arg(const char *str, struct perf_probe_arg *arg) |
439 | { | 439 | { |
440 | const char *tmp; | 440 | char *tmp; |
441 | struct perf_probe_arg_field **fieldp; | 441 | struct perf_probe_arg_field **fieldp; |
442 | 442 | ||
443 | pr_debug("parsing arg: %s into ", str); | 443 | pr_debug("parsing arg: %s into ", str); |
444 | 444 | ||
445 | tmp = strchr(str, '='); | ||
446 | if (tmp) { | ||
447 | arg->name = xstrndup(str, tmp - str); | ||
448 | str = tmp + 1; | ||
449 | } | ||
450 | |||
445 | tmp = strpbrk(str, "-."); | 451 | tmp = strpbrk(str, "-."); |
446 | if (!is_c_varname(str) || !tmp) { | 452 | if (!is_c_varname(str) || !tmp) { |
447 | /* A variable, register, symbol or special value */ | 453 | /* A variable, register, symbol or special value */ |
448 | arg->name = xstrdup(str); | 454 | arg->var = xstrdup(str); |
449 | pr_debug("%s\n", arg->name); | 455 | pr_debug("%s\n", arg->var); |
450 | return; | 456 | return; |
451 | } | 457 | } |
452 | 458 | ||
453 | /* Structure fields */ | 459 | /* Structure fields */ |
454 | arg->name = xstrndup(str, tmp - str); | 460 | arg->var = xstrndup(str, tmp - str); |
455 | pr_debug("%s, ", arg->name); | 461 | pr_debug("%s, ", arg->var); |
456 | fieldp = &arg->field; | 462 | fieldp = &arg->field; |
457 | 463 | ||
458 | do { | 464 | do { |
@@ -497,7 +503,7 @@ void parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev) | |||
497 | pev->args = xzalloc(sizeof(struct perf_probe_arg) * pev->nargs); | 503 | pev->args = xzalloc(sizeof(struct perf_probe_arg) * pev->nargs); |
498 | for (i = 0; i < pev->nargs; i++) { | 504 | for (i = 0; i < pev->nargs; i++) { |
499 | parse_perf_probe_arg(argv[i + 1], &pev->args[i]); | 505 | parse_perf_probe_arg(argv[i + 1], &pev->args[i]); |
500 | if (is_c_varname(pev->args[i].name) && pev->point.retprobe) | 506 | if (is_c_varname(pev->args[i].var) && pev->point.retprobe) |
501 | semantic_error("You can't specify local variable for" | 507 | semantic_error("You can't specify local variable for" |
502 | " kretprobe"); | 508 | " kretprobe"); |
503 | } | 509 | } |
@@ -514,7 +520,7 @@ bool perf_probe_event_need_dwarf(struct perf_probe_event *pev) | |||
514 | return true; | 520 | return true; |
515 | 521 | ||
516 | for (i = 0; i < pev->nargs; i++) | 522 | for (i = 0; i < pev->nargs; i++) |
517 | if (is_c_varname(pev->args[i].name)) | 523 | if (is_c_varname(pev->args[i].var)) |
518 | return true; | 524 | return true; |
519 | 525 | ||
520 | return false; | 526 | return false; |
@@ -575,7 +581,10 @@ int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len) | |||
575 | int ret; | 581 | int ret; |
576 | char *tmp = buf; | 582 | char *tmp = buf; |
577 | 583 | ||
578 | ret = e_snprintf(tmp, len, "%s", pa->name); | 584 | if (pa->name && pa->var) |
585 | ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var); | ||
586 | else | ||
587 | ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var); | ||
579 | if (ret <= 0) | 588 | if (ret <= 0) |
580 | goto error; | 589 | goto error; |
581 | tmp += ret; | 590 | tmp += ret; |
@@ -803,6 +812,8 @@ void clear_perf_probe_event(struct perf_probe_event *pev) | |||
803 | for (i = 0; i < pev->nargs; i++) { | 812 | for (i = 0; i < pev->nargs; i++) { |
804 | if (pev->args[i].name) | 813 | if (pev->args[i].name) |
805 | free(pev->args[i].name); | 814 | free(pev->args[i].name); |
815 | if (pev->args[i].var) | ||
816 | free(pev->args[i].var); | ||
806 | field = pev->args[i].field; | 817 | field = pev->args[i].field; |
807 | while (field) { | 818 | while (field) { |
808 | next = field->next; | 819 | next = field->next; |
@@ -1117,8 +1128,11 @@ static int convert_to_kprobe_trace_events(struct perf_probe_event *pev, | |||
1117 | if (tev->nargs) { | 1128 | if (tev->nargs) { |
1118 | tev->args = xzalloc(sizeof(struct kprobe_trace_arg) | 1129 | tev->args = xzalloc(sizeof(struct kprobe_trace_arg) |
1119 | * tev->nargs); | 1130 | * tev->nargs); |
1120 | for (i = 0; i < tev->nargs; i++) | 1131 | for (i = 0; i < tev->nargs; i++) { |
1121 | tev->args[i].value = xstrdup(pev->args[i].name); | 1132 | if (pev->args[i].name) |
1133 | tev->args[i].name = xstrdup(pev->args[i].name); | ||
1134 | tev->args[i].value = xstrdup(pev->args[i].var); | ||
1135 | } | ||
1122 | } | 1136 | } |
1123 | 1137 | ||
1124 | /* Currently just checking function name from symbol map */ | 1138 | /* Currently just checking function name from symbol map */ |