Skip to contentSkip to conversation

perf - probe finder fails to resolve function name to address

PATCH In review Prashanth Nageshappa 6 participants 12 messages Mar 22, 2012 – Mar 31, 2012 1 message not in the archive perf events

lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

PATCH 1/1 perf - probe finder fails to resolve function name to address

probe finder fails to resolve valid function names into addresses for functions which have more than one die entries in DWARF info.

It is valid for DWARF info to contain more than 1 entries for a given function name, where one entry corresponds to definition which has code address/range attributes and remaining entries (which are only declarations) does not have code address/range attributes. (example: do_fork, sys_write, sys_wait4, sys_sync etc)

If die entries corresponding to declarations appear before definition entry, probe finder returns error instead of continuing to look further for a definition entry.

This patch ensures we reach to the die entry corresponding to the definition and get the function address. I have also removed the warning as this is a valid thing to happen.

---

 tools/perf/util/probe-finder.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)
tools/perf/util/probe-finder.c +1 -4
index 5d73262..5e1e6f7 100644
@@ -984,10 +984,7 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 			param->retval = find_probe_point_lazy(sp_die, pf);
 		else {
 			if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
-				pr_warning("Failed to get entry address of "
-					   "%s.\n", dwarf_diename(sp_die));
-				param->retval = -ENOENT;
-				return DWARF_CB_ABORT;
+				return DWARF_CB_OK;
 			}
 			pf->addr += pp->offset;
 			/* TODO: Check the address in this function */
#2 lore raw

Hi,

Quoted 8 lines · Prashanth Nageshappa

probe finder fails to resolve valid function names into addresses for functions which have more than one die entries in DWARF info.

It is valid for DWARF info to contain more than 1 entries for a given function name, where one entry corresponds to definition which has code address/range attributes and remaining entries (which are only declarations) does not have code address/range attributes. (example: do_fork, sys_write, sys_wait4, sys_sync etc)

Hmm, I'd like to reproduce and see what happened on debuginfo in those cases. Could you tell me your environment or actual dwarf dump of those entries as below?

$ readelf -wi vmlinux | grep do_fork -A 16

for example, on my fedora15, it shows;

    <3c68a3>   DW_AT_name        : (indirect string, offset: 0x201e0): do_fork_idle
    <3c68a7>   DW_AT_decl_file   : 2
    <3c68a8>   DW_AT_decl_line   : 631
    <3c68aa>   DW_AT_prototyped  : 1
    <3c68ab>   DW_AT_low_pc      : 0xffffffff817f0e25
    <3c68b3>   DW_AT_high_pc     : 0xffffffff817f0e47
    <3c68bb>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <3c68bd>   DW_AT_sibling     : <0x3c68e2>
 <2><3c68c1>: Abbrev Number: 92 (DW_TAG_formal_parameter)
    <3c68c2>   DW_AT_name        : (indirect string, offset: 0x20a53d): work
    <3c68c6>   DW_AT_decl_file   : 2
--
    <672173>   DW_AT_name        : (indirect string, offset: 0x2d346): do_fork
    <672177>   DW_AT_decl_file   : 3
    <672178>   DW_AT_decl_line   : 1519
    <67217a>   DW_AT_prototyped  : 1
    <67217b>   DW_AT_type        : <0x65ab83>
    <67217f>   DW_AT_low_pc      : 0xffffffff8103cb40
    <672187>   DW_AT_high_pc     : 0xffffffff8103ce75
    <67218f>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <672191>   DW_AT_sibling     : <0x6727bd>
 <2><672195>: Abbrev Number: 105 (DW_TAG_formal_parameter)
    <672196>   DW_AT_name        : (indirect string, offset: 0xc27d): clone_flags

I'd like to see what attribute was different in the case which you encountered.

Quoted 19 lines

If die entries corresponding to declarations appear before definition entry, probe finder returns error instead of continuing to look further for a definition entry.

This patch ensures we reach to the die entry corresponding to the definition and get the function address. I have also removed the warning as this is a valid thing to happen.

---

 tools/perf/util/probe-finder.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)
