Commit ee45b6c2 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo

perf probe: Fix to do exit call for symbol maps

Some perf-probe commands do symbol_init() but doesn't do exit call.

This fixes that to call symbol_exit() and releases machine if needed.

This also merges init_vmlinux() and init_user_exec() because both of
them are doing similar things.  (init_user_exec() just skips init
vmlinux related symbol maps)

Changes from v2:
 - Not to set symbol_conf.try_vmlinux_path in init_symbol_maps()
   (Thanks to Namhyung Kim!)
Signed-off-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: "David A. Long" <dave.long@linaro.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: yrl.pp-manager.tt@hitachi.com
Link: http://lkml.kernel.org/r/20140206053204.29635.28334.stgit@kbuild-fedora.yrl.intra.hitachi.co.jpSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent c96626b1
...@@ -73,31 +73,31 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp); ...@@ -73,31 +73,31 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
static int convert_name_to_addr(struct perf_probe_event *pev, static int convert_name_to_addr(struct perf_probe_event *pev,
const char *exec); const char *exec);
static void clear_probe_trace_event(struct probe_trace_event *tev); static void clear_probe_trace_event(struct probe_trace_event *tev);
static struct machine machine; static struct machine *host_machine;
/* Initialize symbol maps and path of vmlinux/modules */ /* Initialize symbol maps and path of vmlinux/modules */
static int init_vmlinux(void) static int init_symbol_maps(bool user_only)
{ {
int ret; int ret;
symbol_conf.sort_by_name = true; symbol_conf.sort_by_name = true;
if (symbol_conf.vmlinux_name == NULL)
symbol_conf.try_vmlinux_path = true;
else
pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
ret = symbol__init(); ret = symbol__init();
if (ret < 0) { if (ret < 0) {
pr_debug("Failed to init symbol map.\n"); pr_debug("Failed to init symbol map.\n");
goto out; goto out;
} }
ret = machine__init(&machine, "", HOST_KERNEL_ID); if (host_machine || user_only) /* already initialized */
if (ret < 0) return 0;
goto out;
if (machine__create_kernel_maps(&machine) < 0) { if (symbol_conf.vmlinux_name)
pr_debug("machine__create_kernel_maps() failed.\n"); pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
goto out;
host_machine = machine__new_host();
if (!host_machine) {
pr_debug("machine__new_host() failed.\n");
symbol__exit();
ret = -1;
} }
out: out:
if (ret < 0) if (ret < 0)
...@@ -105,21 +105,30 @@ static int init_vmlinux(void) ...@@ -105,21 +105,30 @@ static int init_vmlinux(void)
return ret; return ret;
} }
static void exit_symbol_maps(void)
{
if (host_machine) {
machine__delete(host_machine);
host_machine = NULL;
}
symbol__exit();
}
static struct symbol *__find_kernel_function_by_name(const char *name, static struct symbol *__find_kernel_function_by_name(const char *name,
struct map **mapp) struct map **mapp)
{ {
return machine__find_kernel_function_by_name(&machine, name, mapp, return machine__find_kernel_function_by_name(host_machine, name, mapp,
NULL); NULL);
} }
static struct map *kernel_get_module_map(const char *module) static struct map *kernel_get_module_map(const char *module)
{ {
struct rb_node *nd; struct rb_node *nd;
struct map_groups *grp = &machine.kmaps; struct map_groups *grp = &host_machine->kmaps;
/* A file path -- this is an offline module */ /* A file path -- this is an offline module */
if (module && strchr(module, '/')) if (module && strchr(module, '/'))
return machine__new_module(&machine, 0, module); return machine__new_module(host_machine, 0, module);
if (!module) if (!module)
module = "kernel"; module = "kernel";
...@@ -141,7 +150,7 @@ static struct dso *kernel_get_module_dso(const char *module) ...@@ -141,7 +150,7 @@ static struct dso *kernel_get_module_dso(const char *module)
const char *vmlinux_name; const char *vmlinux_name;
if (module) { if (module) {
list_for_each_entry(dso, &machine.kernel_dsos, node) { list_for_each_entry(dso, &host_machine->kernel_dsos, node) {
if (strncmp(dso->short_name + 1, module, if (strncmp(dso->short_name + 1, module,
dso->short_name_len - 2) == 0) dso->short_name_len - 2) == 0)
goto found; goto found;
...@@ -150,7 +159,7 @@ static struct dso *kernel_get_module_dso(const char *module) ...@@ -150,7 +159,7 @@ static struct dso *kernel_get_module_dso(const char *module)
return NULL; return NULL;
} }
map = machine.vmlinux_maps[MAP__FUNCTION]; map = host_machine->vmlinux_maps[MAP__FUNCTION];
dso = map->dso; dso = map->dso;
vmlinux_name = symbol_conf.vmlinux_name; vmlinux_name = symbol_conf.vmlinux_name;
...@@ -173,20 +182,6 @@ const char *kernel_get_module_path(const char *module) ...@@ -173,20 +182,6 @@ const char *kernel_get_module_path(const char *module)
return (dso) ? dso->long_name : NULL; return (dso) ? dso->long_name : NULL;
} }
static int init_user_exec(void)
{
int ret = 0;
symbol_conf.try_vmlinux_path = false;
symbol_conf.sort_by_name = true;
ret = symbol__init();
if (ret < 0)
pr_debug("Failed to init symbol map.\n");
return ret;
}
static int convert_exec_to_group(const char *exec, char **result) static int convert_exec_to_group(const char *exec, char **result)
{ {
char *ptr1, *ptr2, *exec_copy; char *ptr1, *ptr2, *exec_copy;
...@@ -563,7 +558,7 @@ static int _show_one_line(FILE *fp, int l, bool skip, bool show_num) ...@@ -563,7 +558,7 @@ static int _show_one_line(FILE *fp, int l, bool skip, bool show_num)
* Show line-range always requires debuginfo to find source file and * Show line-range always requires debuginfo to find source file and
* line number. * line number.
*/ */
int show_line_range(struct line_range *lr, const char *module) static int __show_line_range(struct line_range *lr, const char *module)
{ {
int l = 1; int l = 1;
struct line_node *ln; struct line_node *ln;
...@@ -573,10 +568,6 @@ int show_line_range(struct line_range *lr, const char *module) ...@@ -573,10 +568,6 @@ int show_line_range(struct line_range *lr, const char *module)
char *tmp; char *tmp;
/* Search a line range */ /* Search a line range */
ret = init_vmlinux();
if (ret < 0)
return ret;
dinfo = open_debuginfo(module); dinfo = open_debuginfo(module);
if (!dinfo) { if (!dinfo) {
pr_warning("Failed to open debuginfo file.\n"); pr_warning("Failed to open debuginfo file.\n");
...@@ -646,6 +637,19 @@ int show_line_range(struct line_range *lr, const char *module) ...@@ -646,6 +637,19 @@ int show_line_range(struct line_range *lr, const char *module)
return ret; return ret;
} }
int show_line_range(struct line_range *lr, const char *module)
{
int ret;
ret = init_symbol_maps(false);
if (ret < 0)
return ret;
ret = __show_line_range(lr, module);
exit_symbol_maps();
return ret;
}
static int show_available_vars_at(struct debuginfo *dinfo, static int show_available_vars_at(struct debuginfo *dinfo,
struct perf_probe_event *pev, struct perf_probe_event *pev,
int max_vls, struct strfilter *_filter, int max_vls, struct strfilter *_filter,
...@@ -707,14 +711,15 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, ...@@ -707,14 +711,15 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
int i, ret = 0; int i, ret = 0;
struct debuginfo *dinfo; struct debuginfo *dinfo;
ret = init_vmlinux(); ret = init_symbol_maps(false);
if (ret < 0) if (ret < 0)
return ret; return ret;
dinfo = open_debuginfo(module); dinfo = open_debuginfo(module);
if (!dinfo) { if (!dinfo) {
pr_warning("Failed to open debuginfo file.\n"); pr_warning("Failed to open debuginfo file.\n");
return -ENOENT; ret = -ENOENT;
goto out;
} }
setup_pager(); setup_pager();
...@@ -724,6 +729,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, ...@@ -724,6 +729,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs,
externs); externs);
debuginfo__delete(dinfo); debuginfo__delete(dinfo);
out:
exit_symbol_maps();
return ret; return ret;
} }
...@@ -1807,7 +1814,7 @@ int show_perf_probe_events(void) ...@@ -1807,7 +1814,7 @@ int show_perf_probe_events(void)
if (fd < 0) if (fd < 0)
return fd; return fd;
ret = init_vmlinux(); ret = init_symbol_maps(false);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -1820,6 +1827,7 @@ int show_perf_probe_events(void) ...@@ -1820,6 +1827,7 @@ int show_perf_probe_events(void)
close(fd); close(fd);
} }
exit_symbol_maps();
return ret; return ret;
} }
...@@ -2135,12 +2143,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, ...@@ -2135,12 +2143,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
if (pkgs == NULL) if (pkgs == NULL)
return -ENOMEM; return -ENOMEM;
if (!pevs->uprobes) ret = init_symbol_maps(pevs->uprobes);
/* Init vmlinux path */
ret = init_vmlinux();
else
ret = init_user_exec();
if (ret < 0) { if (ret < 0) {
free(pkgs); free(pkgs);
return ret; return ret;
...@@ -2174,6 +2177,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, ...@@ -2174,6 +2177,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
zfree(&pkgs[i].tevs); zfree(&pkgs[i].tevs);
} }
free(pkgs); free(pkgs);
exit_symbol_maps();
return ret; return ret;
} }
...@@ -2347,7 +2351,7 @@ static int available_kernel_funcs(const char *module) ...@@ -2347,7 +2351,7 @@ static int available_kernel_funcs(const char *module)
struct map *map; struct map *map;
int ret; int ret;
ret = init_vmlinux(); ret = init_symbol_maps(false);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -2356,7 +2360,10 @@ static int available_kernel_funcs(const char *module) ...@@ -2356,7 +2360,10 @@ static int available_kernel_funcs(const char *module)
pr_err("Failed to find %s map.\n", (module) ? : "kernel"); pr_err("Failed to find %s map.\n", (module) ? : "kernel");
return -EINVAL; return -EINVAL;
} }
return __show_available_funcs(map); ret = __show_available_funcs(map);
exit_symbol_maps();
return ret;
} }
static int available_user_funcs(const char *target) static int available_user_funcs(const char *target)
...@@ -2364,7 +2371,7 @@ static int available_user_funcs(const char *target) ...@@ -2364,7 +2371,7 @@ static int available_user_funcs(const char *target)
struct map *map; struct map *map;
int ret; int ret;
ret = init_user_exec(); ret = init_symbol_maps(true);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -2372,6 +2379,7 @@ static int available_user_funcs(const char *target) ...@@ -2372,6 +2379,7 @@ static int available_user_funcs(const char *target)
ret = __show_available_funcs(map); ret = __show_available_funcs(map);
dso__delete(map->dso); dso__delete(map->dso);
map__delete(map); map__delete(map);
exit_symbol_maps();
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment