diff options
author | Masami Hiramatsu <mhiramat@kernel.org> | 2016-09-23 11:35:31 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-09-29 10:17:08 -0400 |
commit | d5a00296a63fdd049273f86d0a0cdef6b230f8e6 (patch) | |
tree | f1020d6a3eaa93d89c26dd0efee69c358bb5e04e /tools/perf | |
parent | 35726d3a4ca9ce10811032baf6fa0b3529aac087 (diff) |
perf probe: Match linkage name with mangled name
Match linkage name with mangled name if exists. The linkage_name is used
for storing mangled name of the object.
Thus, this allows 'perf probe' to find appropriate probe point from
mangled symbol as below.
E.g. without this fix:
----
$ perf probe -x /usr/lib64/libstdc++.so.6 \
-D _ZNKSt15basic_fstreamXXIwSt11char_traitsIwEE7is_openEv
Probe point '_ZNKSt15basic_fstreamXXIwSt11char_traitsIwEE7is_openEv'
not found.
Error: Failed to add events.
----
With this fix, perf probe can find the correct one.
----
$ perf probe -x /usr/lib64/libstdc++.so.6 \
-D _ZNKSt15basic_fstreamXXIwSt11char_traitsIwEE7is_openEv
p:probe_libstdc/_ZNKSt15basic_fstreamXXIwSt11char_traitsIwEE7is_openEv
/usr/lib64/libstdc++.so.6.0.22:0x8ca60
----
Committer notes:
After the fix, setting it for real (no -D/--definition, that amounts to
a --dry-run):
# perf probe -x /usr/lib64/libstdc++.so.6 _ZNKSt15basic_fstreamXXIwSt11char_traitsIwEE7is_openEv
Added new event:
probe_libstdc:_ZNKSt15basic_fstreamXXIwSt11char_traitsIwEE7is_openEv (on _ZNKSt15basic_fstreamXXIwSt11char_traitsIwEE7is_openEv in /usr/lib64/libstdc++.so.6.0.22)
You can now use it in all perf tools, such as:
perf record -e probe_libstdc:_ZNKSt15basic_fstreamXXIwSt11char_traitsIwEE7is_openEv -aR sleep 1
# perf probe -l probe_libstdc:*
probe_libstdc:_ZNKSt15basic_fstreamXXIwSt11char_traitsIwEE7is_openEv (on is_open@libstdc++-v3/include/fstream in /usr/lib64/libstdc++.so.6.0.22)
#
Reported-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Jiri Olsa <jolsa@kernel.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/147464493162.29804.16715053505069382443.stgit@devbox
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/util/dwarf-aux.c | 28 | ||||
-rw-r--r-- | tools/perf/util/dwarf-aux.h | 3 |
2 files changed, 29 insertions, 2 deletions
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c index faec899435f2..41e068e94349 100644 --- a/tools/perf/util/dwarf-aux.c +++ b/tools/perf/util/dwarf-aux.c | |||
@@ -130,6 +130,22 @@ int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, | |||
130 | } | 130 | } |
131 | 131 | ||
132 | /** | 132 | /** |
133 | * die_get_linkage_name - Get the linkage name of the object | ||
134 | * @dw_die: A DIE of the object | ||
135 | * | ||
136 | * Get the linkage name attiribute of given @dw_die. | ||
137 | * For C++ binary, the linkage name will be the mangled symbol. | ||
138 | */ | ||
139 | const char *die_get_linkage_name(Dwarf_Die *dw_die) | ||
140 | { | ||
141 | Dwarf_Attribute attr; | ||
142 | |||
143 | if (dwarf_attr_integrate(dw_die, DW_AT_linkage_name, &attr) == NULL) | ||
144 | return NULL; | ||
145 | return dwarf_formstring(&attr); | ||
146 | } | ||
147 | |||
148 | /** | ||
133 | * die_compare_name - Compare diename and tname | 149 | * die_compare_name - Compare diename and tname |
134 | * @dw_die: a DIE | 150 | * @dw_die: a DIE |
135 | * @tname: a string of target name | 151 | * @tname: a string of target name |
@@ -145,18 +161,26 @@ bool die_compare_name(Dwarf_Die *dw_die, const char *tname) | |||
145 | } | 161 | } |
146 | 162 | ||
147 | /** | 163 | /** |
148 | * die_match_name - Match diename and glob | 164 | * die_match_name - Match diename/linkage name and glob |
149 | * @dw_die: a DIE | 165 | * @dw_die: a DIE |
150 | * @glob: a string of target glob pattern | 166 | * @glob: a string of target glob pattern |
151 | * | 167 | * |
152 | * Glob matching the name of @dw_die and @glob. Return false if matching fail. | 168 | * Glob matching the name of @dw_die and @glob. Return false if matching fail. |
169 | * This also match linkage name. | ||
153 | */ | 170 | */ |
154 | bool die_match_name(Dwarf_Die *dw_die, const char *glob) | 171 | bool die_match_name(Dwarf_Die *dw_die, const char *glob) |
155 | { | 172 | { |
156 | const char *name; | 173 | const char *name; |
157 | 174 | ||
158 | name = dwarf_diename(dw_die); | 175 | name = dwarf_diename(dw_die); |
159 | return name ? strglobmatch(name, glob) : false; | 176 | if (name && strglobmatch(name, glob)) |
177 | return true; | ||
178 | /* fall back to check linkage name */ | ||
179 | name = die_get_linkage_name(dw_die); | ||
180 | if (name && strglobmatch(name, glob)) | ||
181 | return true; | ||
182 | |||
183 | return false; | ||
160 | } | 184 | } |
161 | 185 | ||
162 | /** | 186 | /** |
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h index 8b6d2f83af02..8ac53bf1ec4e 100644 --- a/tools/perf/util/dwarf-aux.h +++ b/tools/perf/util/dwarf-aux.h | |||
@@ -38,6 +38,9 @@ int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr, | |||
38 | int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, | 38 | 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 | /* Get DW_AT_linkage_name (should be NULL for C binary) */ | ||
42 | const char *die_get_linkage_name(Dwarf_Die *dw_die); | ||
43 | |||
41 | /* Ensure that this DIE is a subprogram and definition (not declaration) */ | 44 | /* Ensure that this DIE is a subprogram and definition (not declaration) */ |
42 | bool die_is_func_def(Dwarf_Die *dw_die); | 45 | bool die_is_func_def(Dwarf_Die *dw_die); |
43 | 46 | ||