aboutsummaryrefslogtreecommitdiffstats
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
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>
-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;