tools/perf/util/probe-finder.c +0 -0
index 5d73262..5e1e6f7 100644

tools/perf/util/probe-finder.c static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) · line 984

Quoted 1 line
tools/perf/util/probe-finder.c +0 -0
@@ -984,10 +984,7 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 			param->retval = find_probe_point_lazy(sp_die, pf);

At least we must consider this lazy_line case. If I understand correctly, that can also affect find_probe_point_lazy(sp_die, pf);

If I find the different attribute, I'd like to add a checker function and filter it out at early step in this function.

tools/perf/util/probe-finder.c static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) · line 990

Quoted 11 lines
tools/perf/util/probe-finder.c +1 -4
 		else {
 			if (dwarf_entrypc(sp_die, &pf->addr) != 0) {
-				pr_warning("Failed to get entry address of "
-					   "%s.\n", dwarf_diename(sp_die));
-				param->retval = -ENOENT;
-				return DWARF_CB_ABORT;
+				return DWARF_CB_OK;
 			}
 			pf->addr += pp->offset;
 			/* TODO: Check the address in this function */

Thank you,

Signature · 4 lines
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: [email protected]
#3 lore raw
Quoted 6 lines · Masami Hiramatsu

Hi,

Quoted 3 lines · Prashanth Nageshappa

probe finder fails to resolve valid function names into addresses for functions which have more than one die entries in DWARF info.

Quoted 9 lines
Quoted 5 lines

It is valid for DWARF info to contain more than 1 entries for a given function name, where one entry corresponds to definition which has code address/range attributes and remaining entries (which are only declarations) does not have code address/range attributes. (example: do_fork, sys_write, sys_wait4, sys_sync etc)

Hmm, I'd like to reproduce and see what happened on debuginfo in those cases. Could you tell me your environment or actual dwarf dump of those entries as below?

$ uname -r
3.1.0-7.fc16.x86_64
$ sudo perf probe  do_fork
Failed to get entry address of do_fork.
  Error: Failed to add events. (-2)
$ readelf -wi /usr/lib/debug/lib/modules/3.1.0-7.fc16.x86_64/vmlinux | grep do_fork -A 16
    <2691f7>   DW_AT_name        : (indirect string, offset: 0x1b1e0): do_fork	
    <2691fb>   DW_AT_decl_file   : 3	
    <2691fc>   DW_AT_decl_line   : 2269	
    <2691fe>   DW_AT_prototyped  : 1	
    <2691fe>   DW_AT_type        : <0x2593d1>	
    <269202>   DW_AT_declaration : 1	
    <269202>   DW_AT_sibling     : <0x269225>	
 <2><269206>: Abbrev Number: 14 (DW_TAG_formal_parameter)
    <269207>   DW_AT_type        : <0x259284>	
 <2><26920b>: Abbrev Number: 14 (DW_TAG_formal_parameter)
    <26920c>   DW_AT_type        : <0x259284>	
 <2><269210>: Abbrev Number: 14 (DW_TAG_formal_parameter)
    <269211>   DW_AT_type        : <0x25b2b1>	
 <2><269215>: Abbrev Number: 14 (DW_TAG_formal_parameter)
    <269216>   DW_AT_type        : <0x259284>	
 <2><26921a>: Abbrev Number: 14 (DW_TAG_formal_parameter)
    <26921b>   DW_AT_type        : <0x25a1f3>	
--
    <4015fc>   DW_AT_name        : (indirect string, offset: 0x266d7): do_fork_idle	
    <401600>   DW_AT_decl_file   : 3	
    <401601>   DW_AT_decl_line   : 638	
    <401603>   DW_AT_prototyped  : 1	
    <401603>   DW_AT_low_pc      : 0xffffffff814a32bb	
    <40160b>   DW_AT_high_pc     : 0xffffffff814a32dd	
    <401613>   DW_AT_frame_base  : 1 byte block: 9c 	(DW_OP_call_frame_cfa)
    <401615>   DW_AT_GNU_all_call_sites: 1	
    <401615>   DW_AT_sibling     : <0x40165b>	
 <2><401619>: Abbrev Number: 91 (DW_TAG_formal_parameter)
    <40161a>   DW_AT_name        : (indirect string, offset: 0x10f8da): work	
    <40161e>   DW_AT_decl_file   : 3	
    <40161f>   DW_AT_decl_line   : 638	
    <401621>   DW_AT_type        : <0x3f96c9>	
    <401625>   DW_AT_location    : 0x7fb55	(location list)
 <2><401629>: Abbrev Number: 110 (DW_TAG_variable)
    <40162a>   DW_AT_name        : (indirect string, offset: 0x1109a7): c_idle	
--
    <679053>   DW_AT_name        : (indirect string, offset: 0x1b1e0): do_fork	
    <679057>   DW_AT_decl_file   : 25	
    <679058>   DW_AT_decl_line   : 2269	
    <67905a>   DW_AT_prototyped  : 1	
    <67905a>   DW_AT_type        : <0x66a9b5>	
    <67905e>   DW_AT_declaration : 1	
    <67905e>   DW_AT_sibling     : <0x679081>	
 <2><679062>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <679063>   DW_AT_type        : <0x66a872>	
 <2><679067>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <679068>   DW_AT_type        : <0x66a872>	
 <2><67906c>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <67906d>   DW_AT_type        : <0x66c935>	
 <2><679071>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <679072>   DW_AT_type        : <0x66a872>	
 <2><679076>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <679077>   DW_AT_type        : <0x66b877>	
--
    <723f0b>   DW_AT_name        : (indirect string, offset: 0x1b1e0): do_fork	
    <723f0f>   DW_AT_decl_file   : 4	
    <723f10>   DW_AT_decl_line   : 1476	
    <723f12>   DW_AT_prototyped  : 1	
    <723f12>   DW_AT_type        : <0x70caad>	
    <723f16>   DW_AT_low_pc      : 0xffffffff81056ee1	
    <723f1e>   DW_AT_high_pc     : 0xffffffff81057149	
    <723f26>   DW_AT_frame_base  : 1 byte block: 9c 	(DW_OP_call_frame_cfa)
    <723f28>   DW_AT_GNU_all_call_sites: 1	
    <723f28>   DW_AT_sibling     : <0x7244fd>	
 <2><723f2c>: Abbrev Number: 96 (DW_TAG_formal_parameter)
    <723f2d>   DW_AT_name        : (indirect string, offset: 0x146df): clone_flags	
    <723f31>   DW_AT_decl_file   : 4	
    <723f32>   DW_AT_decl_line   : 1476	
    <723f34>   DW_AT_type        : <0x70ca0d>	
    <723f38>   DW_AT_location    : 0x10db3b	(location list)
 <2><723f3c>: Abbrev Number: 96 (DW_TAG_formal_parameter)
--
    <33629b6>   DW_AT_name        : (indirect string, offset: 0x124058): run_do_fork_test	
    <33629ba>   DW_AT_decl_file   : 2	
    <33629bb>   DW_AT_decl_line   : 858	
    <33629bd>   DW_AT_prototyped  : 1	
    <33629bd>   DW_AT_inline      : 1	(inlined)
 <1><33629be>: Abbrev Number: 71 (DW_TAG_subprogram)
    <33629bf>   DW_AT_name        : (indirect string, offset: 0x123c3d): run_sys_open_test	
    <33629c3>   DW_AT_decl_file   : 2	
    <33629c4>   DW_AT_decl_line   : 867	
    <33629c6>   DW_AT_prototyped  : 1	
    <33629c6>   DW_AT_inline      : 1	(inlined)
 <1><33629c7>: Abbrev Number: 64 (DW_TAG_subprogram)
    <33629c8>   DW_AT_name        : (indirect string, offset: 0x123e9e): kgdbts_option_setup	
    <33629cc>   DW_AT_decl_file   : 2	
    <33629cd>   DW_AT_decl_line   : 985	
    <33629cf>   DW_AT_prototyped  : 1	
    <33629cf>   DW_AT_type        : <0x335570d>	
--
    <33651ea>   DW_AT_name        : (indirect string, offset: 0x12405c): do_fork_test	
    <33651ee>   DW_AT_decl_file   : 2	
    <33651ef>   DW_AT_decl_line   : 522	
    <33651f1>   DW_AT_type        : <0x33651d9>	
    <33651f5>   DW_AT_location    : 9 byte block: 3 30 87 a7 81 ff ff ff ff 	(DW_OP_addr: ffffffff81a78730)
 <1><33651ff>: Abbrev Number: 122 (DW_TAG_variable)
    <3365200>   DW_AT_name        : (indirect string, offset: 0x123c41): sys_open_test	
    <3365204>   DW_AT_decl_file   : 2	
    <3365205>   DW_AT_decl_line   : 540	
    <3365207>   DW_AT_type        : <0x33651d9>	
    <336520b>   DW_AT_location    : 9 byte block: 3 b0 88 a7 81 ff ff ff ff 	(DW_OP_addr: ffffffff81a788b0)
 <1><3365215>: Abbrev Number: 122 (DW_TAG_variable)
    <3365216>   DW_AT_name        : (indirect string, offset: 0x123b83): hw_breakpoint_test	
    <336521a>   DW_AT_decl_file   : 2	
    <336521b>   DW_AT_decl_line   : 558	
    <336521d>   DW_AT_type        : <0x3365167>	
    <3365221>   DW_AT_location    : 9 byte block: 3 30 8a a7 81 ff ff ff ff 	(DW_OP_addr: ffffffff81a78a30)
Quoted 6 lines

At least we must consider this lazy_line case. If I understand correctly, that can also affect find_probe_point_lazy(sp_die, pf);

If I find the different attribute, I'd like to add a checker function and filter it out at early step in this function.

Based on the above comments I have redone the patch:

If die entries corresponding to declarations appear before definition entry, probe finder returns error instead of continuing to look further for a definition entry.

This patch ensures we reach to the die entry corresponding to the definition and get the function address.

V2: A simpler solution based on Masami's suggestion.

---

 tools/perf/util/probe-finder.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)
