aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-probe.c')
-rw-r--r--tools/perf/builtin-probe.c94
1 files changed, 71 insertions, 23 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index c1e6774fd3ed..ad47bd4c50ef 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -41,7 +41,6 @@
41#include "util/debugfs.h" 41#include "util/debugfs.h"
42#include "util/symbol.h" 42#include "util/symbol.h"
43#include "util/thread.h" 43#include "util/thread.h"
44#include "util/session.h"
45#include "util/parse-options.h" 44#include "util/parse-options.h"
46#include "util/parse-events.h" /* For debugfs_path */ 45#include "util/parse-events.h" /* For debugfs_path */
47#include "util/probe-finder.h" 46#include "util/probe-finder.h"
@@ -55,11 +54,13 @@ static struct {
55 bool need_dwarf; 54 bool need_dwarf;
56 bool list_events; 55 bool list_events;
57 bool force_add; 56 bool force_add;
57 bool show_lines;
58 int nr_probe; 58 int nr_probe;
59 struct probe_point probes[MAX_PROBES]; 59 struct probe_point probes[MAX_PROBES];
60 struct strlist *dellist; 60 struct strlist *dellist;
61 struct perf_session *psession; 61 struct map_groups kmap_groups;
62 struct map *kmap; 62 struct map *kmaps[MAP__NR_TYPES];
63 struct line_range line_range;
63} session; 64} session;
64 65
65 66
@@ -120,8 +121,8 @@ static int opt_del_probe_event(const struct option *opt __used,
120static void evaluate_probe_point(struct probe_point *pp) 121static void evaluate_probe_point(struct probe_point *pp)
121{ 122{
122 struct symbol *sym; 123 struct symbol *sym;
123 sym = map__find_symbol_by_name(session.kmap, pp->function, 124 sym = map__find_symbol_by_name(session.kmaps[MAP__FUNCTION],
124 session.psession, NULL); 125 pp->function, NULL);
125 if (!sym) 126 if (!sym)
126 die("Kernel symbol \'%s\' not found - probe not added.", 127 die("Kernel symbol \'%s\' not found - probe not added.",
127 pp->function); 128 pp->function);
@@ -130,12 +131,23 @@ static void evaluate_probe_point(struct probe_point *pp)
130#ifndef NO_LIBDWARF 131#ifndef NO_LIBDWARF
131static int open_vmlinux(void) 132static int open_vmlinux(void)
132{ 133{
133 if (map__load(session.kmap, session.psession, NULL) < 0) { 134 if (map__load(session.kmaps[MAP__FUNCTION], NULL) < 0) {
134 pr_debug("Failed to load kernel map.\n"); 135 pr_debug("Failed to load kernel map.\n");
135 return -EINVAL; 136 return -EINVAL;
136 } 137 }
137 pr_debug("Try to open %s\n", session.kmap->dso->long_name); 138 pr_debug("Try to open %s\n",
138 return open(session.kmap->dso->long_name, O_RDONLY); 139 session.kmaps[MAP__FUNCTION]->dso->long_name);
140 return open(session.kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
141}
142
143static int opt_show_lines(const struct option *opt __used,
144 const char *str, int unset __used)
145{
146 if (str)
147 parse_line_range_desc(str, &session.line_range);
148 INIT_LIST_HEAD(&session.line_range.line_list);
149 session.show_lines = true;
150 return 0;
139} 151}
140#endif 152#endif
141 153
@@ -144,6 +156,7 @@ static const char * const probe_usage[] = {
144 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]", 156 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
145 "perf probe [<options>] --del '[GROUP:]EVENT' ...", 157 "perf probe [<options>] --del '[GROUP:]EVENT' ...",
146 "perf probe --list", 158 "perf probe --list",
159 "perf probe --line 'LINEDESC'",
147 NULL 160 NULL
148}; 161};
149 162
@@ -182,9 +195,31 @@ static const struct option options[] = {
182 opt_add_probe_event), 195 opt_add_probe_event),
183 OPT_BOOLEAN('f', "force", &session.force_add, "forcibly add events" 196 OPT_BOOLEAN('f', "force", &session.force_add, "forcibly add events"
184 " with existing name"), 197 " with existing name"),
198#ifndef NO_LIBDWARF
199 OPT_CALLBACK('L', "line", NULL,
200 "FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]",
201 "Show source code lines.", opt_show_lines),
202#endif
185 OPT_END() 203 OPT_END()
186}; 204};
187 205
206/* Initialize symbol maps for vmlinux */
207static void init_vmlinux(void)
208{
209 symbol_conf.sort_by_name = true;
210 if (symbol_conf.vmlinux_name == NULL)
211 symbol_conf.try_vmlinux_path = true;
212 else
213 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
214 if (symbol__init() < 0)
215 die("Failed to init symbol map.");
216
217 map_groups__init(&session.kmap_groups);
218 if (map_groups__create_kernel_maps(&session.kmap_groups,
219 session.kmaps) < 0)
220 die("Failed to create kernel maps.");
221}
222
188int cmd_probe(int argc, const char **argv, const char *prefix __used) 223int cmd_probe(int argc, const char **argv, const char *prefix __used)
189{ 224{
190 int i, ret; 225 int i, ret;
@@ -203,7 +238,8 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
203 parse_probe_event_argv(argc, argv); 238 parse_probe_event_argv(argc, argv);
204 } 239 }
205 240
206 if ((!session.nr_probe && !session.dellist && !session.list_events)) 241 if ((!session.nr_probe && !session.dellist && !session.list_events &&
242 !session.show_lines))
207 usage_with_options(probe_usage, options); 243 usage_with_options(probe_usage, options);
208 244
209 if (debugfs_valid_mountpoint(debugfs_path) < 0) 245 if (debugfs_valid_mountpoint(debugfs_path) < 0)
@@ -215,10 +251,34 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
215 " --add/--del.\n"); 251 " --add/--del.\n");
216 usage_with_options(probe_usage, options); 252 usage_with_options(probe_usage, options);
217 } 253 }
254 if (session.show_lines) {
255 pr_warning(" Error: Don't use --list with --line.\n");
256 usage_with_options(probe_usage, options);
257 }
218 show_perf_probe_events(); 258 show_perf_probe_events();
219 return 0; 259 return 0;
220 } 260 }
221 261
262#ifndef NO_LIBDWARF
263 if (session.show_lines) {
264 if (session.nr_probe != 0 || session.dellist) {
265 pr_warning(" Error: Don't use --line with"
266 " --add/--del.\n");
267 usage_with_options(probe_usage, options);
268 }
269 init_vmlinux();
270 fd = open_vmlinux();
271 if (fd < 0)
272 die("Could not open debuginfo file.");
273 ret = find_line_range(fd, &session.line_range);
274 if (ret <= 0)
275 die("Source line is not found.\n");
276 close(fd);
277 show_line_range(&session.line_range);
278 return 0;
279 }
280#endif
281
222 if (session.dellist) { 282 if (session.dellist) {
223 del_trace_kprobe_events(session.dellist); 283 del_trace_kprobe_events(session.dellist);
224 strlist__delete(session.dellist); 284 strlist__delete(session.dellist);
@@ -226,20 +286,8 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used)
226 return 0; 286 return 0;
227 } 287 }
228 288
229 /* Initialize symbol maps for vmlinux */ 289 /* Add probes */
230 symbol_conf.sort_by_name = true; 290 init_vmlinux();
231 if (symbol_conf.vmlinux_name == NULL)
232 symbol_conf.try_vmlinux_path = true;
233 if (symbol__init() < 0)
234 die("Failed to init symbol map.");
235 session.psession = perf_session__new(NULL, O_WRONLY, false);
236 if (session.psession == NULL)
237 die("Failed to init perf_session.");
238 session.kmap = map_groups__find_by_name(&session.psession->kmaps,
239 MAP__FUNCTION,
240 "[kernel.kallsyms]");
241 if (!session.kmap)
242 die("Could not find kernel map.\n");
243 291
244 if (session.need_dwarf) 292 if (session.need_dwarf)
245#ifdef NO_LIBDWARF 293#ifdef NO_LIBDWARF