builtin-probe.c (de1764892a61a3ed212973cc028c80dd083179dd) builtin-probe.c (631c9def804b2c92b5cca04fb9ff7b5df9e35094)
1/*
2 * builtin-probe.c
3 *
4 * Builtin probe command: Set up probe events by C expression
5 *
6 * Written by Masami Hiramatsu <mhiramat@redhat.com>
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 41 unchanged lines hidden (view full) ---

50#define MAX_PATH_LEN 256
51#define MAX_PROBES 128
52
53/* Session management structure */
54static struct {
55 bool need_dwarf;
56 bool list_events;
57 bool force_add;
1/*
2 * builtin-probe.c
3 *
4 * Builtin probe command: Set up probe events by C expression
5 *
6 * Written by Masami Hiramatsu <mhiramat@redhat.com>
7 *
8 * This program is free software; you can redistribute it and/or modify

--- 41 unchanged lines hidden (view full) ---

50#define MAX_PATH_LEN 256
51#define MAX_PROBES 128
52
53/* Session management structure */
54static struct {
55 bool need_dwarf;
56 bool list_events;
57 bool force_add;
58 bool show_lines;
58 int nr_probe;
59 struct probe_point probes[MAX_PROBES];
60 struct strlist *dellist;
61 struct perf_session *psession;
62 struct map *kmap;
59 int nr_probe;
60 struct probe_point probes[MAX_PROBES];
61 struct strlist *dellist;
62 struct perf_session *psession;
63 struct map *kmap;
64 struct line_range line_range;
63} session;
64
65
66/* Parse an event definition. Note that any error must die. */
67static void parse_probe_event(const char *str)
68{
69 struct probe_point *pp = &session.probes[session.nr_probe];
70

--- 40 unchanged lines hidden (view full) ---

111 if (str) {
112 if (!session.dellist)
113 session.dellist = strlist__new(true, NULL);
114 strlist__add(session.dellist, str);
115 }
116 return 0;
117}
118
65} session;
66
67
68/* Parse an event definition. Note that any error must die. */
69static void parse_probe_event(const char *str)
70{
71 struct probe_point *pp = &session.probes[session.nr_probe];
72

--- 40 unchanged lines hidden (view full) ---

113 if (str) {
114 if (!session.dellist)
115 session.dellist = strlist__new(true, NULL);
116 strlist__add(session.dellist, str);
117 }
118 return 0;
119}
120
121static int opt_show_lines(const struct option *opt __used,
122 const char *str, int unset __used)
123{
124 if (str)
125 parse_line_range_desc(str, &session.line_range);
126 INIT_LIST_HEAD(&session.line_range.line_list);
127 session.show_lines = true;
128 return 0;
129}
119/* Currently just checking function name from symbol map */
120static void evaluate_probe_point(struct probe_point *pp)
121{
122 struct symbol *sym;
123 sym = map__find_symbol_by_name(session.kmap, pp->function,
124 session.psession, NULL);
125 if (!sym)
126 die("Kernel symbol \'%s\' not found - probe not added.",

--- 12 unchanged lines hidden (view full) ---

139}
140#endif
141
142static const char * const probe_usage[] = {
143 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
144 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
145 "perf probe [<options>] --del '[GROUP:]EVENT' ...",
146 "perf probe --list",
130/* Currently just checking function name from symbol map */
131static void evaluate_probe_point(struct probe_point *pp)
132{
133 struct symbol *sym;
134 sym = map__find_symbol_by_name(session.kmap, pp->function,
135 session.psession, NULL);
136 if (!sym)
137 die("Kernel symbol \'%s\' not found - probe not added.",

--- 12 unchanged lines hidden (view full) ---

150}
151#endif
152
153static const char * const probe_usage[] = {
154 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
155 "perf probe [<options>] --add 'PROBEDEF' [--add 'PROBEDEF' ...]",
156 "perf probe [<options>] --del '[GROUP:]EVENT' ...",
157 "perf probe --list",
158 "perf probe --line 'LINEDESC'",
147 NULL
148};
149
150static const struct option options[] = {
151 OPT_BOOLEAN('v', "verbose", &verbose,
152 "be more verbose (show parsed arguments, etc)"),
153#ifndef NO_LIBDWARF
154 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,

--- 22 unchanged lines hidden (view full) ---

177 "\t\tRLN:\tRelative line number from function entry.\n"
178 "\t\tALN:\tAbsolute line number in file.\n"
179 "\t\tARG:\tProbe argument (local variable name or\n"
180#endif
181 "\t\t\tkprobe-tracer argument format.)\n",
182 opt_add_probe_event),
183 OPT_BOOLEAN('f', "force", &session.force_add, "forcibly add events"
184 " with existing name"),
159 NULL
160};
161
162static const struct option options[] = {
163 OPT_BOOLEAN('v', "verbose", &verbose,
164 "be more verbose (show parsed arguments, etc)"),
165#ifndef NO_LIBDWARF
166 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,

--- 22 unchanged lines hidden (view full) ---

189 "\t\tRLN:\tRelative line number from function entry.\n"
190 "\t\tALN:\tAbsolute line number in file.\n"
191 "\t\tARG:\tProbe argument (local variable name or\n"
192#endif
193 "\t\t\tkprobe-tracer argument format.)\n",
194 opt_add_probe_event),
195 OPT_BOOLEAN('f', "force", &session.force_add, "forcibly add events"
196 " with existing name"),
197#ifndef NO_LIBDWARF
198 OPT_CALLBACK('L', "line", NULL,
199 "FUNC[:RLN[+NUM|:RLN2]]|SRC:ALN[+NUM|:ALN2]",
200 "Show source code lines.", opt_show_lines),
201#endif
185 OPT_END()
186};
187
202 OPT_END()
203};
204
205/* Initialize symbol maps for vmlinux */
206static void init_vmlinux(void)
207{
208 symbol_conf.sort_by_name = true;
209 if (symbol_conf.vmlinux_name == NULL)
210 symbol_conf.try_vmlinux_path = true;
211 else
212 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
213 if (symbol__init() < 0)
214 die("Failed to init symbol map.");
215 session.psession = perf_session__new(NULL, O_WRONLY, false);
216 if (session.psession == NULL)
217 die("Failed to init perf_session.");
218 session.kmap = session.psession->vmlinux_maps[MAP__FUNCTION];
219 if (!session.kmap)
220 die("Could not find kernel map.\n");
221}
222
188int cmd_probe(int argc, const char **argv, const char *prefix __used)
189{
190 int i, ret;
191#ifndef NO_LIBDWARF
192 int fd;
193#endif
194 struct probe_point *pp;
195
196 argc = parse_options(argc, argv, options, probe_usage,
197 PARSE_OPT_STOP_AT_NON_OPTION);
198 if (argc > 0) {
199 if (strcmp(argv[0], "-") == 0) {
200 pr_warning(" Error: '-' is not supported.\n");
201 usage_with_options(probe_usage, options);
202 }
203 parse_probe_event_argv(argc, argv);
204 }
205
223int cmd_probe(int argc, const char **argv, const char *prefix __used)
224{
225 int i, ret;
226#ifndef NO_LIBDWARF
227 int fd;
228#endif
229 struct probe_point *pp;
230
231 argc = parse_options(argc, argv, options, probe_usage,
232 PARSE_OPT_STOP_AT_NON_OPTION);
233 if (argc > 0) {
234 if (strcmp(argv[0], "-") == 0) {
235 pr_warning(" Error: '-' is not supported.\n");
236 usage_with_options(probe_usage, options);
237 }
238 parse_probe_event_argv(argc, argv);
239 }
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);
208
209 if (debugfs_valid_mountpoint(debugfs_path) < 0)
210 die("Failed to find debugfs path.");
211
212 if (session.list_events) {
213 if (session.nr_probe != 0 || session.dellist) {
214 pr_warning(" Error: Don't use --list with"
215 " --add/--del.\n");
216 usage_with_options(probe_usage, options);
217 }
243 usage_with_options(probe_usage, options);
244
245 if (debugfs_valid_mountpoint(debugfs_path) < 0)
246 die("Failed to find debugfs path.");
247
248 if (session.list_events) {
249 if (session.nr_probe != 0 || session.dellist) {
250 pr_warning(" Error: Don't use --list with"
251 " --add/--del.\n");
252 usage_with_options(probe_usage, options);
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();
219 return 0;
220 }
221
258 show_perf_probe_events();
259 return 0;
260 }
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) {
223 del_trace_kprobe_events(session.dellist);
224 strlist__delete(session.dellist);
225 if (session.nr_probe == 0)
226 return 0;
227 }
228
282 if (session.dellist) {
283 del_trace_kprobe_events(session.dellist);
284 strlist__delete(session.dellist);
285 if (session.nr_probe == 0)
286 return 0;
287 }
288
229 /* Initialize symbol maps for vmlinux */
230 symbol_conf.sort_by_name = true;
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 = session.psession->vmlinux_maps[MAP__FUNCTION];
239 if (!session.kmap)
240 die("Could not find kernel map.\n");
289 /* Add probes */
290 init_vmlinux();
241
242 if (session.need_dwarf)
243#ifdef NO_LIBDWARF
244 die("Debuginfo-analysis is not supported");
245#else /* !NO_LIBDWARF */
246 pr_debug("Some probes require debuginfo.\n");
247
248 fd = open_vmlinux();

--- 59 unchanged lines hidden ---
291
292 if (session.need_dwarf)
293#ifdef NO_LIBDWARF
294 die("Debuginfo-analysis is not supported");
295#else /* !NO_LIBDWARF */
296 pr_debug("Some probes require debuginfo.\n");
297
298 fd = open_vmlinux();

--- 59 unchanged lines hidden ---