tools/perf/util/probe-finder.c +2 -1
index 5d73262..fc59df2 100644
@@ -963,10 +963,11 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 	struct dwarf_callback_param *param = data;
 	struct probe_finder *pf = param->data;
 	struct perf_probe_point *pp = &pf->pev->point;
+	Dwarf_Attribute attr;
 
 	/* Check tag and diename */
 	if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
-	    !die_compare_name(sp_die, pp->function))
+	    !die_compare_name(sp_die, pp->function) || dwarf_attr(sp_die, DW_AT_declaration, &attr))
 		return DWARF_CB_OK;
 
 	/* Check declared file */
#4 lore raw
In reply to Masami Hiramatsu

Fixing a coding style issue..

Quoted 6 lines · Masami Hiramatsu

Hi,

Quoted 3 lines · Prashanth Nageshappa

probe finder fails to resolve valid function names into addresses for functions which have more than one die entries in DWARF info.

Quoted 9 lines
Quoted 5 lines

It is valid for DWARF info to contain more than 1 entries for a given function name, where one entry corresponds to definition which has code address/range attributes and remaining entries (which are only declarations) does not have code address/range attributes. (example: do_fork, sys_write, sys_wait4, sys_sync etc)

Hmm, I'd like to reproduce and see what happened on debuginfo in those cases. Could you tell me your environment or actual dwarf dump of those entries as below?

