perf probe: Show the error reason comes from invalid DSO
PATCH 1/1 perf probe: Show the error reason comes from invalid DSO
Show the reason of error when dso__load* failed. This shows when user gives wrong kernel image or wrong path.
Without this, perf probe shows an obscure message.
----
$ perf probe -k ~/kbin/linux-3.x86_64/vmlinux -L vfs_read
Failed to find path of kernel module.
Error: Failed to show lines.
----With this, perf shows appropriate error message.
----
$ perf probe -k ~/kbin/linux-3.x86_64/vmlinux -L vfs_read
Failed to find the path for kernel: Mismatching build id
Error: Failed to show lines.
----
And
----
$ perf probe -k /non-exist/kernel/vmlinux -L vfs_read
Failed to find the path for kernel: No such file or directory
Error: Failed to show lines.
----Signed-off-by Masami Hiramatsu <[email protected]>
--- tools/perf/util/probe-event.c | 47 +++++++++++++++++++++-------------------- tools/perf/util/probe-event.h | 3 --- 2 files changed, 24 insertions(+), 26 deletions(-)
tools/perf/util/probe-event.c +24 -23
@@ -201,11 +201,12 @@ static void put_target_map(struct map *map, bool user) } -static struct dso *kernel_get_module_dso (const char *module) +static int kernel_get_module_dso (const char *module,struct dso **pdso) {struct dso *dso;struct map *map;const char *vmlinux_name; +int ret =0 ;if (module) { list_for_each_entry(dso, &host_machine->kernel_dsos.head,
@@ -215,30 +216,21 @@ static struct dso *kernel_get_module_dso(const char *module) goto found; }pr_debug ("Failed to find module %s.\n" , module); -return NULL ; +return -ENOENT ; } map = host_machine->vmlinux_maps[MAP__FUNCTION ]; dso = map->dso; vmlinux_name = symbol_conf.vmlinux_name; -if (vmlinux_name) { -if (dso__load_vmlinux (dso, map, vmlinux_name, false,NULL ) <=0 ) -return NULL ; - }else { -if (dso__load_vmlinux_path (dso, map,NULL ) <=0 ) { -pr_debug ("Failed to load kernel map.\n" ); -return NULL ; - } - } + dso->load_errno =0 ; +if (vmlinux_name) + ret =dso__load_vmlinux (dso, map, vmlinux_name, false,NULL ); +else + ret =dso__load_vmlinux_path (dso, map,NULL ); found: -return dso; -} - -const char *kernel_get_module_path (const char *module) -{ -struct dso *dso =kernel_get_module_dso (module); -return (dso) ? dso->long_name :NULL ; + *pdso = dso; +return ret; }static int convert_exec_to_group (const char *exec,char **result)
@@ -390,16 +382,25 @@ static int get_alternative_line_range(struct debuginfo *dinfo,static struct debuginfo *open_debuginfo (const char *module,bool silent) {const char *path = module; -struct debuginfo *ret; +char reason[STRERR_BUFSIZE ]; +struct debuginfo *ret =NULL ; +struct dso *dso =NULL ; +int err;if (!module || !strchr (module,'/' )) { - path =kernel_get_module_path (module); -if (!path) { + err =kernel_get_module_dso (module, &dso); +if (err <0 ) { +if (!dso || dso->load_errno ==0 ) { +if (!strerror_r (-err, reason,STRERR_BUFSIZE )) +strcpy (reason,"(unknown)" ); + }else +dso__strerror_load (dso, reason,STRERR_BUFSIZE );if (!silent) -pr_err ("Failed to find path of %s module.\n" , - module ?:"kernel" ); +pr_err ("Failed to find the path for %s: %s\n" , + module ?:"kernel" , reason);return NULL ; } + path = dso->long_name; } ret =debuginfo__new (path);if (!ret && !silent) {
tools/perf/util/probe-event.h +0 -3
@@ -131,9 +131,6 @@ extern void line_range__clear(struct line_range *lr);/* Initialize line range */ extern int line_range__init (struct line_range *lr); -/* Internal use: Return kernel/module path */ -extern const char *kernel_get_module_path (const char *module); -extern int add_perf_probe_events (struct perf_probe_event *pevs,int npevs);extern int del_perf_probe_events (struct strfilter *filter);extern int show_perf_probe_events (struct strfilter *filter);
Arnaldo, could you also apply this?
This will helps users to find the reason why perf probe failed to open the debuginfo.
Quoted 133 lines · Masami Hiramatsu
Show the reason of error when dso__load* failed. This shows when user gives wrong kernel image or wrong path.
Without this, perf probe shows an obscure message.
----$ perf probe -k ~/kbin/linux-3.x86_64/vmlinux -L vfs_read Failed to find path of kernel module. Error: Failed to show lines. ----With this, perf shows appropriate error message.
----$ perf probe -k ~/kbin/linux-3.x86_64/vmlinux -L vfs_read Failed to find the path for kernel: Mismatching build id Error: Failed to show lines. ---- And ---- $ perf probe -k /non-exist/kernel/vmlinux -L vfs_read Failed to find the path for kernel: No such file or directory Error: Failed to show lines. ----Signed-off-by Masami Hiramatsu <[email protected]>--- tools/perf/util/probe-event.c | 47 +++++++++++++++++++++-------------------- tools/perf/util/probe-event.h | 3 --- 2 files changed, 24 insertions(+), 26 deletions(-)tools/perf/util/probe-event.c +24
-23@@ -201,11 +201,12 @@ static void put_target_map(struct map *map, bool user) } -static struct dso *kernel_get_module_dso (const char *module) +static int kernel_get_module_dso (const char *module,struct dso **pdso) {struct dso *dso;struct map *map;const char *vmlinux_name; +int ret =0 ;if (module) { list_for_each_entry(dso, &host_machine->kernel_dsos.head,@@ -215,30 +216,21 @@ static struct dso *kernel_get_module_dso(const char *module) goto found; }pr_debug ("Failed to find module %s.\n" , module); -return NULL ; +return -ENOENT ; } map = host_machine->vmlinux_maps[MAP__FUNCTION ]; dso = map->dso; vmlinux_name = symbol_conf.vmlinux_name; -if (vmlinux_name) { -if (dso__load_vmlinux (dso, map, vmlinux_name, false,NULL ) <=0 ) -return NULL ; - }else { -if (dso__load_vmlinux_path (dso, map,NULL ) <=0 ) { -pr_debug ("Failed to load kernel map.\n" ); -return NULL ; - } - } + dso->load_errno =0 ; +if (vmlinux_name) + ret =dso__load_vmlinux (dso, map, vmlinux_name, false,NULL ); +else + ret =dso__load_vmlinux_path (dso, map,NULL ); found: -return dso; -} - -const char *kernel_get_module_path (const char *module) -{ -struct dso *dso =kernel_get_module_dso (module); -return (dso) ? dso->long_name :NULL ; + *pdso = dso; +return ret; }static int convert_exec_to_group (const char *exec,char **result)@@ -390,16 +382,25 @@ static int get_alternative_line_range(struct debuginfo *dinfo,static struct debuginfo *open_debuginfo (const char *module,bool silent) {const char *path = module; -struct debuginfo *ret; +char reason[STRERR_BUFSIZE ]; +struct debuginfo *ret =NULL ; +struct dso *dso =NULL ; +int err;if (!module || !strchr (module,'/' )) { - path =kernel_get_module_path (module); -if (!path) { + err =kernel_get_module_dso (module, &dso); +if (err <0 ) { +if (!dso || dso->load_errno ==0 ) { +if (!strerror_r (-err, reason,STRERR_BUFSIZE )) +strcpy (reason,"(unknown)" ); + }else +dso__strerror_load (dso, reason,STRERR_BUFSIZE );if (!silent) -pr_err ("Failed to find path of %s module.\n" , - module ?:"kernel" ); +pr_err ("Failed to find the path for %s: %s\n" , + module ?:"kernel" , reason);return NULL ; } + path = dso->long_name; } ret =debuginfo__new (path);if (!ret && !silent) {tools/perf/util/probe-event.h +0
-3@@ -131,9 +131,6 @@ extern void line_range__clear(struct line_range *lr);/* Initialize line range */ extern int line_range__init (struct line_range *lr); -/* Internal use: Return kernel/module path */ -extern const char *kernel_get_module_path (const char *module); -extern int add_perf_probe_events (struct perf_probe_event *pevs,int npevs);extern int del_perf_probe_events (struct strfilter *filter);extern int show_perf_probe_events (struct strfilter *filter);
Signature · 5 lines
Masami HIRAMATSU Linux Technology Research Center, System Productivity Research Dept. Center for Technology Innovation - Systems Engineering Hitachi, Ltd., Research & Development Group E-mail: [email protected]