diff options
| author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2014-02-06 00:32:04 -0500 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2014-02-18 07:34:50 -0500 |
| commit | ee45b6c2c52d4217aae82eb2e8136fa2f8b93303 (patch) | |
| tree | 542bbd6330f9d036d332dab9932644976958420a | |
| parent | c96626b1da589075b1b3e815239ceace11350662 (diff) | |
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: Masami 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.jp
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
| -rw-r--r-- | tools/perf/util/probe-event.c | 104 |
1 files changed, 56 insertions, 48 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index d8b048c20cde..9aa77832099a 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
| @@ -73,31 +73,31 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp); | |||
| 73 | static int convert_name_to_addr(struct perf_probe_event *pev, | 73 | static int convert_name_to_addr(struct perf_probe_event *pev, |
| 74 | const char *exec); | 74 | const char *exec); |
| 75 | static void clear_probe_trace_event(struct probe_trace_event *tev); | 75 | static void clear_probe_trace_event(struct probe_trace_event *tev); |
| 76 | static struct machine machine; | 76 | static struct machine *host_machine; |
| 77 | 77 | ||
| 78 | /* Initialize symbol maps and path of vmlinux/modules */ | 78 | /* Initialize symbol maps and path of vmlinux/modules */ |
| 79 | static int init_vmlinux(void) | 79 | static int init_symbol_maps(bool user_only) |
| 80 | { | 80 | { |
| 81 | int ret; | 81 | int ret; |
| 82 | 82 | ||
| 83 | symbol_conf.sort_by_name = true; | 83 | symbol_conf.sort_by_name = true; |
| 84 | if (symbol_conf.vmlinux_name == NULL) | ||
| 85 | symbol_conf.try_vmlinux_path = true; | ||
| 86 | else | ||
| 87 | pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name); | ||
| 88 | ret = symbol__init(); | 84 | ret = symbol__init(); |
| 89 | if (ret < 0) { | 85 | if (ret < 0) { |
| 90 | pr_debug("Failed to init symbol map.\n"); | 86 | pr_debug("Failed to init symbol map.\n"); |
| 91 | goto out; | 87 | goto out; |
| 92 | } | 88 | } |
| 93 | 89 | ||
| 94 | ret = machine__init(&machine, "", HOST_KERNEL_ID); | 90 | if (host_machine || user_only) /* already initialized */ |
| 95 | if (ret < 0) | 91 | return 0; |
| 96 | goto out; | ||
| 97 | 92 | ||
| 98 | if (machine__create_kernel_maps(&machine) < 0) { | 93 | if (symbol_conf.vmlinux_name) |
| 99 | pr_debug("machine__create_kernel_maps() failed.\n"); | 94 | pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name); |
| 100 | goto out; | 95 | |
| 96 | host_machine = machine__new_host(); | ||
| 97 | if (!host_machine) { | ||
| 98 | pr_debug("machine__new_host() failed.\n"); | ||
| 99 | symbol__exit(); | ||
| 100 | ret = -1; | ||
| 101 | } | 101 | } |
| 102 | out: | 102 | out: |
| 103 | if (ret < 0) | 103 | if (ret < 0) |
| @@ -105,21 +105,30 @@ out: | |||
| 105 | return ret; | 105 | return ret; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static void exit_symbol_maps(void) | ||
| 109 | { | ||
| 110 | if (host_machine) { | ||
| 111 | machine__delete(host_machine); | ||
| 112 | host_machine = NULL; | ||
| 113 | } | ||
| 114 | symbol__exit(); | ||
| 115 | } | ||
| 116 | |||
| 108 | static struct symbol *__find_kernel_function_by_name(const char *name, | 117 | static struct symbol *__find_kernel_function_by_name(const char *name, |
| 109 | struct map **mapp) | 118 | struct map **mapp) |
| 110 | { | 119 | { |
| 111 | return machine__find_kernel_function_by_name(&machine, name, mapp, | 120 | return machine__find_kernel_function_by_name(host_machine, name, mapp, |
| 112 | NULL); | 121 | NULL); |
| 113 | } | 122 | } |
| 114 | 123 | ||
| 115 | static struct map *kernel_get_module_map(const char *module) | 124 | static struct map *kernel_get_module_map(const char *module) |
| 116 | { | 125 | { |
| 117 | struct rb_node *nd; | 126 | struct rb_node *nd; |
| 118 | struct map_groups *grp = &machine.kmaps; | 127 | struct map_groups *grp = &host_machine->kmaps; |
| 119 | 128 | ||
| 120 | /* A file path -- this is an offline module */ | 129 | /* A file path -- this is an offline module */ |
| 121 | if (module && strchr(module, '/')) | 130 | if (module && strchr(module, '/')) |
| 122 | return machine__new_module(&machine, 0, module); | 131 | return machine__new_module(host_machine, 0, module); |
| 123 | 132 | ||
| 124 | if (!module) | 133 | if (!module) |
| 125 | module = "kernel"; | 134 | module = "kernel"; |
| @@ -141,7 +150,7 @@ static struct dso *kernel_get_module_dso(const char *module) | |||
| 141 | const char *vmlinux_name; | 150 | const char *vmlinux_name; |
| 142 | 151 | ||
| 143 | if (module) { | 152 | if (module) { |
| 144 | list_for_each_entry(dso, &machine.kernel_dsos, node) { | 153 | list_for_each_entry(dso, &host_machine->kernel_dsos, node) { |
| 145 | if (strncmp(dso->short_name + 1, module, | 154 | if (strncmp(dso->short_name + 1, module, |
| 146 | dso->short_name_len - 2) == 0) | 155 | dso->short_name_len - 2) == 0) |
| 147 | goto found; | 156 | goto found; |
| @@ -150,7 +159,7 @@ static struct dso *kernel_get_module_dso(const char *module) | |||
| 150 | return NULL; | 159 | return NULL; |
| 151 | } | 160 | } |
| 152 | 161 | ||
| 153 | map = machine.vmlinux_maps[MAP__FUNCTION]; | 162 | map = host_machine->vmlinux_maps[MAP__FUNCTION]; |
| 154 | dso = map->dso; | 163 | dso = map->dso; |
| 155 | 164 | ||
| 156 | vmlinux_name = symbol_conf.vmlinux_name; | 165 | vmlinux_name = symbol_conf.vmlinux_name; |
| @@ -173,20 +182,6 @@ const char *kernel_get_module_path(const char *module) | |||
| 173 | return (dso) ? dso->long_name : NULL; | 182 | return (dso) ? dso->long_name : NULL; |
| 174 | } | 183 | } |
| 175 | 184 | ||
| 176 | static int init_user_exec(void) | ||
| 177 | { | ||
| 178 | int ret = 0; | ||
| 179 | |||
| 180 | symbol_conf.try_vmlinux_path = false; | ||
| 181 | symbol_conf.sort_by_name = true; | ||
| 182 | ret = symbol__init(); | ||
| 183 | |||
| 184 | if (ret < 0) | ||
| 185 | pr_debug("Failed to init symbol map.\n"); | ||
| 186 | |||
| 187 | return ret; | ||
| 188 | } | ||
| 189 | |||
| 190 | static int convert_exec_to_group(const char *exec, char **result) | 185 | static int convert_exec_to_group(const char *exec, char **result) |
| 191 | { | 186 | { |
| 192 | char *ptr1, *ptr2, *exec_copy; | 187 | char *ptr1, *ptr2, *exec_copy; |
| @@ -563,7 +558,7 @@ static int _show_one_line(FILE *fp, int l, bool skip, bool show_num) | |||
| 563 | * Show line-range always requires debuginfo to find source file and | 558 | * Show line-range always requires debuginfo to find source file and |
| 564 | * line number. | 559 | * line number. |
| 565 | */ | 560 | */ |
| 566 | int show_line_range(struct line_range *lr, const char *module) | 561 | static int __show_line_range(struct line_range *lr, const char *module) |
| 567 | { | 562 | { |
| 568 | int l = 1; | 563 | int l = 1; |
| 569 | struct line_node *ln; | 564 | struct line_node *ln; |
| @@ -573,10 +568,6 @@ int show_line_range(struct line_range *lr, const char *module) | |||
| 573 | char *tmp; | 568 | char *tmp; |
| 574 | 569 | ||
| 575 | /* Search a line range */ | 570 | /* Search a line range */ |
| 576 | ret = init_vmlinux(); | ||
| 577 | if (ret < 0) | ||
| 578 | return ret; | ||
| 579 | |||
| 580 | dinfo = open_debuginfo(module); | 571 | dinfo = open_debuginfo(module); |
| 581 | if (!dinfo) { | 572 | if (!dinfo) { |
| 582 | pr_warning("Failed to open debuginfo file.\n"); | 573 | pr_warning("Failed to open debuginfo file.\n"); |
| @@ -646,6 +637,19 @@ end: | |||
| 646 | return ret; | 637 | return ret; |
| 647 | } | 638 | } |
| 648 | 639 | ||
| 640 | int show_line_range(struct line_range *lr, const char *module) | ||
| 641 | { | ||
| 642 | int ret; | ||
| 643 | |||
| 644 | ret = init_symbol_maps(false); | ||
| 645 | if (ret < 0) | ||
| 646 | return ret; | ||
| 647 | ret = __show_line_range(lr, module); | ||
| 648 | exit_symbol_maps(); | ||
| 649 | |||
| 650 | return ret; | ||
| 651 | } | ||
| 652 | |||
| 649 | static int show_available_vars_at(struct debuginfo *dinfo, | 653 | static int show_available_vars_at(struct debuginfo *dinfo, |
| 650 | struct perf_probe_event *pev, | 654 | struct perf_probe_event *pev, |
| 651 | int max_vls, struct strfilter *_filter, | 655 | int max_vls, struct strfilter *_filter, |
| @@ -707,14 +711,15 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, | |||
| 707 | int i, ret = 0; | 711 | int i, ret = 0; |
| 708 | struct debuginfo *dinfo; | ||