$ uname -r
3.1.0-7.fc16.x86_64
$ sudo perf probe  do_fork
Failed to get entry address of do_fork.
  Error: Failed to add events. (-2)
$ readelf -wi /usr/lib/debug/lib/modules/3.1.0-7.fc16.x86_64/vmlinux | grep do_fork -A 16
    <2691f7>   DW_AT_name        : (indirect string, offset: 0x1b1e0): do_fork	
    <2691fb>   DW_AT_decl_file   : 3	
    <2691fc>   DW_AT_decl_line   : 2269	
    <2691fe>   DW_AT_prototyped  : 1	
    <2691fe>   DW_AT_type        : <0x2593d1>	
    <269202>   DW_AT_declaration : 1	
    <269202>   DW_AT_sibling     : <0x269225>	
 <2><269206>: Abbrev Number: 14 (DW_TAG_formal_parameter)
    <269207>   DW_AT_type        : <0x259284>	
 <2><26920b>: Abbrev Number: 14 (DW_TAG_formal_parameter)
    <26920c>   DW_AT_type        : <0x259284>	
 <2><269210>: Abbrev Number: 14 (DW_TAG_formal_parameter)
    <269211>   DW_AT_type        : <0x25b2b1>	
 <2><269215>: Abbrev Number: 14 (DW_TAG_formal_parameter)
    <269216>   DW_AT_type        : <0x259284>	
 <2><26921a>: Abbrev Number: 14 (DW_TAG_formal_parameter)
    <26921b>   DW_AT_type        : <0x25a1f3>	
