aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2010-05-19 15:57:35 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-07-05 17:47:28 -0400
commit73317b954041031249e8968d2e9023ff4e960d99 (patch)
tree44768b7724bacbb15c54057710c70accce1cd8c3 /tools/perf
parente09c8614b32915c16f68e039ac7040e602d73e35 (diff)
perf probe: Support "string" type
Support string type casting to event argument. If perf-probe finds an argument casted as string, it ensures the target variable is "(unsigned/signed) char *(or []). perf-probe also adds dereference if the target is a pointer. So, both of 'char buf[10];' and 'char *buf;' can be accessed by 'buf:string' 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: <20100519195734.2885.1666.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')
-rw-r--r--tools/perf/Documentation/perf-probe.txt2
-rw-r--r--tools/perf/util/probe-finder.c59
2 files changed, 49 insertions, 12 deletions
diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index ea531d9d975c..394016d33ce3 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -95,7 +95,7 @@ Each probe argument follows below syntax.
95 [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE] 95 [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE]
96 96
97'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.) 97'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
98'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo. 98'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo. You can specify 'string' type only for the local variable or structure member which is an array of or a pointer to 'char' or 'unsigned char' type.
99 99
100LINE SYNTAX 100LINE SYNTAX
101----------- 101-----------
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index baf665383498..aaea16b1c60b 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -464,18 +464,61 @@ static int convert_location(Dwarf_Op *op, struct probe_finder *pf)
464} 464}
465 465
466static int convert_variable_type(Dwarf_Die *vr_die, 466static int convert_variable_type(Dwarf_Die *vr_die,
467 struct kprobe_trace_arg *targ) 467 struct kprobe_trace_arg *tvar,
468 const char *cast)
468{ 469{
470 struct kprobe_trace_arg_ref **ref_ptr = &tvar->ref;
469 Dwarf_Die type; 471 Dwarf_Die type;
470 char buf[16]; 472 char buf[16];
471 int ret; 473 int ret;
472 474
475 /* TODO: check all types */
476 if (cast && strcmp(cast, "string") != 0) {
477 /* Non string type is OK */
478 tvar->type = strdup(cast);
479 return (tvar->type == NULL) ? -ENOMEM : 0;
480 }
481
473 if (die_get_real_type(vr_die, &type) == NULL) { 482 if (die_get_real_type(vr_die, &type) == NULL) {
474 pr_warning("Failed to get a type information of %s.\n", 483 pr_warning("Failed to get a type information of %s.\n",
475 dwarf_diename(vr_die)); 484 dwarf_diename(vr_die));
476 return -ENOENT; 485 return -ENOENT;
477 } 486 }
478 487
488 if (cast && strcmp(cast, "string") == 0) { /* String type */
489 ret = dwarf_tag(&type);
490 if (ret != DW_TAG_pointer_type &&
491 ret != DW_TAG_array_type) {
492 pr_warning("Failed to cast into string: "
493 "%s(%s) is not a pointer nor array.",
494 dwarf_diename(vr_die), dwarf_diename(&type));
495 return -EINVAL;
496 }
497 if (ret == DW_TAG_pointer_type) {
498 if (die_get_real_type(&type, &type) == NULL) {
499 pr_warning("Failed to get a type information.");
500 return -ENOENT;
501 }
502 while (*ref_ptr)
503 ref_ptr = &(*ref_ptr)->next;
504 /* Add new reference with offset +0 */
505 *ref_ptr = zalloc(sizeof(struct kprobe_trace_arg_ref));
506 if (*ref_ptr == NULL) {
507 pr_warning("Out of memory error\n");
508 return -ENOMEM;
509 }
510 }
511 if (die_compare_name(&type, "char") != 0 &&
512 die_compare_name(&type, "unsigned char") != 0) {
513 pr_warning("Failed to cast into string: "
514 "%s is not (unsigned) char *.",
515 dwarf_diename(vr_die));
516 return -EINVAL;
517 }
518 tvar->type = strdup(cast);
519 return (tvar->type == NULL) ? -ENOMEM : 0;
520 }
521
479 ret = die_get_byte_size(&type) * 8; 522 ret = die_get_byte_size(&type) * 8;
480 if (ret) { 523 if (ret) {
481 /* Check the bitwidth */ 524 /* Check the bitwidth */
@@ -495,8 +538,8 @@ static int convert_variable_type(Dwarf_Die *vr_die,
495 strerror(-ret)); 538 strerror(-ret));
496 return ret; 539 return ret;
497 } 540 }
498 targ->type = strdup(buf); 541 tvar->type = strdup(buf);
499 if (targ->type == NULL) 542 if (tvar->type == NULL)
500 return -ENOMEM; 543 return -ENOMEM;
501 } 544 }
502 return 0; 545 return 0;
@@ -606,14 +649,8 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
606 &die_mem); 649 &die_mem);
607 vr_die = &die_mem; 650 vr_die = &die_mem;
608 } 651 }
609 if (ret == 0) { 652 if (ret == 0)
610 if (pf->pvar->type) { 653 ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type);
611 pf->tvar->type = strdup(pf->pvar->type);
612 if (pf->tvar->type == NULL)
613 ret = -ENOMEM;
614 } else
615 ret = convert_variable_type(vr_die, pf->tvar);
616 }
617 /* *expr will be cached in libdw. Don't free it. */ 654 /* *expr will be cached in libdw. Don't free it. */
618 return ret; 655 return ret;
619error: 656error: