perf tools: Set proper module name when build-id event found
Namhyung Kim
maintainerPATCH 1/3 perf tools: Set proper module name when build-id event found
When perf processes build-id event, it creates DSOs with the build-id. But it didn't set the module short name (like '[module-name]') so when processing a kernel mmap event of the module, it cannot found the DSO as it only checks the short names.
That leads for perf to create a same DSO without the build-id info and it'll lookup the system path even if the DSO is already in the build-id cache. After kernel was updated, perf cannot find the DSO and cannot show symbols in it anymore.
You can see this if you have an old data file (w/ old kernel version):
$ perf report -i perf.data.old -v |& grep scsi_mod build id event received for /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz : cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 Failed to open /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz, continuing without symbols ...
The second message didn't show the build-id. With this patch:
$ perf report -i perf.data.old -v |& grep scsi_mod build id event received for /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz: cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz with build id cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 not found, continuing without symbols ...
Now it shows the build-id but still cannot load the symbol table. This is a different problem which will be fixed in the next patch.
--- tools/perf/util/header.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
tools/perf/util/header.c +10 -2
@@ -1469,8 +1469,16 @@ static int __event_process_build_id(struct build_id_event *bev,dso__set_build_id (dso, &bev->build_id); -if (!is_kernel_module (filename, cpumode)) - dso->kernel = dso_type; +if (dso_type !=DSO_TYPE_USER ) { +struct kmod_path m = {}; + +if (!kmod_path__parse_name (&m, filename) && m.kmod) +dso__set_short_name (dso,strdup (m.name), true); +else + dso->kernel = dso_type; + +free (m.name); + }build_id__sprintf (dso->build_id,sizeof (dso->build_id), sbuild_id);
Signature · 1 line
2.13.0
Namhyung Kim
maintainerPATCH 2/3 perf tools: Set module info when build-id event found
Like machine__findnew_module_dso(), it should set necessary info for kernel modules to find symbol info from the file. Factor out dso__set_module_info() to do it.
This is needed for dso__needs_decompress() to detect such DSOs.
--- tools/perf/util/dso.c | 15 +++++++++++++++ tools/perf/util/dso.h | 3 +++ tools/perf/util/header.c | 2 +- tools/perf/util/machine.c | 11 +---------- 4 files changed, 20 insertions(+), 11 deletions(-)
tools/perf/util/dso.c +15 -0
@@ -335,6 +335,21 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,return 0 ; } +void dso__set_module_info (struct dso *dso,struct kmod_path *m, +struct machine *machine) +{ +if (machine__is_host (machine)) + dso->symtab_type =DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ; +else + dso->symtab_type =DSO_BINARY_TYPE__GUEST_KMODULE ; + +/* _KMODULE_COMP should be next to _KMODULE */ +if (m->kmod && m->comp) + dso->symtab_type++; + +dso__set_short_name (dso,strdup (m->name), true); +} +/* * Global list of open DSOs and the counter. */
tools/perf/util/dso.h +3 -0
@@ -259,6 +259,9 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,#define kmod_path__parse_name (__m, __p) __kmod_path__parse(__m, __p, true , false)#define kmod_path__parse_ext (__m, __p) __kmod_path__parse(__m, __p, false, true) +void dso__set_module_info (struct dso *dso,struct kmod_path *m, +struct machine *machine); +/* * The dso__data_* external interface provides following functions: * dso__data_get_fd
tools/perf/util/header.c +1 -1
@@ -1473,7 +1473,7 @@ static int __event_process_build_id(struct build_id_event *bev,struct kmod_path m = {};if (!kmod_path__parse_name (&m, filename) && m.kmod) -dso__set_short_name (dso,strdup (m.name), true); +dso__set_module_info (dso, &m, machine);else dso->kernel = dso_type;
tools/perf/util/machine.c +1 -10
@@ -572,16 +572,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,if (dso ==NULL ) goto out_unlock; -if (machine__is_host (machine)) - dso->symtab_type =DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ; -else - dso->symtab_type =DSO_BINARY_TYPE__GUEST_KMODULE ; - -/* _KMODULE_COMP should be next to _KMODULE */ -if (m->kmod && m->comp) - dso->symtab_type++; - -dso__set_short_name (dso,strdup (m->name), true); +dso__set_module_info (dso, m, machine);dso__set_long_name (dso,strdup (filename), true); }
Signature · 1 line
2.13.0
tip-bot for Namhyung Kim
merge bot[tip:perf/urgent] perf symbols: Set module info when build-id event found
perf symbols: Set module info when build-id event found
Commit-ID: 6b335e8f545591c07df0f34231bd7ff7506c98c1 Gitweb: http://git.kernel.org/tip/6b335e8f545591c07df0f34231bd7ff7506c98c1 Author: Namhyung Kim <[email protected]> AuthorDate: Wed, 31 May 2017 21:01:04 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 5 Jun 2017 14:17:58 -0300
perf symbols: Set module info when build-id event found
Like machine__findnew_module_dso(), it should set necessary info for kernel modules to find symbol info from the file. Factor out dso__set_module_info() to do it.
This is needed for dso__needs_decompress() to detect such DSOs.
--- tools/perf/util/dso.c | 15 +++++++++++++++ tools/perf/util/dso.h | 3 +++ tools/perf/util/header.c | 2 +- tools/perf/util/machine.c | 11 +---------- 4 files changed, 20 insertions(+), 11 deletions(-)
tools/perf/util/dso.c +15 -0
@@ -335,6 +335,21 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,return 0 ; } +void dso__set_module_info (struct dso *dso,struct kmod_path *m, +struct machine *machine) +{ +if (machine__is_host (machine)) + dso->symtab_type =DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ; +else + dso->symtab_type =DSO_BINARY_TYPE__GUEST_KMODULE ; + +/* _KMODULE_COMP should be next to _KMODULE */ +if (m->kmod && m->comp) + dso->symtab_type++; + +dso__set_short_name (dso,strdup (m->name), true); +} +/* * Global list of open DSOs and the counter. */
tools/perf/util/dso.h +3 -0
@@ -259,6 +259,9 @@ int __kmod_path__parse(struct kmod_path *m, const char *path,#define kmod_path__parse_name (__m, __p) __kmod_path__parse(__m, __p, true , false)#define kmod_path__parse_ext (__m, __p) __kmod_path__parse(__m, __p, false, true) +void dso__set_module_info (struct dso *dso,struct kmod_path *m, +struct machine *machine); +/* * The dso__data_* external interface provides following functions: * dso__data_get_fd
tools/perf/util/header.c +1 -1
@@ -1473,7 +1473,7 @@ static int __event_process_build_id(struct build_id_event *bev,struct kmod_path m = { .name =NULL , };if (!kmod_path__parse_name (&m, filename) && m.kmod) -dso__set_short_name (dso,strdup (m.name), true); +dso__set_module_info (dso, &m, machine);else dso->kernel = dso_type;
tools/perf/util/machine.c +1 -10
@@ -572,16 +572,7 @@ static struct dso *machine__findnew_module_dso(struct machine *machine,if (dso ==NULL ) goto out_unlock; -if (machine__is_host (machine)) - dso->symtab_type =DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE ; -else - dso->symtab_type =DSO_BINARY_TYPE__GUEST_KMODULE ; - -/* _KMODULE_COMP should be next to _KMODULE */ -if (m->kmod && m->comp) - dso->symtab_type++; - -dso__set_short_name (dso,strdup (m->name), true); +dso__set_module_info (dso, m, machine);dso__set_long_name (dso,strdup (filename), true); }
Namhyung Kim
maintainerPATCH 3/3 perf tools: Use correct filename for compressed modules in build-id cache
In reply to Namhyung KimThe decompress_kmodule() is to decompress kernel module in order to load symbols from it. In DSO_BINARY_TYPE__BUILD_ID_CACHE case, it needs full file path to extract the file extension to determine decompress method. But overwriting 'name' will fail to decompress since it might point to a non-existing old file.
Instead, use dso->long_name for extension and use real filename to decompress. In DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP case, both name should be same. This can show symbols in the old modules.
Before:
$ perf report -i perf.data.old | grep scsi_mod
0.00% cc1 [scsi_mod] [k] 0x0000000000004aa6
0.00% as [scsi_mod] [k] 0x00000000000099e1
0.00% cc1 [scsi_mod] [k] 0x0000000000009830
0.00% cc1 [scsi_mod] [k] 0x0000000000001b8fAfter:
0.00% cc1 [scsi_mod] [k] scsi_handle_queue_ramp_up
0.00% as [scsi_mod] [k] scsi_sg_alloc
0.00% cc1 [scsi_mod] [k] scsi_setup_cmnd
0.00% cc1 [scsi_mod] [k] scsi_get_command--- tools/perf/util/symbol-elf.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
tools/perf/util/symbol-elf.c +1 -4
@@ -649,10 +649,7 @@ static int decompress_kmodule(struct dso *dso, const char *name, type != DSO_BINARY_TYPE__BUILD_ID_CACHE)return -1 ; -if (type ==DSO_BINARY_TYPE__BUILD_ID_CACHE ) - name = dso->long_name; - -if (kmod_path__parse_ext (&m, name) || !m.comp) +if (kmod_path__parse_ext (&m, dso->long_name) || !m.comp)return -1 ; fd =mkstemp (tmpbuf);
Signature · 1 line
2.13.0
tip-bot for Namhyung Kim
merge bot[tip:perf/urgent] perf symbols: Use correct filename for compressed modules in build-id cache
perf symbols: Use correct filename for compressed modules in build-id cache
Commit-ID: a09935b878dc8efd4b030ed1ffa0553fc9011fb8 Gitweb: http://git.kernel.org/tip/a09935b878dc8efd4b030ed1ffa0553fc9011fb8 Author: Namhyung Kim <[email protected]> AuthorDate: Wed, 31 May 2017 21:01:05 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 5 Jun 2017 14:17:59 -0300
perf symbols: Use correct filename for compressed modules in build-id cache
The decompress_kmodule() decompresses kernel modules in order to load symbols from it. In the DSO_BINARY_TYPE__BUILD_ID_CACHE case, it needs the full file path to extract the file extension to determine the decompression method. But overwriting 'name' will fail the decompression since it might point to a non-existing old file.
Instead, use dso->long_name for having the correct extension and use the real filename to decompress.
In the DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE_COMP case, both names should be the same. This allows resolving symbols in the old modules.
Before:
$ perf report -i perf.data.old | grep scsi_mod
0.00% cc1 [scsi_mod] [k] 0x0000000000004aa6
0.00% as [scsi_mod] [k] 0x00000000000099e1
0.00% cc1 [scsi_mod] [k] 0x0000000000009830
0.00% cc1 [scsi_mod] [k] 0x0000000000001b8fAfter:
0.00% cc1 [scsi_mod] [k] scsi_handle_queue_ramp_up
0.00% as [scsi_mod] [k] scsi_sg_alloc
0.00% cc1 [scsi_mod] [k] scsi_setup_cmnd
0.00% cc1 [scsi_mod] [k] scsi_get_command--- tools/perf/util/symbol-elf.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
tools/perf/util/symbol-elf.c +1 -4
@@ -649,10 +649,7 @@ static int decompress_kmodule(struct dso *dso, const char *name, type != DSO_BINARY_TYPE__BUILD_ID_CACHE)return -1 ; -if (type ==DSO_BINARY_TYPE__BUILD_ID_CACHE ) - name = dso->long_name; - -if (kmod_path__parse_ext (&m, name) || !m.comp) +if (kmod_path__parse_ext (&m, dso->long_name) || !m.comp)return -1 ; fd =mkstemp (tmpbuf);
Quoted 24 lines · Namhyung Kim
When perf processes build-id event, it creates DSOs with the build-id. But it didn't set the module short name (like '[module-name]') so when processing a kernel mmap event of the module, it cannot found the DSO as it only checks the short names.
That leads for perf to create a same DSO without the build-id info and it'll lookup the system path even if the DSO is already in the build-id cache. After kernel was updated, perf cannot find the DSO and cannot show symbols in it anymore.
You can see this if you have an old data file (w/ old kernel version):
$ perf report -i perf.data.old -v |& grep scsi_mod build id event received for /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz : cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 Failed to open /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz, continuing without symbols ...The second message didn't show the build-id. With this patch:
$ perf report -i perf.data.old -v |& grep scsi_mod build id event received for /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz: cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz with build id cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 not found, continuing without symbols ...
Quoted 4 lines
Now it shows the build-id but still cannot load the symbol table. This is a different problem which will be fixed in the next patch.
Signed-off-by Namhyung Kim <[email protected]>
for all 3:
thanks,
jirka
Em Thu, Jun 01, 2017 at 12:24:52AM +0200, Jiri Olsa escreveu:
Quoted 9 lines · Namhyung Kim
Quoted 4 lines
Now it shows the build-id but still cannot load the symbol table. This is a different problem which will be fixed in the next patch.
Signed-off-by Namhyung Kim <[email protected]>for all 3:
Acked-by Jiri Olsa <[email protected]>
Thanks, applied.
- Arnaldo
Arnaldo Carvalho de Melo
maintainerEm Wed, May 31, 2017 at 09:01:03PM +0900, Namhyung Kim escreveu:
tools/perf/util/header.c static int __event_process_build_id(struct build_id_event *bev, · line 1474
Quoted 10 lines
+++
b/tools/perf/util/header.ctools/perf/util/header.c +3
-2@@ -1469,8 +1469,16 @@ static int __event_process_build_id(struct build_id_event *bev,dso__set_build_id (dso, &bev->build_id); -if (!is_kernel_module (filename, cpumode)) - dso->kernel = dso_type; +if (dso_type !=DSO_TYPE_USER ) { +struct kmod_path m = {}; +
This fails in several distros, among them centos:7, debian:8
CC /tmp/build/perf/util/header.outil/header.c: In function '__event_process_build_id':util/header.c:1473:11: error: missing initializer for field 'name' of 'struct kmod_path' [-Werror=missing-field-initializers]
struct kmod_path m = {};
^
In file included from util/symbol.h:24:0,
from util/evsel.h:10,
from util/evlist.h:11,
from util/header.c:19:
util/dso.h:249:8: note: 'name' declared here
char *name;
^cc1: all warnings being treated as errors
mv: cannot stat '/tmp/build/perf/util/.header.o.tmp': No such file or directory make[4]: *** [/tmp/build/perf/util/header.o] Error 1
make[3]: *** [util] Error 2
make[3]: *** Waiting for unfinished jobs....
centos:5, centos:6, debian:7 have a slightly different message:
CC /tmp/build/perf/util/callchain.o
cc1: warnings being treated as errorsutil/header.c: In function '__event_process_build_id':util/header.c:1473: warning: missing initializer util/header.c:1473: warning: (near initialization for 'm.name')
MKDIR /tmp/build/perf/util/
CC /tmp/build/perf/util/values.o
mv: cannot stat `/tmp/build/perf/util/.header.o.tmp': No such file or directory
I'll fix this.
- Arnaldo
tip-bot for Namhyung Kim
merge bot[tip:perf/urgent] perf header: Set proper module name when build-id event found
In reply to Namhyung Kimperf header: Set proper module name when build-id event found
Commit-ID: 1deec1bd96ccd8beb04d2112a6d12fe20505c3a6 Gitweb: http://git.kernel.org/tip/1deec1bd96ccd8beb04d2112a6d12fe20505c3a6 Author: Namhyung Kim <[email protected]> AuthorDate: Wed, 31 May 2017 21:01:03 +0900 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 5 Jun 2017 14:16:49 -0300
perf header: Set proper module name when build-id event found
When perf processes build-id event, it creates DSOs with the build-id. But it didn't set the module short name (like '[module-name]') so when processing a kernel mmap event of the module, it cannot found the DSO as it only checks the short names.
That leads for perf to create a same DSO without the build-id info and it'll lookup the system path even if the DSO is already in the build-id cache. After kernel was updated, perf cannot find the DSO and cannot show symbols in it anymore.
You can see this if you have an old data file (w/ old kernel version):
$ perf report -i perf.data.old -v |& grep scsi_mod build id event received for /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz : cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 Failed to open /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz, continuing without symbols ...
The second message didn't show the build-id. With this patch:
$ perf report -i perf.data.old -v |& grep scsi_mod build id event received for /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz: cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 /lib/modules/3.19.2-1-ARCH/kernel/drivers/scsi/scsi_mod.ko.gz with build id cafe1ce6ca13a98a5d9ed3425cde249e57a27fc1 not found, continuing without symbols ...
Now it shows the build-id but still cannot load the symbol table. This is a different problem which will be fixed in the next patch.
--- tools/perf/util/header.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
tools/perf/util/header.c +10 -2
@@ -1469,8 +1469,16 @@ static int __event_process_build_id(struct build_id_event *bev,dso__set_build_id (dso, &bev->build_id); -if (!is_kernel_module (filename, cpumode)) - dso->kernel = dso_type; +if (dso_type !=DSO_TYPE_USER ) { +struct kmod_path m = { .name =NULL , }; + +if (!kmod_path__parse_name (&m, filename) && m.kmod) +dso__set_short_name (dso,strdup (m.name), true); +else + dso->kernel = dso_type; + +free (m.name); + }build_id__sprintf (dso->build_id,sizeof (dso->build_id), sbuild_id);