--
    <4015fc>   DW_AT_name        : (indirect string, offset: 0x266d7): do_fork_idle	
    <401600>   DW_AT_decl_file   : 3	
    <401601>   DW_AT_decl_line   : 638	
    <401603>   DW_AT_prototyped  : 1	
    <401603>   DW_AT_low_pc      : 0xffffffff814a32bb	
    <40160b>   DW_AT_high_pc     : 0xffffffff814a32dd	
    <401613>   DW_AT_frame_base  : 1 byte block: 9c 	(DW_OP_call_frame_cfa)
    <401615>   DW_AT_GNU_all_call_sites: 1	
    <401615>   DW_AT_sibling     : <0x40165b>	
 <2><401619>: Abbrev Number: 91 (DW_TAG_formal_parameter)
    <40161a>   DW_AT_name        : (indirect string, offset: 0x10f8da): work	
    <40161e>   DW_AT_decl_file   : 3	
    <40161f>   DW_AT_decl_line   : 638	
    <401621>   DW_AT_type        : <0x3f96c9>	
    <401625>   DW_AT_location    : 0x7fb55	(location list)
 <2><401629>: Abbrev Number: 110 (DW_TAG_variable)
    <40162a>   DW_AT_name        : (indirect string, offset: 0x1109a7): c_idle	
--
    <679053>   DW_AT_name        : (indirect string, offset: 0x1b1e0): do_fork	
    <679057>   DW_AT_decl_file   : 25	
    <679058>   DW_AT_decl_line   : 2269	
    <67905a>   DW_AT_prototyped  : 1	
    <67905a>   DW_AT_type        : <0x66a9b5>	
    <67905e>   DW_AT_declaration : 1	
    <67905e>   DW_AT_sibling     : <0x679081>	
 <2><679062>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <679063>   DW_AT_type        : <0x66a872>	
 <2><679067>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <679068>   DW_AT_type        : <0x66a872>	
 <2><67906c>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <67906d>   DW_AT_type        : <0x66c935>	
 <2><679071>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <679072>   DW_AT_type        : <0x66a872>	
 <2><679076>: Abbrev Number: 12 (DW_TAG_formal_parameter)
    <679077>   DW_AT_type        : <0x66b877>	
--
    <723f0b>   DW_AT_name        : (indirect string, offset: 0x1b1e0): do_fork	
    <723f0f>   DW_AT_decl_file   : 4	
    <723f10>   DW_AT_decl_line   : 1476	
    <723f12>   DW_AT_prototyped  : 1	
    <723f12>   DW_AT_type        : <0x70caad>	
    <723f16>   DW_AT_low_pc      : 0xffffffff81056ee1	
    <723f1e>   DW_AT_high_pc     : 0xffffffff81057149	
    <723f26>   DW_AT_frame_base  : 1 byte block: 9c 	(DW_OP_call_frame_cfa)
    <723f28>   DW_AT_GNU_all_call_sites: 1	
    <723f28>   DW_AT_sibling     : <0x7244fd>	
 <2><723f2c>: Abbrev Number: 96 (DW_TAG_formal_parameter)
    <723f2d>   DW_AT_name        : (indirect string, offset: 0x146df): clone_flags	
    <723f31>   DW_AT_decl_file   : 4	
    <723f32>   DW_AT_decl_line   : 1476	
    <723f34>   DW_AT_type        : <0x70ca0d>	
    <723f38>   DW_AT_location    : 0x10db3b	(location list)
 <2><723f3c>: Abbrev Number: 96 (DW_TAG_formal_parameter)
