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 /tools/perf | |
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>
Diffstat (limited to 'tools/perf')
-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; | 712 | struct debuginfo *dinfo; |
709 | 713 | ||
710 | ret = init_vmlinux(); | 714 | ret = init_symbol_maps(false); |
711 | if (ret < 0) | 715 | if (ret < 0) |
712 | return ret; | 716 | return ret; |
713 | 717 | ||
714 | dinfo = open_debuginfo(module); | 718 | dinfo = open_debuginfo(module); |
715 | if (!dinfo) { | 719 | if (!dinfo) { |
716 | pr_warning("Failed to open debuginfo file.\n"); | 720 | pr_warning("Failed to open debuginfo file.\n"); |
717 | return -ENOENT; | 721 | ret = -ENOENT; |
722 | goto out; | ||
718 | } | 723 | } |
719 | 724 | ||
720 | setup_pager(); | 725 | setup_pager(); |
@@ -724,6 +729,8 @@ int show_available_vars(struct perf_probe_event *pevs, int npevs, | |||
724 | externs); | 729 | externs); |
725 | 730 | ||
726 | debuginfo__delete(dinfo); | 731 | debuginfo__delete(dinfo); |
732 | out: | ||
733 | exit_symbol_maps(); | ||
727 | return ret; | 734 | return ret; |
728 | } | 735 | } |
729 | 736 | ||
@@ -1807,7 +1814,7 @@ int show_perf_probe_events(void) | |||
1807 | if (fd < 0) | 1814 | if (fd < 0) |
1808 | return fd; | 1815 | return fd; |
1809 | 1816 | ||
1810 | ret = init_vmlinux(); | 1817 | ret = init_symbol_maps(false); |
1811 | if (ret < 0) | 1818 | if (ret < 0) |
1812 | return ret; | 1819 | return ret; |
1813 | 1820 | ||
@@ -1820,6 +1827,7 @@ int show_perf_probe_events(void) | |||
1820 | close(fd); | 1827 | close(fd); |
1821 | } | 1828 | } |
1822 | 1829 | ||
1830 | exit_symbol_maps(); | ||
1823 | return ret; | 1831 | return ret; |
1824 | } | 1832 | } |
1825 | 1833 | ||
@@ -2135,12 +2143,7 @@ int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, | |||
2135 | if (pkgs == NULL) | 2143 | if (pkgs == NULL) |
2136 | return -ENOMEM; | 2144 | return -ENOMEM; |
2137 | 2145 | ||
2138 | if (!pevs->uprobes) | 2146 | ret = init_symbol_maps(pevs->uprobes); |
2139 | /* Init vmlinux path */ | ||
2140 | ret = init_vmlinux(); | ||
2141 | else | ||
2142 | ret = init_user_exec(); | ||
2143 | |||
2144 | if (ret < 0) { | 2147 | if (ret < 0) { |
2145 | free(pkgs); | 2148 | free(pkgs); |
2146 | return ret; | 2149 | return ret; |
@@ -2174,6 +2177,7 @@ end: | |||
2174 | zfree(&pkgs[i].tevs); | 2177 | zfree(&pkgs[i].tevs); |
2175 | } | 2178 | } |
2176 | free(pkgs); | 2179 | free(pkgs); |
2180 | exit_symbol_maps(); | ||
2177 | 2181 | ||
2178 | return ret; | 2182 | return ret; |
2179 | } | 2183 | } |
@@ -2347,7 +2351,7 @@ static int available_kernel_funcs(const char *module) | |||
2347 | struct map *map; | 2351 | struct map *map; |
2348 | int ret; | 2352 | int ret; |
2349 | 2353 | ||
2350 | ret = init_vmlinux(); | 2354 | ret = init_symbol_maps(false); |
2351 | if (ret < 0) | 2355 | if (ret < 0) |
2352 | return ret; | 2356 | return ret; |
2353 | 2357 | ||
@@ -2356,7 +2360,10 @@ static int available_kernel_funcs(const char *module) | |||
2356 | pr_err("Failed to find %s map.\n", (module) ? : "kernel"); | 2360 | pr_err("Failed to find %s map.\n", (module) ? : "kernel"); |
2357 | return -EINVAL; | 2361 | return -EINVAL; |
2358 | } | 2362 | } |
2359 | return __show_available_funcs(map); | 2363 | ret = __show_available_funcs(map); |
2364 | exit_symbol_maps(); | ||
2365 | |||
2366 | return ret; | ||
2360 | } | 2367 | } |
2361 | 2368 | ||
2362 | static int available_user_funcs(const char *target) | 2369 | static int available_user_funcs(const char *target) |
@@ -2364,7 +2371,7 @@ static int available_user_funcs(const char *target) | |||
2364 | struct map *map; | 2371 | struct map *map; |
2365 | int ret; | 2372 | int ret; |
2366 | 2373 | ||
2367 | ret = init_user_exec(); | 2374 | ret = init_symbol_maps(true); |
2368 | if (ret < 0) | 2375 | if (ret < 0) |
2369 | return ret; | 2376 | return ret; |
2370 | 2377 | ||
@@ -2372,6 +2379,7 @@ static int available_user_funcs(const char *target) | |||
2372 | ret = __show_available_funcs(map); | 2379 | ret = __show_available_funcs(map); |
2373 | dso__delete(map->dso); | 2380 | dso__delete(map->dso); |
2374 | map__delete(map); | 2381 | map__delete(map); |
2382 | exit_symbol_maps(); | ||
2375 | return ret; | 2383 | return ret; |
2376 | } | 2384 | } |
2377 | 2385 | ||