perf-probe: Fix to show lines of sys_ functions correctly
PATCH v2 1/1 perf-probe: Fix to show lines of sys_ functions correctly
"perf probe --lines sys_poll" shows only the first line of sys_poll, because the SYSCALL_DEFINE macro
----
SYSCALL_DEFINE*(foo,...)
{
body;
}
----
is expanded as below (on debuginfo)
----
static inline int SYSC_foo(...)
{
body;
}
int SyS_foo(...) <- is an alias of sys_foo.
{
return SYSC_foo(...);
}
----
So, "perf probe --lines sys_foo" decodes SyS_foo function and it also skips inlined functions(SYSC_foo) inside the target function because those functions are usually defined somewhere else.
To fix this issue, this fix checks whether the inlined function is defined at the same point of the target function, and if so, it doesn't skip the inline function.
---
Changes in v2
- Fix to add a brace to if statement.
--- tools/perf/util/dwarf-aux.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
tools/perf/util/dwarf-aux.c +15 -6
@@ -734,15 +734,18 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)Dwarf_Lines *lines;Dwarf_Line *line;Dwarf_Addr addr; -const char *fname; +const char *fname, *decf =NULL ;int lineno, ret =0 ; +int decl =0 , inl;Dwarf_Die die_mem, *cu_die;size_t nlines, i;/* Get the CU die */ -if (dwarf_tag (rt_die) != DW_TAG_compile_unit) +if (dwarf_tag (rt_die) != DW_TAG_compile_unit) { cu_die =dwarf_diecu (rt_die, &die_mem,NULL ,NULL ); -else +dwarf_decl_line (rt_die, &decl); + decf =dwarf_decl_file (rt_die); + }else cu_die = rt_die;if (!cu_die) {pr_debug2 ("Failed to get CU from given DIE.\n" );
@@ -767,15 +770,21 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)continue ; }/* Filter lines based on address */ -if (rt_die != cu_die) +if (rt_die != cu_die) {/* * Address filtering * The line is included in given function, and * no inline block includes it. */ -if (!dwarf_haspc (rt_die, addr) || -die_find_inlinefunc (rt_die, addr, &die_mem)) +if (!dwarf_haspc (rt_die, addr))continue ; +if (die_find_inlinefunc (rt_die, addr, &die_mem)) { +dwarf_decl_line (&die_mem, &inl); +if (inl != decl || + decf !=dwarf_decl_file (&die_mem)) +continue ; + } + }/* Get source line */ fname =dwarf_linesrc (line,NULL ,NULL );
Sorry, please ignore this. the original one already merged. I'll send diff patch.
Thanks!
Quoted 82 lines
From: Masami Hiramatsu [mailto:[email protected]]
"perf probe --lines
sys_poll" shows only the first line ofsys_poll, because theSYSCALL_DEFINEmacro
----
SYSCALL_DEFINE*(foo,...)
{
body;
}
----
is expanded as below (on debuginfo)----
static inline intSYSC_foo(...)
{
body;
}
intSyS_foo(...)<- is an alias ofsys_foo.
{
returnSYSC_foo(...);
}
----So, "perf probe --lines
sys_foo" decodesSyS_foofunction and it also skips inlinedfunctions(SYSC_foo)inside the target function because those functions are usually defined somewhere else.To fix this issue, this fix checks whether the inlined function is defined at the same point of the target function, and if so, it doesn't skip the inline function.
Reported-by Arnaldo Carvalho de Melo <[email protected]>Signed-off-by Masami Hiramatsu <[email protected]>---
Changes in v2
- Fix to add a brace to if statement.--- tools/perf/util/dwarf-aux.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)tools/perf/util/dwarf-aux.c +8
-6@@ -734,15 +734,18 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)Dwarf_Lines *lines;Dwarf_Line *line;Dwarf_Addr addr; -const char *fname; +const char *fname, *decf =NULL ;int lineno, ret =0 ; +int decl =0 , inl;Dwarf_Die die_mem, *cu_die;size_t nlines, i;/* Get the CU die */ -if (dwarf_tag (rt_die) != DW_TAG_compile_unit) +if (dwarf_tag (rt_die) != DW_TAG_compile_unit) { cu_die =dwarf_diecu (rt_die, &die_mem,NULL ,NULL ); -else +dwarf_decl_line (rt_die, &decl); + decf =dwarf_decl_file (rt_die); + }else cu_die = rt_die;if (!cu_die) {pr_debug2 ("Failed to get CU from given DIE.\n" );@@ -767,15 +770,21 @@ int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data)continue ; }/* Filter lines based on address */ -if (rt_die != cu_die) +if (rt_die != cu_die) {/* * Address filtering * The line is included in given function, and * no inline block includes it. */ -if (!dwarf_haspc (rt_die, addr) || -die_find_inlinefunc (rt_die, addr, &die_mem)) +if (!dwarf_haspc (rt_die, addr))continue ;
tools/perf/util/dwarf-aux.c int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data) · line 790
Quoted 10 lines
tools/perf/util/dwarf-aux.c +7
-0+if (die_find_inlinefunc (rt_die, addr, &die_mem)) { +dwarf_decl_line (&die_mem, &inl); +if (inl != decl || + decf !=dwarf_decl_file (&die_mem)) +continue ; + } + }/* Get source line */ fname =dwarf_linesrc (line,NULL ,NULL );
���{.n�+�������+%�����ݶ��w��{.n�+����{��G�����{ay�ʇڙ�,j��f���h��������z_�(�階�ݢj"���m������G������?����&���~��iO��z��v�^�m����������?�I