--
    <33629b6>   DW_AT_name        : (indirect string, offset: 0x124058): run_do_fork_test	
    <33629ba>   DW_AT_decl_file   : 2	
    <33629bb>   DW_AT_decl_line   : 858	
    <33629bd>   DW_AT_prototyped  : 1	
    <33629bd>   DW_AT_inline      : 1	(inlined)
 <1><33629be>: Abbrev Number: 71 (DW_TAG_subprogram)
    <33629bf>   DW_AT_name        : (indirect string, offset: 0x123c3d): run_sys_open_test	
    <33629c3>   DW_AT_decl_file   : 2	
    <33629c4>   DW_AT_decl_line   : 867	
    <33629c6>   DW_AT_prototyped  : 1	
    <33629c6>   DW_AT_inline      : 1	(inlined)
 <1><33629c7>: Abbrev Number: 64 (DW_TAG_subprogram)
    <33629c8>   DW_AT_name        : (indirect string, offset: 0x123e9e): kgdbts_option_setup	
    <33629cc>   DW_AT_decl_file   : 2	
    <33629cd>   DW_AT_decl_line   : 985	
    <33629cf>   DW_AT_prototyped  : 1	
    <33629cf>   DW_AT_type        : <0x335570d>	
--
    <33651ea>   DW_AT_name        : (indirect string, offset: 0x12405c): do_fork_test	
    <33651ee>   DW_AT_decl_file   : 2	
    <33651ef>   DW_AT_decl_line   : 522	
    <33651f1>   DW_AT_type        : <0x33651d9>	
    <33651f5>   DW_AT_location    : 9 byte block: 3 30 87 a7 81 ff ff ff ff 	(DW_OP_addr: ffffffff81a78730)
 <1><33651ff>: Abbrev Number: 122 (DW_TAG_variable)
    <3365200>   DW_AT_name        : (indirect string, offset: 0x123c41): sys_open_test	
    <3365204>   DW_AT_decl_file   : 2	
    <3365205>   DW_AT_decl_line   : 540	
    <3365207>   DW_AT_type        : <0x33651d9>	
    <336520b>   DW_AT_location    : 9 byte block: 3 b0 88 a7 81 ff ff ff ff 	(DW_OP_addr: ffffffff81a788b0)
 <1><3365215>: Abbrev Number: 122 (DW_TAG_variable)
    <3365216>   DW_AT_name        : (indirect string, offset: 0x123b83): hw_breakpoint_test	
    <336521a>   DW_AT_decl_file   : 2	
    <336521b>   DW_AT_decl_line   : 558	
    <336521d>   DW_AT_type        : <0x3365167>	
    <3365221>   DW_AT_location    : 9 byte block: 3 30 8a a7 81 ff ff ff ff 	(DW_OP_addr: ffffffff81a78a30)
Quoted 7 lines

At least we must consider this lazy_line case. If I understand correctly, that can also affect find_probe_point_lazy(sp_die, pf);

If I find the different attribute, I'd like to add a checker function and filter it out at early step in this function.

Based on the above comments I have redone the patch:

If die entries corresponding to declarations appear before definition entry, probe finder returns error instead of continuing to look further for a definition entry.

This patch ensures we reach to the die entry corresponding to the definition and get the function address.

V2: A simpler solution based on Masami's suggestion.

---

 tools/perf/util/probe-finder.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
tools/perf/util/probe-finder.c +3 -1
index 5d73262..d5914ee 100644
@@ -963,10 +963,12 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 	struct dwarf_callback_param *param = data;
 	struct probe_finder *pf = param->data;
 	struct perf_probe_point *pp = &pf->pev->point;
+	Dwarf_Attribute attr;
 
 	/* Check tag and diename */
 	if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
