mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
41840d211c
commit
76c588f1f6
|
@ -134,8 +134,6 @@ static struct dso *__machine__addnew_vdso(struct machine *machine, const char *s
|
|||
return dso;
|
||||
}
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
|
||||
static enum dso_type machine__thread_dso_type(struct machine *machine,
|
||||
struct thread *thread)
|
||||
{
|
||||
|
@ -156,6 +154,8 @@ static enum dso_type machine__thread_dso_type(struct machine *machine,
|
|||
return dso_type;
|
||||
}
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
|
||||
static int vdso__do_copy_compat(FILE *f, int fd)
|
||||
{
|
||||
char buf[4096];
|
||||
|
@ -283,8 +283,38 @@ static int __machine__findnew_vdso_compat(struct machine *machine,
|
|||
|
||||
#endif
|
||||
|
||||
static struct dso *machine__find_vdso(struct machine *machine,
|
||||
struct thread *thread)
|
||||
{
|
||||
struct dso *dso = NULL;
|
||||
enum dso_type dso_type;
|
||||
|
||||
dso_type = machine__thread_dso_type(machine, thread);
|
||||
switch (dso_type) {
|
||||
case DSO__TYPE_32BIT:
|
||||
dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO32, true);
|
||||
if (!dso) {
|
||||
dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO,
|
||||
true);
|
||||
if (dso && dso_type != dso__type(dso, machine))
|
||||
dso = NULL;
|
||||
}
|
||||
break;
|
||||
case DSO__TYPE_X32BIT:
|
||||
dso = __dsos__find(&machine->dsos, DSO__NAME_VDSOX32, true);
|
||||
break;
|
||||
case DSO__TYPE_64BIT:
|
||||
case DSO__TYPE_UNKNOWN:
|
||||
default:
|
||||
dso = __dsos__find(&machine->dsos, DSO__NAME_VDSO, true);
|
||||
break;
|
||||
}
|
||||
|
||||
return dso;
|
||||
}
|
||||
|
||||
struct dso *machine__findnew_vdso(struct machine *machine,
|
||||
struct thread *thread __maybe_unused)
|
||||
struct thread *thread)
|
||||
{
|
||||
struct vdso_info *vdso_info;
|
||||
struct dso *dso = NULL;
|
||||
|
@ -297,6 +327,10 @@ struct dso *machine__findnew_vdso(struct machine *machine,
|
|||
if (!vdso_info)
|
||||
goto out_unlock;
|
||||
|
||||
dso = machine__find_vdso(machine, thread);
|
||||
if (dso)
|
||||
goto out_unlock;
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
if (__machine__findnew_vdso_compat(machine, thread, vdso_info, &dso))
|
||||
goto out_unlock;
|
||||
|
|
Loading…
Reference in New Issue