aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2014-02-06 00:32:04 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-02-18 07:34:50 -0500
commitee45b6c2c52d4217aae82eb2e8136fa2f8b93303 (patch)
tree542bbd6330f9d036d332dab9932644976958420a /tools/perf
parentc96626b1da589075b1b3e815239ceace11350662 (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.c104
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);
73static int convert_name_to_addr(struct perf_probe_event *pev, 73static int convert_name_to_addr(struct perf_probe_event *pev,
74 const char *exec); 74 const char *exec);
75static void clear_probe_trace_event(struct probe_trace_event *tev); 75static void clear_probe_trace_event(struct probe_trace_event *tev);
76static struct machine machine; 76static struct machine *host_machine;
77 77
78/* Initialize symbol maps and path of vmlinux/modules */ 78/* Initialize symbol maps and path of vmlinux/modules */
79static int init_vmlinux(void) 79static 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 }
102out: 102out:
103 if (ret < 0) 103 if (ret < 0)
@@ -105,21 +105,30 @@ out:
105 return ret; 105 return ret;
106} 106}
107 107
108static 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
108static struct symbol *__find_kernel_function_by_name(const char *name, 117static 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
115static struct map *kernel_get_module_map(const char *module) 124static 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
176static 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
190static int convert_exec_to_group(const char *exec, char **result) 185static 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 */
566int show_line_range(struct line_range *lr, const char *module) 561static 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
640int 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
649static int show_available_vars_at(struct debuginfo *dinfo, 653static 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);
732out:
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
2362static int available_user_funcs(const char *target) 2369static 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