-	    !die_compare_name(sp_die, pp->function))
+	    !die_compare_name(sp_die, pp->function) ||
+	    dwarf_attr(sp_die, DW_AT_declaration, &attr))
 		return DWARF_CB_OK;
 
 	/* Check declared file */
#5 lore raw
Quoted 27 lines · Prashanth Nageshappa

Fixing a coding style issue..

Quoted 6 lines · Masami Hiramatsu

Hi,

Quoted 3 lines · Prashanth Nageshappa

probe finder fails to resolve valid function names into addresses for functions which have more than one die entries in DWARF info.

Quoted 9 lines
Quoted 5 lines

It is valid for DWARF info to contain more than 1 entries for a given function name, where one entry corresponds to definition which has code address/range attributes and remaining entries (which are only declarations) does not have code address/range attributes. (example: do_fork, sys_write, sys_wait4, sys_sync etc)

Hmm, I'd like to reproduce and see what happened on debuginfo in those cases. Could you tell me your environment or actual dwarf dump of those entries as below?

$ uname -r
3.1.0-7.fc16.x86_64
$ sudo perf probe  do_fork
Failed to get entry address of do_fork.
  Error: Failed to add events. (-2)
Quoted 7 lines
$ readelf -wi /usr/lib/debug/lib/modules/3.1.0-7.fc16.x86_64/vmlinux | grep do_fork -A 16
    <2691f7>   DW_AT_name        : (indirect string, offset: 0x1b1e0): do_fork	
    <2691fb>   DW_AT_decl_file   : 3	
    <2691fc>   DW_AT_decl_line   : 2269	
    <2691fe>   DW_AT_prototyped  : 1	
    <2691fe>   DW_AT_type        : <0x2593d1>	
    <269202>   DW_AT_declaration : 1	

OK, compared with mine, this attribute is actually new one for this kind of (declaration) entries.

[...]

Quoted 14 lines
Quoted 7 lines

At least we must consider this lazy_line case. If I understand correctly, that can also affect find_probe_point_lazy(sp_die, pf);

If I find the different attribute, I'd like to add a checker function and filter it out at early step in this function.

Based on the above comments I have redone the patch:

If die entries corresponding to declarations appear before definition entry, probe finder returns error instead of continuing to look further for a definition entry.

Quoted 7 lines

This patch ensures we reach to the die entry corresponding to the definition and get the function address.

V2: A simpler solution based on Masami's suggestion.

Well, OK. This looks good for me too :)

Quoted 25 lines

---

 tools/perf/util/probe-finder.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
tools/perf/util/probe-finder.c +3 -1
index 5d73262..d5914ee 100644
@@ -963,10 +963,12 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 	struct dwarf_callback_param *param = data;
 	struct probe_finder *pf = param->data;
 	struct perf_probe_point *pp = &pf->pev->point;
+	Dwarf_Attribute attr;
 
 	/* Check tag and diename */
 	if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
-	    !die_compare_name(sp_die, pp->function))
+	    !die_compare_name(sp_die, pp->function) ||
+	    dwarf_attr(sp_die, DW_AT_declaration, &attr))
 		return DWARF_CB_OK;
 
 	/* Check declared file */
Signature · 4 lines
Masami HIRAMATSU
Software Platform Research Dept. Linux Technology Center
Hitachi, Ltd., Yokohama Research Laboratory
E-mail: [email protected]
#7 lore raw

PATCH 1/1 perf: missing export.h file

CC util/rbtree.o
../../lib/rbtree.c:24:26: error: linux/export.h: No such file or directory
cc1: warnings being treated as errors

---
I must be missing something, why nobody hits this error ???

tools/perf/util/include/linux/export.h new file +6 -0
new file mode 100644
index 0000000..841636d
@@ -0,0 +1,6 @@
+#ifndef PERF_LINUX_EXPORT_H
+#define PERF_LINUX_EXPORT_H
+
+#define EXPORT_SYMBOL(name)
+
+#endif
#8 lore raw

Re: [PATCH] perf: missing export.h file

