diff options
author | He Kuang <hekuang@huawei.com> | 2016-05-17 05:04:54 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-06-23 09:25:58 -0400 |
commit | 76c588f1f6b560c510953b390bc0a26c27cbfbd0 (patch) | |
tree | 14a955a4e78daa430957441ba5401bcd6c48f3e8 /tools/perf/util/vdso.c | |
parent | 41840d211c518e6af6e327b03e09323824e563bf (diff) |
perf tools: Find right DSO taking into account if binary is 32 or 64-bit
There's a problem in machine__findnew_vdso(), vdso buildid generated by a
32-bit machine stores it with the name 'vdso', but when processing buildid on a
64-bit machine with the same 'perf.data', perf will search for vdso named as
'vdso32' and get failed.
This patch tries to find the existing dsos in machine->dsos by thread dso_type.
64-bit thread tries to find vdso with name 'vdso', because all 64-bit vdso is
named as that. 32-bit thread first tries to find vdso with name 'vdso32' if
this thread was run on 64-bit machine, if failed, then it tries 'vdso' which
indicates that the thread was run on 32-bit machine when recording.
Committer note:
Additional explanation by Adrian Hunter:
We match maps to builds ids using the file name - consider
machine__findnew_[v]dso() called in map__new(). So in the context of a perf
data file, we consider the file name to be unique.
A vdso map does not have a file name - all we know is that it is vdso. We look
at the thread to tell if it is 32-bit, 64-bit or x32. Then we need to get the
build id which has been recorded using short name "[vdso]" or "[vdso32]" or
"[vdsox32]".
The problem is that on a 32-bit machine, we use the name "[vdso]". If you take
a 32-bit perf data file to a 64-bit machine, it gets hard to figure out if
"[vdso]" is 32-bit or 64-bit.
This patch solves that problem.
----
This also merges a followup patch fixing a problem introduced by the
original submission of this patch, that would crash 'perf record' when
recording samples for a 32-bit app on a 64-bit system.
Signed-off-by: He Kuang <hekuang@huawei.com>
Acked-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Ekaterina Tumanova <tumanova@linux.vnet.ibm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/r/1463475894-163531-1-git-send-email-hekuang@huawei.com
Link: http://lkml.kernel.org/r/1466578626-92406-6-git-send-email-hekuang@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/vdso.c')
-rw-r--r-- | tools/perf/util/vdso.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c index 44d440da15dc..7bdcad484225 100644 --- a/tools/perf/util/vdso.c +++ b/tools/perf/util/vdso.c | |||
@@ -134,8 +134,6 @@ static struct dso *__machine__addnew_vdso(struct machine *machine, const char *s | |||
134 | return dso; | 134 | return dso; |
135 | } | 135 | } |
136 | 136 | ||
137 | #if BITS_PER_LONG == 64 | ||
138 | |||
139 | static enum dso_type machine__thread_dso_type(struct machine *machine, | 137 | static enum dso_type machine__thread_dso_type(struct machine *machine, |
140 | struct thread *thread) | 138 | struct thread *thread) |
141 | { | 139 | { |
@@ -156,6 +154,8 @@ static enum dso_type machine__thread_dso_type(struct machine *machine, | |||
156 | return dso_type; | 154 | return dso_type; |
157 | } | 155 | } |
158 | 156 | ||
157 | #if BITS_PER_LONG == 64 | ||
158 | |||
159 | static int vdso__do_copy_compat(FILE *f, int fd) | 159 | static int vdso__do_copy_compat(FILE *f, int fd) |
160 | { | 160 | { |
161 | char buf[4096]; | 161 | char buf[4096]; |
@@ -283,8 +283,38 @@ static int __machine__findnew_vdso_compat(struct machine *machine, | |||
283 | 283 | ||
284 | #endif | 284 | #endif |
285 | 285 | ||
286 | static struct dso *machine__find_vdso(struct machine *machine, | ||
287 | struct thread *thread) | ||
288 | { | ||
289 | struct dso *dso = NULL; | ||
290 | enum dso_type dso_type; | ||
291 | |||
292 | dso_type = machine__thread_dso_type(machine, thread); | ||
293 | switch (dso_type) { | ||
294 | case DSO__TYPE_32BIT: | ||
295 | dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO32, true); | ||
296 | if (!dso) { | ||
297 | dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO, | ||
298 | true); | ||
299 | if (dso && dso_type != dso__type(dso, machine)) | ||
300 | dso = NULL; | ||
301 | } | ||
302 | break; | ||
303 | case DSO__TYPE_X32BIT: | ||
304 | dso = __dsos__find(&machine->dsos, DSO__NAME_VDSOX32, true); | ||
305 | break; | ||
306 | case DSO__TYPE_64BIT: | ||
307 | case DSO__TYPE_UNKNOWN: | ||
308 | default: | ||
309 | dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO, true); | ||
310 | break; | ||
311 | } | ||
312 | |||
313 | return dso; | ||
314 | } | ||
315 | |||
286 | struct dso *machine__findnew_vdso(struct machine *machine, | 316 | struct dso *machine__findnew_vdso(struct machine *machine, |
287 | struct thread *thread __maybe_unused) | 317 | struct thread *thread) |
288 | { | 318 | { |
289 | struct vdso_info *vdso_info; | 319 | struct vdso_info *vdso_info; |
290 | struct dso *dso = NULL; | 320 | struct dso *dso = NULL; |
@@ -297,6 +327,10 @@ struct dso *machine__findnew_vdso(struct machine *machine, | |||
297 | if (!vdso_info) | 327 | if (!vdso_info) |
298 | goto out_unlock; | 328 | goto out_unlock; |
299 | 329 | ||
330 | dso = machine__find_vdso(machine, thread); | ||
331 | if (dso) | ||
332 | goto out_unlock; | ||
333 | |||
300 | #if BITS_PER_LONG == 64 | 334 | #if BITS_PER_LONG == 64 |
301 | if (__machine__findnew_vdso_compat(machine, thread, vdso_info, &dso)) | 335 | if (__machine__findnew_vdso_compat(machine, thread, vdso_info, &dso)) |
302 | goto out_unlock; | 336 | goto out_unlock; |