perf probe: Fix to search local variables in appropriate scope
Fix perf probe to search local variables in appropriate local inlined function scope. For example, pre_schedule() has only 2 local variables, as below; $ perf probe -L pre_schedule <pre_schedule@/home/mhiramat/ksrc/linux-2.6/kernel/sched.c:0> 0 static inline void pre_schedule(struct rq *rq, struct task_struct *prev) { 2 if (prev->sched_class->pre_schedule) 3 prev->sched_class->pre_schedule(rq, prev); } However, current perf probe shows 4 local variables on pre_schedule(), because it searches variables in the caller(schedule()) scope. $ perf probe -V pre_schedule Available variables at pre_schedule @<schedule+445> int cpu long unsigned int* switch_count struct rq* rq struct task_struct* prev This patch fixes this issue by searching variables in the local scope of the instance of inlined function. Here is the result. $ perf probe -V pre_schedule Available variables at pre_schedule @<schedule+445> struct rq* rq struct task_struct* prev Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Paul Mackerras <paulus@samba.org> Cc: Pekka Enberg <penberg@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: yrl.pp-manager.tt@hitachi.com Link: http://lkml.kernel.org/r/20110811110259.19900.85664.stgit@fedora15 Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
committed by
Arnaldo Carvalho de Melo
parent
13e27d7686
commit
221d061182
@@ -96,6 +96,39 @@ int cu_find_lineinfo(Dwarf_Die *cu_die, unsigned long addr,
|
||||
return *lineno ?: -ENOENT;
|
||||
}
|
||||
|
||||
static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data);
|
||||
|
||||
/**
|
||||
* cu_walk_functions_at - Walk on function DIEs at given address
|
||||
* @cu_die: A CU DIE
|
||||
* @addr: An address
|
||||
* @callback: A callback which called with found DIEs
|
||||
* @data: A user data
|
||||
*
|
||||
* Walk on function DIEs at given @addr in @cu_die. Passed DIEs
|
||||
* should be subprogram or inlined-subroutines.
|
||||
*/
|
||||
int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr,
|
||||
int (*callback)(Dwarf_Die *, void *), void *data)
|
||||
{
|
||||
Dwarf_Die die_mem;
|
||||
Dwarf_Die *sc_die;
|
||||
int ret = -ENOENT;
|
||||
|
||||
/* Inlined function could be recursive. Trace it until fail */
|
||||
for (sc_die = die_find_realfunc(cu_die, addr, &die_mem);
|
||||
sc_die != NULL;
|
||||
sc_die = die_find_child(sc_die, __die_find_inline_cb, &addr,
|
||||
&die_mem)) {
|
||||
ret = callback(sc_die, data);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* die_compare_name - Compare diename and tname
|
||||
* @dw_die: a DIE
|
||||
|
Reference in New Issue
Block a user