blob: ac41578a3552bb5dac6a4b33ed8384e5bf511058 [file] [log] [blame]
Masami Hiramatsu50656ee2009-11-30 19:19:58 -05001/*
2 * probe-event.c : perf-probe definition to kprobe_events format converter
3 *
4 * Written by Masami Hiramatsu <mhiramat@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 */
21
22#define _GNU_SOURCE
23#include <sys/utsname.h>
24#include <sys/types.h>
25#include <sys/stat.h>
26#include <fcntl.h>
27#include <errno.h>
28#include <stdio.h>
29#include <unistd.h>
30#include <stdlib.h>
31#include <string.h>
Masami Hiramatsu4de189f2009-11-30 19:20:17 -050032#include <stdarg.h>
33#include <limits.h>
Masami Hiramatsu50656ee2009-11-30 19:19:58 -050034
35#undef _GNU_SOURCE
Masami Hiramatsu31facc52010-03-16 18:05:30 -040036#include "util.h"
Masami Hiramatsu50656ee2009-11-30 19:19:58 -050037#include "event.h"
Masami Hiramatsue1c01d62009-11-30 19:20:05 -050038#include "string.h"
Masami Hiramatsu4de189f2009-11-30 19:20:17 -050039#include "strlist.h"
Masami Hiramatsu50656ee2009-11-30 19:19:58 -050040#include "debug.h"
Masami Hiramatsu72041332010-01-05 17:47:10 -050041#include "cache.h"
Masami Hiramatsu631c9de2010-01-06 09:45:34 -050042#include "color.h"
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -040043#include "symbol.h"
44#include "thread.h"
Masami Hiramatsu50656ee2009-11-30 19:19:58 -050045#include "parse-events.h" /* For debugfs_path */
46#include "probe-event.h"
47
48#define MAX_CMDLEN 256
49#define MAX_PROBE_ARGS 128
50#define PERFPROBE_GROUP "probe"
51
Masami Hiramatsuf4d7da42010-03-16 18:06:05 -040052bool probe_event_dry_run; /* Dry run flag */
53
Masami Hiramatsu50656ee2009-11-30 19:19:58 -050054#define semantic_error(msg ...) die("Semantic error :" msg)
55
Masami Hiramatsu4de189f2009-11-30 19:20:17 -050056/* If there is no space to write, returns -E2BIG. */
57static int e_snprintf(char *str, size_t size, const char *format, ...)
Masami Hiramatsu84988452009-12-07 12:00:53 -050058 __attribute__((format(printf, 3, 4)));
59
60static int e_snprintf(char *str, size_t size, const char *format, ...)
Masami Hiramatsu4de189f2009-11-30 19:20:17 -050061{
62 int ret;
63 va_list ap;
64 va_start(ap, format);
65 ret = vsnprintf(str, size, format, ap);
66 va_end(ap);
67 if (ret >= (int)size)
68 ret = -E2BIG;
69 return ret;
70}
71
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -040072
73static struct map_groups kmap_groups;
74static struct map *kmaps[MAP__NR_TYPES];
75
76/* Initialize symbol maps for vmlinux */
77static void init_vmlinux(void)
78{
79 symbol_conf.sort_by_name = true;
80 if (symbol_conf.vmlinux_name == NULL)
81 symbol_conf.try_vmlinux_path = true;
82 else
83 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
84 if (symbol__init() < 0)
85 die("Failed to init symbol map.");
86
87 map_groups__init(&kmap_groups);
88 if (map_groups__create_kernel_maps(&kmap_groups, kmaps) < 0)
89 die("Failed to create kernel maps.");
90}
91
92#ifndef NO_DWARF_SUPPORT
93static int open_vmlinux(void)
94{
95 if (map__load(kmaps[MAP__FUNCTION], NULL) < 0) {
96 pr_debug("Failed to load kernel map.\n");
97 return -EINVAL;
98 }
99 pr_debug("Try to open %s\n", kmaps[MAP__FUNCTION]->dso->long_name);
100 return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
101}
102#endif
103
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500104void parse_line_range_desc(const char *arg, struct line_range *lr)
105{
106 const char *ptr;
107 char *tmp;
108 /*
109 * <Syntax>
110 * SRC:SLN[+NUM|-ELN]
111 * FUNC[:SLN[+NUM|-ELN]]
112 */
113 ptr = strchr(arg, ':');
114 if (ptr) {
115 lr->start = (unsigned int)strtoul(ptr + 1, &tmp, 0);
116 if (*tmp == '+')
117 lr->end = lr->start + (unsigned int)strtoul(tmp + 1,
118 &tmp, 0);
119 else if (*tmp == '-')
120 lr->end = (unsigned int)strtoul(tmp + 1, &tmp, 0);
121 else
122 lr->end = 0;
123 pr_debug("Line range is %u to %u\n", lr->start, lr->end);
124 if (lr->end && lr->start > lr->end)
125 semantic_error("Start line must be smaller"
126 " than end line.");
127 if (*tmp != '\0')
128 semantic_error("Tailing with invalid character '%d'.",
129 *tmp);
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400130 tmp = xstrndup(arg, (ptr - arg));
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500131 } else
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400132 tmp = xstrdup(arg);
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500133
134 if (strchr(tmp, '.'))
135 lr->file = tmp;
136 else
137 lr->function = tmp;
138}
139
Masami Hiramatsub7702a22009-12-16 17:24:15 -0500140/* Check the name is good for event/group */
141static bool check_event_name(const char *name)
142{
143 if (!isalpha(*name) && *name != '_')
144 return false;
145 while (*++name != '\0') {
146 if (!isalpha(*name) && !isdigit(*name) && *name != '_')
147 return false;
148 }
149 return true;
150}
151
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500152/* Parse probepoint definition. */
153static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
154{
155 char *ptr, *tmp;
156 char c, nc = 0;
157 /*
158 * <Syntax>
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500159 * perf probe [EVENT=]SRC[:LN|;PTN]
160 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500161 *
162 * TODO:Group name support
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500163 */
164
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500165 ptr = strpbrk(arg, ";=@+%");
166 if (ptr && *ptr == '=') { /* Event name */
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500167 *ptr = '\0';
168 tmp = ptr + 1;
169 ptr = strchr(arg, ':');
170 if (ptr) /* Group name is not supported yet. */
171 semantic_error("Group name is not supported yet.");
Masami Hiramatsub7702a22009-12-16 17:24:15 -0500172 if (!check_event_name(arg))
173 semantic_error("%s is bad for event name -it must "
174 "follow C symbol-naming rule.", arg);
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400175 pp->event = xstrdup(arg);
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500176 arg = tmp;
177 }
178
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500179 ptr = strpbrk(arg, ";:+@%");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500180 if (ptr) {
181 nc = *ptr;
182 *ptr++ = '\0';
183 }
184
185 /* Check arg is function or file and copy it */
186 if (strchr(arg, '.')) /* File */
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400187 pp->file = xstrdup(arg);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500188 else /* Function */
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400189 pp->function = xstrdup(arg);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500190
191 /* Parse other options */
192 while (ptr) {
193 arg = ptr;
194 c = nc;
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500195 if (c == ';') { /* Lazy pattern must be the last part */
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400196 pp->lazy_line = xstrdup(arg);
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500197 break;
198 }
199 ptr = strpbrk(arg, ";:+@%");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500200 if (ptr) {
201 nc = *ptr;
202 *ptr++ = '\0';
203 }
204 switch (c) {
205 case ':': /* Line number */
206 pp->line = strtoul(arg, &tmp, 0);
207 if (*tmp != '\0')
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500208 semantic_error("There is non-digit char"
209 " in line number.");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500210 break;
211 case '+': /* Byte offset from a symbol */
212 pp->offset = strtoul(arg, &tmp, 0);
213 if (*tmp != '\0')
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500214 semantic_error("There is non-digit character"
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500215 " in offset.");
216 break;
217 case '@': /* File name */
218 if (pp->file)
219 semantic_error("SRC@SRC is not allowed.");
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400220 pp->file = xstrdup(arg);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500221 break;
222 case '%': /* Probe places */
223 if (strcmp(arg, "return") == 0) {
224 pp->retprobe = 1;
225 } else /* Others not supported yet */
226 semantic_error("%%%s is not supported.", arg);
227 break;
228 default:
229 DIE_IF("Program has a bug.");
230 break;
231 }
232 }
233
234 /* Exclusion check */
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500235 if (pp->lazy_line && pp->line)
236 semantic_error("Lazy pattern can't be used with line number.");
237
238 if (pp->lazy_line && pp->offset)
239 semantic_error("Lazy pattern can't be used with offset.");
240
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500241 if (pp->line && pp->offset)
242 semantic_error("Offset can't be used with line number.");
243
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500244 if (!pp->line && !pp->lazy_line && pp->file && !pp->function)
245 semantic_error("File always requires line number or "
246 "lazy pattern.");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500247
248 if (pp->offset && !pp->function)
249 semantic_error("Offset requires an entry function.");
250
251 if (pp->retprobe && !pp->function)
252 semantic_error("Return probe requires an entry function.");
253
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500254 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe)
255 semantic_error("Offset/Line/Lazy pattern can't be used with "
256 "return probe.");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500257
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500258 pr_debug("symbol:%s file:%s line:%d offset:%d return:%d lazy:%s\n",
259 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
260 pp->lazy_line);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500261}
262
263/* Parse perf-probe event definition */
Masami Hiramatsufac13fd2009-12-15 10:31:14 -0500264void parse_perf_probe_event(const char *str, struct probe_point *pp,
265 bool *need_dwarf)
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500266{
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500267 char **argv;
Masami Hiramatsufac13fd2009-12-15 10:31:14 -0500268 int argc, i;
269
270 *need_dwarf = false;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500271
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500272 argv = argv_split(str, &argc);
273 if (!argv)
274 die("argv_split failed.");
275 if (argc > MAX_PROBE_ARGS + 1)
276 semantic_error("Too many arguments");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500277
278 /* Parse probe point */
279 parse_perf_probe_probepoint(argv[0], pp);
Masami Hiramatsufc6ceea2010-03-12 18:22:24 -0500280 if (pp->file || pp->line || pp->lazy_line)
Masami Hiramatsufac13fd2009-12-15 10:31:14 -0500281 *need_dwarf = true;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500282
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500283 /* Copy arguments and ensure return probe has no C argument */
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500284 pp->nr_args = argc - 1;
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400285 pp->args = xzalloc(sizeof(char *) * pp->nr_args);
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500286 for (i = 0; i < pp->nr_args; i++) {
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400287 pp->args[i] = xstrdup(argv[i + 1]);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500288 if (is_c_varname(pp->args[i])) {
289 if (pp->retprobe)
290 semantic_error("You can't specify local"
291 " variable for kretprobe");
Masami Hiramatsufac13fd2009-12-15 10:31:14 -0500292 *need_dwarf = true;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500293 }
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500294 }
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500295
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500296 argv_free(argv);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500297}
298
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500299/* Parse kprobe_events event into struct probe_point */
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500300void parse_trace_kprobe_event(const char *str, struct probe_point *pp)
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500301{
302 char pr;
303 char *p;
304 int ret, i, argc;
305 char **argv;
306
307 pr_debug("Parsing kprobe_events: %s\n", str);
308 argv = argv_split(str, &argc);
309 if (!argv)
310 die("argv_split failed.");
311 if (argc < 2)
312 semantic_error("Too less arguments.");
313
314 /* Scan event and group name. */
Liming Wang93aaa452009-12-02 16:42:54 +0800315 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500316 &pr, (float *)(void *)&pp->group,
317 (float *)(void *)&pp->event);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500318 if (ret != 3)
319 semantic_error("Failed to parse event name: %s", argv[0]);
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500320 pr_debug("Group:%s Event:%s probe:%c\n", pp->group, pp->event, pr);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500321
322 pp->retprobe = (pr == 'r');
323
324 /* Scan function name and offset */
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500325 ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function,
326 &pp->offset);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500327 if (ret == 1)
328 pp->offset = 0;
329
330 /* kprobe_events doesn't have this information */
331 pp->line = 0;
332 pp->file = NULL;
333
334 pp->nr_args = argc - 2;
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400335 pp->args = xzalloc(sizeof(char *) * pp->nr_args);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500336 for (i = 0; i < pp->nr_args; i++) {
337 p = strchr(argv[i + 2], '=');
338 if (p) /* We don't need which register is assigned. */
339 *p = '\0';
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400340 pp->args[i] = xstrdup(argv[i + 2]);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500341 }
342
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500343 argv_free(argv);
344}
345
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500346/* Synthesize only probe point (not argument) */
347int synthesize_perf_probe_point(struct probe_point *pp)
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500348{
349 char *buf;
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500350 char offs[64] = "", line[64] = "";
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500351 int ret;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500352
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400353 pp->probes[0] = buf = xzalloc(MAX_CMDLEN);
Masami Hiramatsu388c3aa2010-02-18 13:16:52 -0500354 pp->found = 1;
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500355 if (pp->offset) {
356 ret = e_snprintf(offs, 64, "+%d", pp->offset);
357 if (ret <= 0)
358 goto error;
359 }
360 if (pp->line) {
361 ret = e_snprintf(line, 64, ":%d", pp->line);
362 if (ret <= 0)
363 goto error;
364 }
365
366 if (pp->function)
367 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->function,
368 offs, pp->retprobe ? "%return" : "", line);
369 else
Masami Hiramatsu84988452009-12-07 12:00:53 -0500370 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line);
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500371 if (ret <= 0) {
372error:
373 free(pp->probes[0]);
374 pp->probes[0] = NULL;
Masami Hiramatsu388c3aa2010-02-18 13:16:52 -0500375 pp->found = 0;
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500376 }
377 return ret;
378}
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500379
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500380int synthesize_perf_probe_event(struct probe_point *pp)
381{
382 char *buf;
383 int i, len, ret;
384
385 len = synthesize_perf_probe_point(pp);
386 if (len < 0)
387 return 0;
388
389 buf = pp->probes[0];
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500390 for (i = 0; i < pp->nr_args; i++) {
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500391 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
392 pp->args[i]);
393 if (ret <= 0)
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500394 goto error;
395 len += ret;
396 }
397 pp->found = 1;
398
399 return pp->found;
400error:
401 free(pp->probes[0]);
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500402 pp->probes[0] = NULL;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500403
404 return ret;
405}
406
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500407int synthesize_trace_kprobe_event(struct probe_point *pp)
408{
409 char *buf;
410 int i, len, ret;
411
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400412 pp->probes[0] = buf = xzalloc(MAX_CMDLEN);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500413 ret = e_snprintf(buf, MAX_CMDLEN, "%s+%d", pp->function, pp->offset);
414 if (ret <= 0)
415 goto error;
416 len = ret;
417
418 for (i = 0; i < pp->nr_args; i++) {
419 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
420 pp->args[i]);
421 if (ret <= 0)
422 goto error;
423 len += ret;
424 }
425 pp->found = 1;
426
427 return pp->found;
428error:
429 free(pp->probes[0]);
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500430 pp->probes[0] = NULL;
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500431
432 return ret;
433}
434
Masami Hiramatsuf4d7da42010-03-16 18:06:05 -0400435static int open_kprobe_events(bool readwrite)
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500436{
437 char buf[PATH_MAX];
438 int ret;
439
440 ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path);
441 if (ret < 0)
442 die("Failed to make kprobe_events path.");
443
Masami Hiramatsuf4d7da42010-03-16 18:06:05 -0400444 if (readwrite && !probe_event_dry_run)
445 ret = open(buf, O_RDWR, O_APPEND);
446 else
447 ret = open(buf, O_RDONLY, 0);
448
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500449 if (ret < 0) {
450 if (errno == ENOENT)
451 die("kprobe_events file does not exist -"
Liming Wang63bbd5e2009-12-29 16:37:09 +0800452 " please rebuild with CONFIG_KPROBE_EVENT.");
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500453 else
454 die("Could not open kprobe_events file: %s",
455 strerror(errno));
456 }
457 return ret;
458}
459
460/* Get raw string list of current kprobe_events */
461static struct strlist *get_trace_kprobe_event_rawlist(int fd)
462{
463 int ret, idx;
464 FILE *fp;
465 char buf[MAX_CMDLEN];
466 char *p;
467 struct strlist *sl;
468
469 sl = strlist__new(true, NULL);
470
471 fp = fdopen(dup(fd), "r");
472 while (!feof(fp)) {
473 p = fgets(buf, MAX_CMDLEN, fp);
474 if (!p)
475 break;
476
477 idx = strlen(p) - 1;
478 if (p[idx] == '\n')
479 p[idx] = '\0';
480 ret = strlist__add(sl, buf);
481 if (ret < 0)
482 die("strlist__add failed: %s", strerror(-ret));
483 }
484 fclose(fp);
485
486 return sl;
487}
488
489/* Free and zero clear probe_point */
490static void clear_probe_point(struct probe_point *pp)
491{
492 int i;
493
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500494 if (pp->event)
495 free(pp->event);
496 if (pp->group)
497 free(pp->group);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500498 if (pp->function)
499 free(pp->function);
500 if (pp->file)
501 free(pp->file);
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500502 if (pp->lazy_line)
503 free(pp->lazy_line);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500504 for (i = 0; i < pp->nr_args; i++)
505 free(pp->args[i]);
506 if (pp->args)
507 free(pp->args);
508 for (i = 0; i < pp->found; i++)
509 free(pp->probes[i]);
Julia Lawall5660ce32009-12-09 20:26:18 +0100510 memset(pp, 0, sizeof(*pp));
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500511}
512
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500513/* Show an event */
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500514static void show_perf_probe_event(const char *event, const char *place,
515 struct probe_point *pp)
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500516{
Masami Hiramatsu7e990a52009-12-15 10:31:21 -0500517 int i, ret;
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500518 char buf[128];
519
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500520 ret = e_snprintf(buf, 128, "%s:%s", pp->group, event);
Masami Hiramatsu7e990a52009-12-15 10:31:21 -0500521 if (ret < 0)
522 die("Failed to copy event: %s", strerror(-ret));
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500523 printf(" %-40s (on %s", buf, place);
524
525 if (pp->nr_args > 0) {
526 printf(" with");
527 for (i = 0; i < pp->nr_args; i++)
528 printf(" %s", pp->args[i]);
529 }
530 printf(")\n");
531}
532
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500533/* List up current perf-probe events */
534void show_perf_probe_events(void)
535{
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500536 int fd;
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500537 struct probe_point pp;
538 struct strlist *rawlist;
539 struct str_node *ent;
540
Masami Hiramatsu72041332010-01-05 17:47:10 -0500541 setup_pager();
Masami Hiramatsu388c3aa2010-02-18 13:16:52 -0500542 memset(&pp, 0, sizeof(pp));
Masami Hiramatsu72041332010-01-05 17:47:10 -0500543
Masami Hiramatsuf4d7da42010-03-16 18:06:05 -0400544 fd = open_kprobe_events(false);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500545 rawlist = get_trace_kprobe_event_rawlist(fd);
546 close(fd);
547
Masami Hiramatsuadf365f2009-12-15 10:32:03 -0500548 strlist__for_each(ent, rawlist) {
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500549 parse_trace_kprobe_event(ent->s, &pp);
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500550 /* Synthesize only event probe point */
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500551 synthesize_perf_probe_point(&pp);
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500552 /* Show an event */
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500553 show_perf_probe_event(pp.event, pp.probes[0], &pp);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500554 clear_probe_point(&pp);
555 }
556
557 strlist__delete(rawlist);
558}
559
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500560/* Get current perf-probe event names */
Masami Hiramatsufa282442009-12-08 17:03:23 -0500561static struct strlist *get_perf_event_names(int fd, bool include_group)
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500562{
Masami Hiramatsufa282442009-12-08 17:03:23 -0500563 char buf[128];
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500564 struct strlist *sl, *rawlist;
565 struct str_node *ent;
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500566 struct probe_point pp;
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500567
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500568 memset(&pp, 0, sizeof(pp));
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500569 rawlist = get_trace_kprobe_event_rawlist(fd);
570
Masami Hiramatsue1d20172009-12-07 12:00:46 -0500571 sl = strlist__new(true, NULL);
Masami Hiramatsuadf365f2009-12-15 10:32:03 -0500572 strlist__for_each(ent, rawlist) {
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500573 parse_trace_kprobe_event(ent->s, &pp);
Masami Hiramatsufa282442009-12-08 17:03:23 -0500574 if (include_group) {
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500575 if (e_snprintf(buf, 128, "%s:%s", pp.group,
576 pp.event) < 0)
Masami Hiramatsufa282442009-12-08 17:03:23 -0500577 die("Failed to copy group:event name.");
578 strlist__add(sl, buf);
579 } else
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500580 strlist__add(sl, pp.event);
581 clear_probe_point(&pp);
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500582 }
583
584 strlist__delete(rawlist);
585
586 return sl;
587}
588
Masami Hiramatsua9b495b2009-12-08 17:02:47 -0500589static void write_trace_kprobe_event(int fd, const char *buf)
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500590{
591 int ret;
592
Masami Hiramatsufa282442009-12-08 17:03:23 -0500593 pr_debug("Writing event: %s\n", buf);
Masami Hiramatsuf4d7da42010-03-16 18:06:05 -0400594 if (!probe_event_dry_run) {
595 ret = write(fd, buf, strlen(buf));
596 if (ret <= 0)
597 die("Failed to write event: %s", strerror(errno));
598 }
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500599}
600
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500601static void get_new_event_name(char *buf, size_t len, const char *base,
Masami Hiramatsud761b082009-12-15 10:32:25 -0500602 struct strlist *namelist, bool allow_suffix)
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500603{
604 int i, ret;
Masami Hiramatsu17f88fc2009-12-08 17:03:02 -0500605
606 /* Try no suffix */
607 ret = e_snprintf(buf, len, "%s", base);
608 if (ret < 0)
609 die("snprintf() failed: %s", strerror(-ret));
610 if (!strlist__has_entry(namelist, buf))
611 return;
612
Masami Hiramatsud761b082009-12-15 10:32:25 -0500613 if (!allow_suffix) {
614 pr_warning("Error: event \"%s\" already exists. "
615 "(Use -f to force duplicates.)\n", base);
616 die("Can't add new event.");
617 }
618
Masami Hiramatsu17f88fc2009-12-08 17:03:02 -0500619 /* Try to add suffix */
620 for (i = 1; i < MAX_EVENT_INDEX; i++) {
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500621 ret = e_snprintf(buf, len, "%s_%d", base, i);
622 if (ret < 0)
623 die("snprintf() failed: %s", strerror(-ret));
624 if (!strlist__has_entry(namelist, buf))
625 break;
626 }
627 if (i == MAX_EVENT_INDEX)
628 die("Too many events are on the same function.");
629}
630
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -0400631static void __add_trace_kprobe_events(struct probe_point *probes,
632 int nr_probes, bool force_add)
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500633{
634 int i, j, fd;
635 struct probe_point *pp;
636 char buf[MAX_CMDLEN];
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500637 char event[64];
638 struct strlist *namelist;
Masami Hiramatsud761b082009-12-15 10:32:25 -0500639 bool allow_suffix;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500640
Masami Hiramatsuf4d7da42010-03-16 18:06:05 -0400641 fd = open_kprobe_events(true);
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500642 /* Get current event names */
Masami Hiramatsufa282442009-12-08 17:03:23 -0500643 namelist = get_perf_event_names(fd, false);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500644
645 for (j = 0; j < nr_probes; j++) {
646 pp = probes + j;
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500647 if (!pp->event)
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400648 pp->event = xstrdup(pp->function);
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500649 if (!pp->group)
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400650 pp->group = xstrdup(PERFPROBE_GROUP);
Masami Hiramatsud761b082009-12-15 10:32:25 -0500651 /* If force_add is true, suffix search is allowed */
652 allow_suffix = force_add;
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500653 for (i = 0; i < pp->found; i++) {
654 /* Get an unused new event name */
Masami Hiramatsud761b082009-12-15 10:32:25 -0500655 get_new_event_name(event, 64, pp->event, namelist,
656 allow_suffix);
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500657 snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n",
658 pp->retprobe ? 'r' : 'p',
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500659 pp->group, event,
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500660 pp->probes[i]);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500661 write_trace_kprobe_event(fd, buf);
Masami Hiramatsua9b495b2009-12-08 17:02:47 -0500662 printf("Added new event:\n");
663 /* Get the first parameter (probe-point) */
664 sscanf(pp->probes[i], "%s", buf);
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500665 show_perf_probe_event(event, buf, pp);
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500666 /* Add added event name to namelist */
667 strlist__add(namelist, event);
Masami Hiramatsud761b082009-12-15 10:32:25 -0500668 /*
669 * Probes after the first probe which comes from same
670 * user input are always allowed to add suffix, because
671 * there might be several addresses corresponding to
672 * one code line.
673 */
674 allow_suffix = true;
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500675 }
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500676 }
Masami Hiramatsua9b495b2009-12-08 17:02:47 -0500677 /* Show how to use the event. */
678 printf("\nYou can now use it on all perf tools, such as:\n\n");
679 printf("\tperf record -e %s:%s -a sleep 1\n\n", PERFPROBE_GROUP, event);
680
Masami Hiramatsue1d20172009-12-07 12:00:46 -0500681 strlist__delete(namelist);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500682 close(fd);
683}
Masami Hiramatsufa282442009-12-08 17:03:23 -0500684
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -0400685/* Currently just checking function name from symbol map */
686static void evaluate_probe_point(struct probe_point *pp)
687{
688 struct symbol *sym;
689 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
690 pp->function, NULL);
691 if (!sym)
692 die("Kernel symbol \'%s\' not found - probe not added.",
693 pp->function);
694}
695
696void add_trace_kprobe_events(struct probe_point *probes, int nr_probes,
697 bool force_add, bool need_dwarf)
698{
699 int i, ret;
700 struct probe_point *pp;
701#ifndef NO_DWARF_SUPPORT
702 int fd;
703#endif
704 /* Add probes */
705 init_vmlinux();
706
707 if (need_dwarf)
708#ifdef NO_DWARF_SUPPORT
709 die("Debuginfo-analysis is not supported");
710#else /* !NO_DWARF_SUPPORT */
711 pr_debug("Some probes require debuginfo.\n");
712
713 fd = open_vmlinux();
714 if (fd < 0) {
715 if (need_dwarf)
716 die("Could not open debuginfo file.");
717
718 pr_debug("Could not open vmlinux/module file."
719 " Try to use symbols.\n");
720 goto end_dwarf;
721 }
722
723 /* Searching probe points */
724 for (i = 0; i < nr_probes; i++) {
725 pp = &probes[i];
726 if (pp->found)
727 continue;
728
729 lseek(fd, SEEK_SET, 0);
730 ret = find_probe_point(fd, pp);
731 if (ret > 0)
732 continue;
733 if (ret == 0) { /* No error but failed to find probe point. */
734 synthesize_perf_probe_point(pp);
735 die("Probe point '%s' not found. - probe not added.",
736 pp->probes[0]);
737 }
738 /* Error path */
739 if (need_dwarf) {
740 if (ret == -ENOENT)
741 pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO=y.\n");
742 die("Could not analyze debuginfo.");
743 }
744 pr_debug("An error occurred in debuginfo analysis."
745 " Try to use symbols.\n");
746 break;
747 }
748 close(fd);
749
750end_dwarf:
751#endif /* !NO_DWARF_SUPPORT */
752
753 /* Synthesize probes without dwarf */
754 for (i = 0; i < nr_probes; i++) {
755 pp = &probes[i];
756 if (pp->found) /* This probe is already found. */
757 continue;
758
759 evaluate_probe_point(pp);
760 ret = synthesize_trace_kprobe_event(pp);
761 if (ret == -E2BIG)
762 die("probe point definition becomes too long.");
763 else if (ret < 0)
764 die("Failed to synthesize a probe point.");
765 }
766
767 /* Settng up probe points */
768 __add_trace_kprobe_events(probes, nr_probes, force_add);
769}
770
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500771static void __del_trace_kprobe_event(int fd, struct str_node *ent)
772{
773 char *p;
774 char buf[128];
775
776 /* Convert from perf-probe event to trace-kprobe event */
777 if (e_snprintf(buf, 128, "-:%s", ent->s) < 0)
778 die("Failed to copy event.");
779 p = strchr(buf + 2, ':');
780 if (!p)
781 die("Internal error: %s should have ':' but not.", ent->s);
782 *p = '/';
783
784 write_trace_kprobe_event(fd, buf);
785 printf("Remove event: %s\n", ent->s);
786}
787
Masami Hiramatsufa282442009-12-08 17:03:23 -0500788static void del_trace_kprobe_event(int fd, const char *group,
789 const char *event, struct strlist *namelist)
790{
791 char buf[128];
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500792 struct str_node *ent, *n;
793 int found = 0;
Masami Hiramatsufa282442009-12-08 17:03:23 -0500794
795 if (e_snprintf(buf, 128, "%s:%s", group, event) < 0)
796 die("Failed to copy event.");
Masami Hiramatsufa282442009-12-08 17:03:23 -0500797
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500798 if (strpbrk(buf, "*?")) { /* Glob-exp */
799 strlist__for_each_safe(ent, n, namelist)
800 if (strglobmatch(ent->s, buf)) {
801 found++;
802 __del_trace_kprobe_event(fd, ent);
803 strlist__remove(namelist, ent);
804 }
805 } else {
806 ent = strlist__find(namelist, buf);
807 if (ent) {
808 found++;
809 __del_trace_kprobe_event(fd, ent);
810 strlist__remove(namelist, ent);
811 }
812 }
813 if (found == 0)
814 pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf);
Masami Hiramatsufa282442009-12-08 17:03:23 -0500815}
816
817void del_trace_kprobe_events(struct strlist *dellist)
818{
819 int fd;
Masami Hiramatsufa282442009-12-08 17:03:23 -0500820 const char *group, *event;
821 char *p, *str;
822 struct str_node *ent;
823 struct strlist *namelist;
824
Masami Hiramatsuf4d7da42010-03-16 18:06:05 -0400825 fd = open_kprobe_events(true);
Masami Hiramatsufa282442009-12-08 17:03:23 -0500826 /* Get current event names */
827 namelist = get_perf_event_names(fd, true);
828
Masami Hiramatsuadf365f2009-12-15 10:32:03 -0500829 strlist__for_each(ent, dellist) {
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400830 str = xstrdup(ent->s);
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500831 pr_debug("Parsing: %s\n", str);
Masami Hiramatsufa282442009-12-08 17:03:23 -0500832 p = strchr(str, ':');
833 if (p) {
834 group = str;
835 *p = '\0';
836 event = p + 1;
837 } else {
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500838 group = "*";
Masami Hiramatsufa282442009-12-08 17:03:23 -0500839 event = str;
840 }
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500841 pr_debug("Group: %s, Event: %s\n", group, event);
Masami Hiramatsufa282442009-12-08 17:03:23 -0500842 del_trace_kprobe_event(fd, group, event, namelist);
843 free(str);
844 }
845 strlist__delete(namelist);
846 close(fd);
847}
848
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500849#define LINEBUF_SIZE 256
Masami Hiramatsu5c8d1cb2010-02-25 08:36:04 -0500850#define NR_ADDITIONAL_LINES 2
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500851
852static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
853{
854 char buf[LINEBUF_SIZE];
855 const char *color = PERF_COLOR_BLUE;
856
857 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
858 goto error;
859 if (!skip) {
860 if (show_num)
861 fprintf(stdout, "%7u %s", l, buf);
862 else
863 color_fprintf(stdout, color, " %s", buf);
864 }
865
866 while (strlen(buf) == LINEBUF_SIZE - 1 &&
867 buf[LINEBUF_SIZE - 2] != '\n') {
868 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
869 goto error;
870 if (!skip) {
871 if (show_num)
872 fprintf(stdout, "%s", buf);
873 else
874 color_fprintf(stdout, color, "%s", buf);
875 }
876 }
877 return;
878error:
879 if (feof(fp))
880 die("Source file is shorter than expected.");
881 else
882 die("File read error: %s", strerror(errno));
883}
884
885void show_line_range(struct line_range *lr)
886{
887 unsigned int l = 1;
888 struct line_node *ln;
889 FILE *fp;
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -0400890 int fd, ret;
891
892 /* Search a line range */
893 init_vmlinux();
894 fd = open_vmlinux();
895 if (fd < 0)
896 die("Could not open debuginfo file.");
897 ret = find_line_range(fd, lr);
898 if (ret <= 0)
899 die("Source line is not found.\n");
900 close(fd);
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500901
902 setup_pager();
903
904 if (lr->function)
905 fprintf(stdout, "<%s:%d>\n", lr->function,
906 lr->start - lr->offset);
907 else
908 fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
909
910 fp = fopen(lr->path, "r");
911 if (fp == NULL)
912 die("Failed to open %s: %s", lr->path, strerror(errno));
913 /* Skip to starting line number */
914 while (l < lr->start)
915 show_one_line(fp, l++, true, false);
916
917 list_for_each_entry(ln, &lr->line_list, list) {
918 while (ln->line > l)
919 show_one_line(fp, (l++) - lr->offset, false, false);
920 show_one_line(fp, (l++) - lr->offset, false, true);
921 }
Masami Hiramatsu5c8d1cb2010-02-25 08:36:04 -0500922
923 if (lr->end == INT_MAX)
924 lr->end = l + NR_ADDITIONAL_LINES;
925 while (l < lr->end && !feof(fp))
926 show_one_line(fp, (l++) - lr->offset, false, false);
927
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500928 fclose(fp);
929}
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -0400930
931