aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/vdso.c
diff options
context:
space:
mode:
authorHe Kuang <hekuang@huawei.com>2016-05-17 05:04:54 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-06-23 09:25:58 -0400
commit76c588f1f6b560c510953b390bc0a26c27cbfbd0 (patch)
tree14a955a4e78daa430957441ba5401bcd6c48f3e8 /tools/perf/util/vdso.c
parent41840d211c518e6af6e327b03e09323824e563bf (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.c40
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
139static enum dso_type machine__thread_dso_type(struct machine *machine, 137static 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
159static int vdso__do_copy_compat(FILE *f, int fd) 159static 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
286static 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
286struct dso *machine__findnew_vdso(struct machine *machine, 316struct 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;