diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2012-04-22 23:24:36 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-09-19 10:35:05 -0400 |
commit | 0dbb1cac1dbdddf64cdd0f972c062a26484b7177 (patch) | |
tree | adc8c87044a66f1efb62871df23d260de0f97e78 /tools | |
parent | 33e940a25daaea71be054e8a4bdb61730cc9ebbc (diff) |
perf probe: Fix finder to find lines of given function
The commit ba28c59bc9ed8fb7b9a753cd88ee54a2c4f6265b fixed a declaration
entry bug in probe_point_search_cb(). There are same bugs in line
finder and call_probe_finder(). This introduces a new dwarf utility
function to determine given DIE is a function definition, not
declaration.
Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com>
Cc: Prashanth Nageshappa <prashanth@linux.vnet.ibm.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: yrl.pp-manager.tt@hitachi.com
Link: http://lkml.kernel.org/r/20120423032435.8737.80064.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.c | 19 | ||||
-rw-r--r-- | tools/perf/util/dwarf-aux.h | 3 | ||||
-rw-r--r-- | tools/perf/util/probe-finder.c | 12 |
3 files changed, 27 insertions, 7 deletions
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index 3e5f5430a28a..e23bde19d590 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c | |||
@@ -263,6 +263,21 @@ bool die_is_signed_type(Dwarf_Die *tp_die) | |||
263 | } | 263 | } |
264 | 264 | ||
265 | /** | 265 | /** |
266 | * die_is_func_def - Ensure that this DIE is a subprogram and definition | ||
267 | * @dw_die: a DIE | ||
268 | * | ||
269 | * Ensure that this DIE is a subprogram and NOT a declaration. This | ||
270 | * returns true if @dw_die is a function definition. | ||
271 | **/ | ||
272 | bool die_is_func_def(Dwarf_Die *dw_die) | ||
273 | { | ||
274 | Dwarf_Attribute attr; | ||
275 | |||
276 | return (dwarf_tag(dw_die) == DW_TAG_subprogram && | ||
277 | dwarf_attr(dw_die, DW_AT_declaration, &attr) == NULL); | ||
278 | } | ||
279 | |||
280 | /** | ||
266 | * die_get_data_member_location - Get the data-member offset | 281 | * die_get_data_member_location - Get the data-member offset |
267 | * @mb_die: a DIE of a member of a data structure | 282 | * @mb_die: a DIE of a member of a data structure |
268 | * @offs: The offset of the member in the data structure | 283 | * @offs: The offset of the member in the data structure |
@@ -392,6 +407,10 @@ static int __die_search_func_cb(Dwarf_Die *fn_die, void *data) | |||
392 | { | 407 | { |
393 | struct __addr_die_search_param *ad = data; | 408 | struct __addr_die_search_param *ad = data; |
394 | 409 | ||
410 | /* | ||
411 | * Since a declaration entry doesn't has given pc, this always returns | ||
412 | * function definition entry. | ||
413 | */ | ||
395 | if (dwarf_tag(fn_die) == DW_TAG_subprogram && | 414 | if (dwarf_tag(fn_die) == DW_TAG_subprogram && |
396 | dwarf_haspc(fn_die, ad->addr)) { | 415 | dwarf_haspc(fn_die, ad->addr)) { |
397 | memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die)); | 416 | memcpy(ad->die_mem, fn_die, sizeof(Dwarf_Die)); |
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 6ce1717784b7..8658d41697d2 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h | |||
@@ -38,6 +38,9 @@ extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr, | |||
38 | extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, | 38 | extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, |
39 | int (*callback)(Dwarf_Die *, void *), void *data); | 39 | int (*callback)(Dwarf_Die *, void *), void *data); |
40 | 40 | ||
41 | /* Ensure that this DIE is a subprogram and definition (not declaration) */ | ||
42 | extern bool die_is_func_def(Dwarf_Die *dw_die); | ||
43 | |||
41 | /* Compare diename and tname */ | 44 | /* Compare diename and tname */ |
42 | extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); | 45 | extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); |
43 | 46 | ||
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index be0329394d56..20c7299a9d4e 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -734,7 +734,7 @@ static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf) | |||
734 | } | 734 | } |
735 | 735 | ||
736 | /* If not a real subprogram, find a real one */ | 736 | /* If not a real subprogram, find a real one */ |
737 | if (dwarf_tag(sc_die) != DW_TAG_subprogram) { | 737 | if (!die_is_func_def(sc_die)) { |
738 | if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) { | 738 | if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) { |
739 | pr_warning("Failed to find probe point in any " | 739 | pr_warning("Failed to find probe point in any " |
740 | "functions.\n"); | 740 | "functions.\n"); |
@@ -980,12 +980,10 @@ static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) | |||
980 | struct dwarf_callback_param *param = data; | 980 | struct dwarf_callback_param *param = data; |
981 | struct probe_finder *pf = param->data; | 981 | struct probe_finder *pf = param->data; |
982 | struct perf_probe_point *pp = &pf->pev->point; | 982 | struct perf_probe_point *pp = &pf->pev->point; |
983 | Dwarf_Attribute attr; | ||
984 | 983 | ||
985 | /* Check tag and diename */ | 984 | /* Check tag and diename */ |
986 | if (dwarf_tag(sp_die) != DW_TAG_subprogram || | 985 | if (!die_is_func_def(sp_die) || |
987 | !die_compare_name(sp_die, pp->function) || | 986 | !die_compare_name(sp_die, pp->function)) |
988 | dwarf_attr(sp_die, DW_AT_declaration, &attr)) | ||
989 | return DWARF_CB_OK; | 987 | return DWARF_CB_OK; |
990 | 988 | ||
991 | /* Check declared file */ | 989 | /* Check declared file */ |
@@ -1474,7 +1472,7 @@ static int line_range_inline_cb(Dwarf_Die *in_die, void *data) | |||
1474 | return 0; | 1472 | return 0; |
1475 | } | 1473 | } |
1476 | 1474 | ||
1477 | /* Search function from function name */ | 1475 | /* Search function definition from function name */ |
1478 | static int line_range_search_cb(Dwarf_Die *sp_die, void *data) | 1476 | static int line_range_search_cb(Dwarf_Die *sp_die, void *data) |
1479 | { | 1477 | { |
1480 | struct dwarf_callback_param *param = data; | 1478 | struct dwarf_callback_param *param = data; |
@@ -1485,7 +1483,7 @@ static int line_range_search_cb(Dwarf_Die *sp_die, void *data) | |||
1485 | if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die))) | 1483 | if (lr->file && strtailcmp(lr->file, dwarf_decl_file(sp_die))) |
1486 | return DWARF_CB_OK; | 1484 | return DWARF_CB_OK; |
1487 | 1485 | ||
1488 | if (dwarf_tag(sp_die) == DW_TAG_subprogram && | 1486 | if (die_is_func_def(sp_die) && |
1489 | die_compare_name(sp_die, lr->function)) { | 1487 | die_compare_name(sp_die, lr->function)) { |
1490 | lf->fname = dwarf_decl_file(sp_die); | 1488 | lf->fname = dwarf_decl_file(sp_die); |
1491 | dwarf_decl_line(sp_die, &lr->offset); | 1489 | dwarf_decl_line(sp_die, &lr->offset); |