Em Wed, Mar 28, 2012 at 02:59:01PM +0200, Eric Dumazet escreveu:

Quoted 8 lines

CC util/rbtree.o
../../lib/rbtree.c:24:26: error: linux/export.h: No such file or directory
cc1: warnings being treated as errors

---
I must be missing something, why nobody hits this error ???

I think I saw this reported by another person too, checking.

- Arnaldo

Quoted 13 lines
tools/perf/util/include/linux/export.h new file +6 -0
new file mode 100644
index 0000000..841636d
@@ -0,0 +1,6 @@
+#ifndef PERF_LINUX_EXPORT_H
+#define PERF_LINUX_EXPORT_H
+
+#define EXPORT_SYMBOL(name)
+
+#endif
#9 lore raw

Re: [PATCH] perf: missing export.h file

In reply to Eric Dumazet

From: Eric Dumazet <[email protected]>
Date: Wed, 28 Mar 2012 14:59:01 +0200

Quoted 8 lines

CC util/rbtree.o
../../lib/rbtree.c:24:26: error: linux/export.h: No such file or directory
cc1: warnings being treated as errors

---
I must be missing something, why nobody hits this error ???

Some don't hit it because it's already installed under /usr/include

#10 lore raw

Re: [PATCH] perf: missing export.h file

Quoted 8 lines · David Miller

From: Eric Dumazet <[email protected]>
Date: Wed, 28 Mar 2012 14:59:01 +0200

Quoted 5 lines

CC util/rbtree.o
../../lib/rbtree.c:24:26: error: linux/export.h: No such file or directory
cc1: warnings being treated as errors

Quoted 5 lines
Quoted 3 lines

---
I must be missing something, why nobody hits this error ???

Some don't hit it because it's already installed under /usr/include

The other reason is that it's also fixed in linux-next and in -tip, where most of the folks who build perf from scratch are concentrated. Will get tip:perf/urgent to Linus ASAP.

Thanks,

Ingo

#11 lore raw
In reply to Ingo Molnar

Em Wed, Mar 28, 2012 at 01:47:45PM +0200, Ingo Molnar escreveu:

Quoted 11 lines · Masami Hiramatsu
Quoted 6 lines
Quoted 2 lines

Well, OK. This looks good for me too :)

Ok, someone mind sending me the final, agreed upon version, with full explanation and Acked-by's included?

I'll do it.

Waiting a bit before that for the bison/flex resolution.

- Arnaldo

#12 lore raw

[tip:perf/urgent] perf probe: Finder fails to resolve function name to address

In reply to Prashanth Nageshappa
Commit-ID:  ba28c59bc9ed8fb7b9a753cd88ee54a2c4f6265b
Gitweb:     http://git.kernel.org/tip/ba28c59bc9ed8fb7b9a753cd88ee54a2c4f6265b
Author:     Prashanth Nageshappa <[email protected]>
AuthorDate: Mon, 26 Mar 2012 15:36:49 +0530
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Wed, 28 Mar 2012 11:56:49 -0300

perf probe: Finder fails to resolve function name to address

If DIE entries corresponding to declarations appear before definition entry, probe finder returns error instead of continuing to look further for a definition entry.

This patch ensures we reach to the DIE entry corresponding to the definition and get the function address.

V2: A simpler solution based on Masami's suggestion.

---
 tools/perf/util/probe-finder.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
tools/perf/util/probe-finder.c +3 -1
index 2cc162d..d448984 100644
@@ -972,10 +972,12 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data)
 	struct dwarf_callback_param *param = data;
 	struct probe_finder *pf = param->data;
 	struct perf_probe_point *pp = &pf->pev->point;
+	Dwarf_Attribute attr;
 
 	/* Check tag and diename */
 	if (dwarf_tag(sp_die) != DW_TAG_subprogram ||
-	    !die_compare_name(sp_die, pp->function))
+	    !die_compare_name(sp_die, pp->function) ||
+	    dwarf_attr(sp_die, DW_AT_declaration, &attr))
 		return DWARF_CB_OK;
 
 	/* Check declared file */