aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2015-04-02 03:33:12 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-04-02 12:18:44 -0400
commitc72738355b2ac79506fbfa10ffee8fe3a27e69da (patch)
tree80eb75ac29267a0cf3b70b66af3ef0ffd5c3f551 /tools
parentb83e868d0a0350c107b98417b4dcc73834506f98 (diff)
perf probe: Fix to track down unnamed union/structure members
Fix 'perf probe' to track down unnamed union/structure members. perf probe did not track down the tree of unnamed union/structure members, since it just failed to find given "name" in a parent structure/union. To solve this issue, I've introduced 2 changes. - Fix die_find_member() to track down the type-DIE if it is unnamed, and if it contains the specified member, returns the unnamed member. (note that we don't return found member, since unnamed member has the offset in the parent structure) - Fix convert_variable_fields() to track down the unnamed union/ structure (one-by-one). With this patch, perf probe can access unnamed fields: ----- #./perf probe -nfx ./perf lock__delete ops 'locked_ops=ops->locked.ops' Added new event: probe_perf:lock__delete (on lock__delete in /home/mhiramat/ksrc/linux-3/tools/perf/perf with ops locked_ops=ops->locked.ops) You can now use it in all perf tools, such as: perf record -e probe_perf:lock__delete -aR sleep 1 ----- Reported-by: Arnaldo Carvalho de Melo <acme@kernel.org> Report-Link: https://lkml.org/lkml/2015/3/5/431 Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: David Ahern <dsahern@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20150402073312.14482.37942.stgit@localhost.localdomain Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/dwarf-aux.c14
-rw-r--r--tools/perf/util/probe-finder.c8
2 files changed, 17 insertions, 5 deletions
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index 780b2bc11128..c34e024020c7 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -801,10 +801,16 @@ static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
801{ 801{
802 const char *name = data; 802 const char *name = data;
803 803
804 if ((dwarf_tag(die_mem) == DW_TAG_member) && 804 if (dwarf_tag(die_mem) == DW_TAG_member) {
805 die_compare_name(die_mem, name)) 805 if (die_compare_name(die_mem, name))
806 return DIE_FIND_CB_END; 806 return DIE_FIND_CB_END;
807 807 else if (!dwarf_diename(die_mem)) { /* Unnamed structure */
808 Dwarf_Die type_die, tmp_die;
809 if (die_get_type(die_mem, &type_die) &&
810 die_find_member(&type_die, name, &tmp_die))
811 return DIE_FIND_CB_END;
812 }
813 }
808 return DIE_FIND_CB_SIBLING; 814 return DIE_FIND_CB_SIBLING;
809} 815}
810 816
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 46f009aa486c..7831e2d93949 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -460,7 +460,8 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
460 " nor array.\n", varname); 460 " nor array.\n", varname);
461 return -EINVAL; 461 return -EINVAL;
462 } 462 }
463 if (field->ref) { 463 /* While prcessing unnamed field, we don't care about this */
464 if (field->ref && dwarf_diename(vr_die)) {
464 pr_err("Semantic error: %s must be referred by '.'\n", 465 pr_err("Semantic error: %s must be referred by '.'\n",
465 field->name); 466 field->name);
466 return -EINVAL; 467 return -EINVAL;
@@ -491,6 +492,11 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
491 } 492 }
492 ref->offset += (long)offs; 493 ref->offset += (long)offs;
493 494
495 /* If this member is unnamed, we need to reuse this field */
496 if (!dwarf_diename(die_mem))
497 return convert_variable_fields(die_mem, varname, field,
498 &ref, die_mem);
499
494next: 500next:
495 /* Converting next field */ 501 /* Converting next field */
496 if (field->next) 502 if (field->next)