aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-finder.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2010-10-21 06:13:09 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-10-21 13:58:05 -0400
commit378eeaad3e1cfea7f6614018fb335de93df2ba1f (patch)
treeb087b3b760bfb000d5a6a2ae58f77d984a2f9365 /tools/perf/util/probe-finder.c
parent4046b8bb5ffae9ee916e504cdadee804f10e0c56 (diff)
perf probe: Fix local variable searching loop
Fix to check the die's address and search into the die only if it has given address. This will avoid finding wrong variables in wrong basic block. Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Ingo Molnar <mingo@elte.hu> LKML-Reference: <20101021101309.3542.46434.stgit@ltc236.sdl.hitachi.co.jp> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/probe-finder.c')
-rw-r--r--tools/perf/util/probe-finder.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index a2d1f790d937..abcaec555204 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -329,25 +329,35 @@ static Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr,
329 return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem); 329 return die_find_child(sp_die, __die_find_inline_cb, &addr, die_mem);
330} 330}
331 331
332struct __find_variable_param {
333 const char *name;
334 Dwarf_Addr addr;
335};
336
332static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data) 337static int __die_find_variable_cb(Dwarf_Die *die_mem, void *data)
333{ 338{
334 const char *name = data; 339 struct __find_variable_param *fvp = data;
335 int tag; 340 int tag;
336 341
337 tag = dwarf_tag(die_mem); 342 tag = dwarf_tag(die_mem);
338 if ((tag == DW_TAG_formal_parameter || 343 if ((tag == DW_TAG_formal_parameter ||
339 tag == DW_TAG_variable) && 344 tag == DW_TAG_variable) &&
340 die_compare_name(die_mem, name)) 345 die_compare_name(die_mem, fvp->name))
341 return DIE_FIND_CB_FOUND; 346 return DIE_FIND_CB_FOUND;
342 347
343 return DIE_FIND_CB_CONTINUE; 348 if (dwarf_haspc(die_mem, fvp->addr))
349 return DIE_FIND_CB_CONTINUE;
350 else
351 return DIE_FIND_CB_SIBLING;
344} 352}
345 353
346/* Find a variable called 'name' */ 354/* Find a variable called 'name' at given address */
347static Dwarf_Die *die_find_variable(Dwarf_Die *sp_die, const char *name, 355static Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name,
348 Dwarf_Die *die_mem) 356 Dwarf_Addr addr, Dwarf_Die *die_mem)
349{ 357{
350 return die_find_child(sp_die, __die_find_variable_cb, (void *)name, 358 struct __find_variable_param fvp = { .name = name, .addr = addr};
359
360 return die_find_child(sp_die, __die_find_variable_cb, (void *)&fvp,
351 die_mem); 361 die_mem);
352} 362}
353 363
@@ -731,7 +741,7 @@ static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf)
731 pr_debug("Searching '%s' variable in context.\n", 741 pr_debug("Searching '%s' variable in context.\n",
732 pf->pvar->var); 742 pf->pvar->var);
733 /* Search child die for local variables and parameters. */ 743 /* Search child die for local variables and parameters. */
734 if (die_find_variable(sp_die, pf->pvar->var, &vr_die)) 744 if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die))
735 ret = convert_variable(&vr_die, pf); 745 ret = convert_variable(&vr_die, pf);
736 else { 746 else {
737 /* Search upper class */ 747 /* Search upper class */