blob: 1e60a659578b8a4125ac767da5803a7ce289fb69 [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
52#define semantic_error(msg ...) die("Semantic error :" msg)
53
Masami Hiramatsu4de189f2009-11-30 19:20:17 -050054/* If there is no space to write, returns -E2BIG. */
55static int e_snprintf(char *str, size_t size, const char *format, ...)
Masami Hiramatsu84988452009-12-07 12:00:53 -050056 __attribute__((format(printf, 3, 4)));
57
58static int e_snprintf(char *str, size_t size, const char *format, ...)
Masami Hiramatsu4de189f2009-11-30 19:20:17 -050059{
60 int ret;
61 va_list ap;
62 va_start(ap, format);
63 ret = vsnprintf(str, size, format, ap);
64 va_end(ap);
65 if (ret >= (int)size)
66 ret = -E2BIG;
67 return ret;
68}
69
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -040070
71static struct map_groups kmap_groups;
72static struct map *kmaps[MAP__NR_TYPES];
73
74/* Initialize symbol maps for vmlinux */
75static void init_vmlinux(void)
76{
77 symbol_conf.sort_by_name = true;
78 if (symbol_conf.vmlinux_name == NULL)
79 symbol_conf.try_vmlinux_path = true;
80 else
81 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
82 if (symbol__init() < 0)
83 die("Failed to init symbol map.");
84
85 map_groups__init(&kmap_groups);
86 if (map_groups__create_kernel_maps(&kmap_groups, kmaps) < 0)
87 die("Failed to create kernel maps.");
88}
89
90#ifndef NO_DWARF_SUPPORT
91static int open_vmlinux(void)
92{
93 if (map__load(kmaps[MAP__FUNCTION], NULL) < 0) {
94 pr_debug("Failed to load kernel map.\n");
95 return -EINVAL;
96 }
97 pr_debug("Try to open %s\n", kmaps[MAP__FUNCTION]->dso->long_name);
98 return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
99}
100#endif
101
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500102void parse_line_range_desc(const char *arg, struct line_range *lr)
103{
104 const char *ptr;
105 char *tmp;
106 /*
107 * <Syntax>
108 * SRC:SLN[+NUM|-ELN]
109 * FUNC[:SLN[+NUM|-ELN]]
110 */
111 ptr = strchr(arg, ':');
112 if (ptr) {
113 lr->start = (unsigned int)strtoul(ptr + 1, &tmp, 0);
114 if (*tmp == '+')
115 lr->end = lr->start + (unsigned int)strtoul(tmp + 1,
116 &tmp, 0);
117 else if (*tmp == '-')
118 lr->end = (unsigned int)strtoul(tmp + 1, &tmp, 0);
119 else
120 lr->end = 0;
121 pr_debug("Line range is %u to %u\n", lr->start, lr->end);
122 if (lr->end && lr->start > lr->end)
123 semantic_error("Start line must be smaller"
124 " than end line.");
125 if (*tmp != '\0')
126 semantic_error("Tailing with invalid character '%d'.",
127 *tmp);
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400128 tmp = xstrndup(arg, (ptr - arg));
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500129 } else
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400130 tmp = xstrdup(arg);
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500131
132 if (strchr(tmp, '.'))
133 lr->file = tmp;
134 else
135 lr->function = tmp;
136}
137
Masami Hiramatsub7702a22009-12-16 17:24:15 -0500138/* Check the name is good for event/group */
139static bool check_event_name(const char *name)
140{
141 if (!isalpha(*name) && *name != '_')
142 return false;
143 while (*++name != '\0') {
144 if (!isalpha(*name) && !isdigit(*name) && *name != '_')
145 return false;
146 }
147 return true;
148}
149
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500150/* Parse probepoint definition. */
151static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
152{
153 char *ptr, *tmp;
154 char c, nc = 0;
155 /*
156 * <Syntax>
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500157 * perf probe [EVENT=]SRC[:LN|;PTN]
158 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500159 *
160 * TODO:Group name support
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500161 */
162
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500163 ptr = strpbrk(arg, ";=@+%");
164 if (ptr && *ptr == '=') { /* Event name */
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500165 *ptr = '\0';
166 tmp = ptr + 1;
167 ptr = strchr(arg, ':');
168 if (ptr) /* Group name is not supported yet. */
169 semantic_error("Group name is not supported yet.");
Masami Hiramatsub7702a22009-12-16 17:24:15 -0500170 if (!check_event_name(arg))
171 semantic_error("%s is bad for event name -it must "
172 "follow C symbol-naming rule.", arg);
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400173 pp->event = xstrdup(arg);
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500174 arg = tmp;
175 }
176
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500177 ptr = strpbrk(arg, ";:+@%");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500178 if (ptr) {
179 nc = *ptr;
180 *ptr++ = '\0';
181 }
182
183 /* Check arg is function or file and copy it */
184 if (strchr(arg, '.')) /* File */
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400185 pp->file = xstrdup(arg);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500186 else /* Function */
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400187 pp->function = xstrdup(arg);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500188
189 /* Parse other options */
190 while (ptr) {
191 arg = ptr;
192 c = nc;
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500193 if (c == ';') { /* Lazy pattern must be the last part */
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400194 pp->lazy_line = xstrdup(arg);
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500195 break;
196 }
197 ptr = strpbrk(arg, ";:+@%");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500198 if (ptr) {
199 nc = *ptr;
200 *ptr++ = '\0';
201 }
202 switch (c) {
203 case ':': /* Line number */
204 pp->line = strtoul(arg, &tmp, 0);
205 if (*tmp != '\0')
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500206 semantic_error("There is non-digit char"
207 " in line number.");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500208 break;
209 case '+': /* Byte offset from a symbol */
210 pp->offset = strtoul(arg, &tmp, 0);
211 if (*tmp != '\0')
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500212 semantic_error("There is non-digit character"
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500213 " in offset.");
214 break;
215 case '@': /* File name */
216 if (pp->file)
217 semantic_error("SRC@SRC is not allowed.");
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400218 pp->file = xstrdup(arg);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500219 break;
220 case '%': /* Probe places */
221 if (strcmp(arg, "return") == 0) {
222 pp->retprobe = 1;
223 } else /* Others not supported yet */
224 semantic_error("%%%s is not supported.", arg);
225 break;
226 default:
227 DIE_IF("Program has a bug.");
228 break;
229 }
230 }
231
232 /* Exclusion check */
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500233 if (pp->lazy_line && pp->line)
234 semantic_error("Lazy pattern can't be used with line number.");
235
236 if (pp->lazy_line && pp->offset)
237 semantic_error("Lazy pattern can't be used with offset.");
238
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500239 if (pp->line && pp->offset)
240 semantic_error("Offset can't be used with line number.");
241
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500242 if (!pp->line && !pp->lazy_line && pp->file && !pp->function)
243 semantic_error("File always requires line number or "
244 "lazy pattern.");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500245
246 if (pp->offset && !pp->function)
247 semantic_error("Offset requires an entry function.");
248
249 if (pp->retprobe && !pp->function)
250 semantic_error("Return probe requires an entry function.");
251
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500252 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe)
253 semantic_error("Offset/Line/Lazy pattern can't be used with "
254 "return probe.");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500255
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500256 pr_debug("symbol:%s file:%s line:%d offset:%d return:%d lazy:%s\n",
257 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
258 pp->lazy_line);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500259}
260
261/* Parse perf-probe event definition */
Masami Hiramatsufac13fd2009-12-15 10:31:14 -0500262void parse_perf_probe_event(const char *str, struct probe_point *pp,
263 bool *need_dwarf)
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500264{
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500265 char **argv;
Masami Hiramatsufac13fd2009-12-15 10:31:14 -0500266 int argc, i;
267
268 *need_dwarf = false;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500269
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500270 argv = argv_split(str, &argc);
271 if (!argv)
272 die("argv_split failed.");
273 if (argc > MAX_PROBE_ARGS + 1)
274 semantic_error("Too many arguments");
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500275
276 /* Parse probe point */
277 parse_perf_probe_probepoint(argv[0], pp);
Masami Hiramatsufc6ceea2010-03-12 18:22:24 -0500278 if (pp->file || pp->line || pp->lazy_line)
Masami Hiramatsufac13fd2009-12-15 10:31:14 -0500279 *need_dwarf = true;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500280
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500281 /* Copy arguments and ensure return probe has no C argument */
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500282 pp->nr_args = argc - 1;
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400283 pp->args = xzalloc(sizeof(char *) * pp->nr_args);
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500284 for (i = 0; i < pp->nr_args; i++) {
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400285 pp->args[i] = xstrdup(argv[i + 1]);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500286 if (is_c_varname(pp->args[i])) {
287 if (pp->retprobe)
288 semantic_error("You can't specify local"
289 " variable for kretprobe");
Masami Hiramatsufac13fd2009-12-15 10:31:14 -0500290 *need_dwarf = true;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500291 }
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500292 }
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500293
Masami Hiramatsue1c01d62009-11-30 19:20:05 -0500294 argv_free(argv);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500295}
296
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500297/* Parse kprobe_events event into struct probe_point */
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500298void parse_trace_kprobe_event(const char *str, struct probe_point *pp)
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500299{
300 char pr;
301 char *p;
302 int ret, i, argc;
303 char **argv;
304
305 pr_debug("Parsing kprobe_events: %s\n", str);
306 argv = argv_split(str, &argc);
307 if (!argv)
308 die("argv_split failed.");
309 if (argc < 2)
310 semantic_error("Too less arguments.");
311
312 /* Scan event and group name. */
Liming Wang93aaa452009-12-02 16:42:54 +0800313 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500314 &pr, (float *)(void *)&pp->group,
315 (float *)(void *)&pp->event);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500316 if (ret != 3)
317 semantic_error("Failed to parse event name: %s", argv[0]);
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500318 pr_debug("Group:%s Event:%s probe:%c\n", pp->group, pp->event, pr);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500319
320 pp->retprobe = (pr == 'r');
321
322 /* Scan function name and offset */
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500323 ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function,
324 &pp->offset);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500325 if (ret == 1)
326 pp->offset = 0;
327
328 /* kprobe_events doesn't have this information */
329 pp->line = 0;
330 pp->file = NULL;
331
332 pp->nr_args = argc - 2;
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400333 pp->args = xzalloc(sizeof(char *) * pp->nr_args);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500334 for (i = 0; i < pp->nr_args; i++) {
335 p = strchr(argv[i + 2], '=');
336 if (p) /* We don't need which register is assigned. */
337 *p = '\0';
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400338 pp->args[i] = xstrdup(argv[i + 2]);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500339 }
340
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500341 argv_free(argv);
342}
343
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500344/* Synthesize only probe point (not argument) */
345int synthesize_perf_probe_point(struct probe_point *pp)
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500346{
347 char *buf;
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500348 char offs[64] = "", line[64] = "";
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500349 int ret;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500350
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400351 pp->probes[0] = buf = xzalloc(MAX_CMDLEN);
Masami Hiramatsu388c3aa2010-02-18 13:16:52 -0500352 pp->found = 1;
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500353 if (pp->offset) {
354 ret = e_snprintf(offs, 64, "+%d", pp->offset);
355 if (ret <= 0)
356 goto error;
357 }
358 if (pp->line) {
359 ret = e_snprintf(line, 64, ":%d", pp->line);
360 if (ret <= 0)
361 goto error;
362 }
363
364 if (pp->function)
365 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->function,
366 offs, pp->retprobe ? "%return" : "", line);
367 else
Masami Hiramatsu84988452009-12-07 12:00:53 -0500368 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line);
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500369 if (ret <= 0) {
370error:
371 free(pp->probes[0]);
372 pp->probes[0] = NULL;
Masami Hiramatsu388c3aa2010-02-18 13:16:52 -0500373 pp->found = 0;
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500374 }
375 return ret;
376}
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500377
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500378int synthesize_perf_probe_event(struct probe_point *pp)
379{
380 char *buf;
381 int i, len, ret;
382
383 len = synthesize_perf_probe_point(pp);
384 if (len < 0)
385 return 0;
386
387 buf = pp->probes[0];
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500388 for (i = 0; i < pp->nr_args; i++) {
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500389 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
390 pp->args[i]);
391 if (ret <= 0)
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500392 goto error;
393 len += ret;
394 }
395 pp->found = 1;
396
397 return pp->found;
398error:
399 free(pp->probes[0]);
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500400 pp->probes[0] = NULL;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500401
402 return ret;
403}
404
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500405int synthesize_trace_kprobe_event(struct probe_point *pp)
406{
407 char *buf;
408 int i, len, ret;
409
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400410 pp->probes[0] = buf = xzalloc(MAX_CMDLEN);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500411 ret = e_snprintf(buf, MAX_CMDLEN, "%s+%d", pp->function, pp->offset);
412 if (ret <= 0)
413 goto error;
414 len = ret;
415
416 for (i = 0; i < pp->nr_args; i++) {
417 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
418 pp->args[i]);
419 if (ret <= 0)
420 goto error;
421 len += ret;
422 }
423 pp->found = 1;
424
425 return pp->found;
426error:
427 free(pp->probes[0]);
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500428 pp->probes[0] = NULL;
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500429
430 return ret;
431}
432
433static int open_kprobe_events(int flags, int mode)
434{
435 char buf[PATH_MAX];
436 int ret;
437
438 ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path);
439 if (ret < 0)
440 die("Failed to make kprobe_events path.");
441
442 ret = open(buf, flags, mode);
443 if (ret < 0) {
444 if (errno == ENOENT)
445 die("kprobe_events file does not exist -"
Liming Wang63bbd5e2009-12-29 16:37:09 +0800446 " please rebuild with CONFIG_KPROBE_EVENT.");
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500447 else
448 die("Could not open kprobe_events file: %s",
449 strerror(errno));
450 }
451 return ret;
452}
453
454/* Get raw string list of current kprobe_events */
455static struct strlist *get_trace_kprobe_event_rawlist(int fd)
456{
457 int ret, idx;
458 FILE *fp;
459 char buf[MAX_CMDLEN];
460 char *p;
461 struct strlist *sl;
462
463 sl = strlist__new(true, NULL);
464
465 fp = fdopen(dup(fd), "r");
466 while (!feof(fp)) {
467 p = fgets(buf, MAX_CMDLEN, fp);
468 if (!p)
469 break;
470
471 idx = strlen(p) - 1;
472 if (p[idx] == '\n')
473 p[idx] = '\0';
474 ret = strlist__add(sl, buf);
475 if (ret < 0)
476 die("strlist__add failed: %s", strerror(-ret));
477 }
478 fclose(fp);
479
480 return sl;
481}
482
483/* Free and zero clear probe_point */
484static void clear_probe_point(struct probe_point *pp)
485{
486 int i;
487
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500488 if (pp->event)
489 free(pp->event);
490 if (pp->group)
491 free(pp->group);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500492 if (pp->function)
493 free(pp->function);
494 if (pp->file)
495 free(pp->file);
Masami Hiramatsu2a9c8c32010-02-25 08:36:12 -0500496 if (pp->lazy_line)
497 free(pp->lazy_line);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500498 for (i = 0; i < pp->nr_args; i++)
499 free(pp->args[i]);
500 if (pp->args)
501 free(pp->args);
502 for (i = 0; i < pp->found; i++)
503 free(pp->probes[i]);
Julia Lawall5660ce32009-12-09 20:26:18 +0100504 memset(pp, 0, sizeof(*pp));
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500505}
506
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500507/* Show an event */
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500508static void show_perf_probe_event(const char *event, const char *place,
509 struct probe_point *pp)
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500510{
Masami Hiramatsu7e990a52009-12-15 10:31:21 -0500511 int i, ret;
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500512 char buf[128];
513
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500514 ret = e_snprintf(buf, 128, "%s:%s", pp->group, event);
Masami Hiramatsu7e990a52009-12-15 10:31:21 -0500515 if (ret < 0)
516 die("Failed to copy event: %s", strerror(-ret));
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500517 printf(" %-40s (on %s", buf, place);
518
519 if (pp->nr_args > 0) {
520 printf(" with");
521 for (i = 0; i < pp->nr_args; i++)
522 printf(" %s", pp->args[i]);
523 }
524 printf(")\n");
525}
526
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500527/* List up current perf-probe events */
528void show_perf_probe_events(void)
529{
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500530 int fd;
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500531 struct probe_point pp;
532 struct strlist *rawlist;
533 struct str_node *ent;
534
Masami Hiramatsu72041332010-01-05 17:47:10 -0500535 setup_pager();
Masami Hiramatsu388c3aa2010-02-18 13:16:52 -0500536 memset(&pp, 0, sizeof(pp));
Masami Hiramatsu72041332010-01-05 17:47:10 -0500537
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500538 fd = open_kprobe_events(O_RDONLY, 0);
539 rawlist = get_trace_kprobe_event_rawlist(fd);
540 close(fd);
541
Masami Hiramatsuadf365f2009-12-15 10:32:03 -0500542 strlist__for_each(ent, rawlist) {
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500543 parse_trace_kprobe_event(ent->s, &pp);
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500544 /* Synthesize only event probe point */
Masami Hiramatsu7ef17aa2009-12-15 10:32:47 -0500545 synthesize_perf_probe_point(&pp);
Masami Hiramatsu278498d2009-12-08 17:02:40 -0500546 /* Show an event */
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500547 show_perf_probe_event(pp.event, pp.probes[0], &pp);
Masami Hiramatsu4de189f2009-11-30 19:20:17 -0500548 clear_probe_point(&pp);
549 }
550
551 strlist__delete(rawlist);
552}
553
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500554/* Get current perf-probe event names */
Masami Hiramatsufa282442009-12-08 17:03:23 -0500555static struct strlist *get_perf_event_names(int fd, bool include_group)
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500556{
Masami Hiramatsufa282442009-12-08 17:03:23 -0500557 char buf[128];
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500558 struct strlist *sl, *rawlist;
559 struct str_node *ent;
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500560 struct probe_point pp;
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500561
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500562 memset(&pp, 0, sizeof(pp));
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500563 rawlist = get_trace_kprobe_event_rawlist(fd);
564
Masami Hiramatsue1d20172009-12-07 12:00:46 -0500565 sl = strlist__new(true, NULL);
Masami Hiramatsuadf365f2009-12-15 10:32:03 -0500566 strlist__for_each(ent, rawlist) {
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500567 parse_trace_kprobe_event(ent->s, &pp);
Masami Hiramatsufa282442009-12-08 17:03:23 -0500568 if (include_group) {
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500569 if (e_snprintf(buf, 128, "%s:%s", pp.group,
570 pp.event) < 0)
Masami Hiramatsufa282442009-12-08 17:03:23 -0500571 die("Failed to copy group:event name.");
572 strlist__add(sl, buf);
573 } else
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500574 strlist__add(sl, pp.event);
575 clear_probe_point(&pp);
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500576 }
577
578 strlist__delete(rawlist);
579
580 return sl;
581}
582
Masami Hiramatsua9b495b2009-12-08 17:02:47 -0500583static void write_trace_kprobe_event(int fd, const char *buf)
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500584{
585 int ret;
586
Masami Hiramatsufa282442009-12-08 17:03:23 -0500587 pr_debug("Writing event: %s\n", buf);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500588 ret = write(fd, buf, strlen(buf));
589 if (ret <= 0)
Masami Hiramatsufa282442009-12-08 17:03:23 -0500590 die("Failed to write event: %s", strerror(errno));
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500591}
592
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500593static void get_new_event_name(char *buf, size_t len, const char *base,
Masami Hiramatsud761b082009-12-15 10:32:25 -0500594 struct strlist *namelist, bool allow_suffix)
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500595{
596 int i, ret;
Masami Hiramatsu17f88fc2009-12-08 17:03:02 -0500597
598 /* Try no suffix */
599 ret = e_snprintf(buf, len, "%s", base);
600 if (ret < 0)
601 die("snprintf() failed: %s", strerror(-ret));
602 if (!strlist__has_entry(namelist, buf))
603 return;
604
Masami Hiramatsud761b082009-12-15 10:32:25 -0500605 if (!allow_suffix) {
606 pr_warning("Error: event \"%s\" already exists. "
607 "(Use -f to force duplicates.)\n", base);
608 die("Can't add new event.");
609 }
610
Masami Hiramatsu17f88fc2009-12-08 17:03:02 -0500611 /* Try to add suffix */
612 for (i = 1; i < MAX_EVENT_INDEX; i++) {
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500613 ret = e_snprintf(buf, len, "%s_%d", base, i);
614 if (ret < 0)
615 die("snprintf() failed: %s", strerror(-ret));
616 if (!strlist__has_entry(namelist, buf))
617 break;
618 }
619 if (i == MAX_EVENT_INDEX)
620 die("Too many events are on the same function.");
621}
622
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -0400623static void __add_trace_kprobe_events(struct probe_point *probes,
624 int nr_probes, bool force_add)
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500625{
626 int i, j, fd;
627 struct probe_point *pp;
628 char buf[MAX_CMDLEN];
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500629 char event[64];
630 struct strlist *namelist;
Masami Hiramatsud761b082009-12-15 10:32:25 -0500631 bool allow_suffix;
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500632
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500633 fd = open_kprobe_events(O_RDWR, O_APPEND);
634 /* Get current event names */
Masami Hiramatsufa282442009-12-08 17:03:23 -0500635 namelist = get_perf_event_names(fd, false);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500636
637 for (j = 0; j < nr_probes; j++) {
638 pp = probes + j;
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500639 if (!pp->event)
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400640 pp->event = xstrdup(pp->function);
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500641 if (!pp->group)
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400642 pp->group = xstrdup(PERFPROBE_GROUP);
Masami Hiramatsud761b082009-12-15 10:32:25 -0500643 /* If force_add is true, suffix search is allowed */
644 allow_suffix = force_add;
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500645 for (i = 0; i < pp->found; i++) {
646 /* Get an unused new event name */
Masami Hiramatsud761b082009-12-15 10:32:25 -0500647 get_new_event_name(event, 64, pp->event, namelist,
648 allow_suffix);
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500649 snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n",
650 pp->retprobe ? 'r' : 'p',
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500651 pp->group, event,
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500652 pp->probes[i]);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500653 write_trace_kprobe_event(fd, buf);
Masami Hiramatsua9b495b2009-12-08 17:02:47 -0500654 printf("Added new event:\n");
655 /* Get the first parameter (probe-point) */
656 sscanf(pp->probes[i], "%s", buf);
Masami Hiramatsuaf663d72009-12-15 10:32:18 -0500657 show_perf_probe_event(event, buf, pp);
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500658 /* Add added event name to namelist */
659 strlist__add(namelist, event);
Masami Hiramatsud761b082009-12-15 10:32:25 -0500660 /*
661 * Probes after the first probe which comes from same
662 * user input are always allowed to add suffix, because
663 * there might be several addresses corresponding to
664 * one code line.
665 */
666 allow_suffix = true;
Masami Hiramatsub498ce12009-11-30 19:20:25 -0500667 }
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500668 }
Masami Hiramatsua9b495b2009-12-08 17:02:47 -0500669 /* Show how to use the event. */
670 printf("\nYou can now use it on all perf tools, such as:\n\n");
671 printf("\tperf record -e %s:%s -a sleep 1\n\n", PERFPROBE_GROUP, event);
672
Masami Hiramatsue1d20172009-12-07 12:00:46 -0500673 strlist__delete(namelist);
Masami Hiramatsu50656ee2009-11-30 19:19:58 -0500674 close(fd);
675}
Masami Hiramatsufa282442009-12-08 17:03:23 -0500676
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -0400677/* Currently just checking function name from symbol map */
678static void evaluate_probe_point(struct probe_point *pp)
679{
680 struct symbol *sym;
681 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
682 pp->function, NULL);
683 if (!sym)
684 die("Kernel symbol \'%s\' not found - probe not added.",
685 pp->function);
686}
687
688void add_trace_kprobe_events(struct probe_point *probes, int nr_probes,
689 bool force_add, bool need_dwarf)
690{
691 int i, ret;
692 struct probe_point *pp;
693#ifndef NO_DWARF_SUPPORT
694 int fd;
695#endif
696 /* Add probes */
697 init_vmlinux();
698
699 if (need_dwarf)
700#ifdef NO_DWARF_SUPPORT
701 die("Debuginfo-analysis is not supported");
702#else /* !NO_DWARF_SUPPORT */
703 pr_debug("Some probes require debuginfo.\n");
704
705 fd = open_vmlinux();
706 if (fd < 0) {
707 if (need_dwarf)
708 die("Could not open debuginfo file.");
709
710 pr_debug("Could not open vmlinux/module file."
711 " Try to use symbols.\n");
712 goto end_dwarf;
713 }
714
715 /* Searching probe points */
716 for (i = 0; i < nr_probes; i++) {
717 pp = &probes[i];
718 if (pp->found)
719 continue;
720
721 lseek(fd, SEEK_SET, 0);
722 ret = find_probe_point(fd, pp);
723 if (ret > 0)
724 continue;
725 if (ret == 0) { /* No error but failed to find probe point. */
726 synthesize_perf_probe_point(pp);
727 die("Probe point '%s' not found. - probe not added.",
728 pp->probes[0]);
729 }
730 /* Error path */
731 if (need_dwarf) {
732 if (ret == -ENOENT)
733 pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO=y.\n");
734 die("Could not analyze debuginfo.");
735 }
736 pr_debug("An error occurred in debuginfo analysis."
737 " Try to use symbols.\n");
738 break;
739 }
740 close(fd);
741
742end_dwarf:
743#endif /* !NO_DWARF_SUPPORT */
744
745 /* Synthesize probes without dwarf */
746 for (i = 0; i < nr_probes; i++) {
747 pp = &probes[i];
748 if (pp->found) /* This probe is already found. */
749 continue;
750
751 evaluate_probe_point(pp);
752 ret = synthesize_trace_kprobe_event(pp);
753 if (ret == -E2BIG)
754 die("probe point definition becomes too long.");
755 else if (ret < 0)
756 die("Failed to synthesize a probe point.");
757 }
758
759 /* Settng up probe points */
760 __add_trace_kprobe_events(probes, nr_probes, force_add);
761}
762
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500763static void __del_trace_kprobe_event(int fd, struct str_node *ent)
764{
765 char *p;
766 char buf[128];
767
768 /* Convert from perf-probe event to trace-kprobe event */
769 if (e_snprintf(buf, 128, "-:%s", ent->s) < 0)
770 die("Failed to copy event.");
771 p = strchr(buf + 2, ':');
772 if (!p)
773 die("Internal error: %s should have ':' but not.", ent->s);
774 *p = '/';
775
776 write_trace_kprobe_event(fd, buf);
777 printf("Remove event: %s\n", ent->s);
778}
779
Masami Hiramatsufa282442009-12-08 17:03:23 -0500780static void del_trace_kprobe_event(int fd, const char *group,
781 const char *event, struct strlist *namelist)
782{
783 char buf[128];
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500784 struct str_node *ent, *n;
785 int found = 0;
Masami Hiramatsufa282442009-12-08 17:03:23 -0500786
787 if (e_snprintf(buf, 128, "%s:%s", group, event) < 0)
788 die("Failed to copy event.");
Masami Hiramatsufa282442009-12-08 17:03:23 -0500789
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500790 if (strpbrk(buf, "*?")) { /* Glob-exp */
791 strlist__for_each_safe(ent, n, namelist)
792 if (strglobmatch(ent->s, buf)) {
793 found++;
794 __del_trace_kprobe_event(fd, ent);
795 strlist__remove(namelist, ent);
796 }
797 } else {
798 ent = strlist__find(namelist, buf);
799 if (ent) {
800 found++;
801 __del_trace_kprobe_event(fd, ent);
802 strlist__remove(namelist, ent);
803 }
804 }
805 if (found == 0)
806 pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf);
Masami Hiramatsufa282442009-12-08 17:03:23 -0500807}
808
809void del_trace_kprobe_events(struct strlist *dellist)
810{
811 int fd;
Masami Hiramatsufa282442009-12-08 17:03:23 -0500812 const char *group, *event;
813 char *p, *str;
814 struct str_node *ent;
815 struct strlist *namelist;
816
817 fd = open_kprobe_events(O_RDWR, O_APPEND);
818 /* Get current event names */
819 namelist = get_perf_event_names(fd, true);
820
Masami Hiramatsuadf365f2009-12-15 10:32:03 -0500821 strlist__for_each(ent, dellist) {
Masami Hiramatsu31facc52010-03-16 18:05:30 -0400822 str = xstrdup(ent->s);
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500823 pr_debug("Parsing: %s\n", str);
Masami Hiramatsufa282442009-12-08 17:03:23 -0500824 p = strchr(str, ':');
825 if (p) {
826 group = str;
827 *p = '\0';
828 event = p + 1;
829 } else {
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500830 group = "*";
Masami Hiramatsufa282442009-12-08 17:03:23 -0500831 event = str;
832 }
Masami Hiramatsubbbb5212009-12-15 10:32:10 -0500833 pr_debug("Group: %s, Event: %s\n", group, event);
Masami Hiramatsufa282442009-12-08 17:03:23 -0500834 del_trace_kprobe_event(fd, group, event, namelist);
835 free(str);
836 }
837 strlist__delete(namelist);
838 close(fd);
839}
840
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500841#define LINEBUF_SIZE 256
Masami Hiramatsu5c8d1cb2010-02-25 08:36:04 -0500842#define NR_ADDITIONAL_LINES 2
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500843
844static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
845{
846 char buf[LINEBUF_SIZE];
847 const char *color = PERF_COLOR_BLUE;
848
849 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
850 goto error;
851 if (!skip) {
852 if (show_num)
853 fprintf(stdout, "%7u %s", l, buf);
854 else
855 color_fprintf(stdout, color, " %s", buf);
856 }
857
858 while (strlen(buf) == LINEBUF_SIZE - 1 &&
859 buf[LINEBUF_SIZE - 2] != '\n') {
860 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
861 goto error;
862 if (!skip) {
863 if (show_num)
864 fprintf(stdout, "%s", buf);
865 else
866 color_fprintf(stdout, color, "%s", buf);
867 }
868 }
869 return;
870error:
871 if (feof(fp))
872 die("Source file is shorter than expected.");
873 else
874 die("File read error: %s", strerror(errno));
875}
876
877void show_line_range(struct line_range *lr)
878{
879 unsigned int l = 1;
880 struct line_node *ln;
881 FILE *fp;
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -0400882 int fd, ret;
883
884 /* Search a line range */
885 init_vmlinux();
886 fd = open_vmlinux();
887 if (fd < 0)
888 die("Could not open debuginfo file.");
889 ret = find_line_range(fd, lr);
890 if (ret <= 0)
891 die("Source line is not found.\n");
892 close(fd);
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500893
894 setup_pager();
895
896 if (lr->function)
897 fprintf(stdout, "<%s:%d>\n", lr->function,
898 lr->start - lr->offset);
899 else
900 fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
901
902 fp = fopen(lr->path, "r");
903 if (fp == NULL)
904 die("Failed to open %s: %s", lr->path, strerror(errno));
905 /* Skip to starting line number */
906 while (l < lr->start)
907 show_one_line(fp, l++, true, false);
908
909 list_for_each_entry(ln, &lr->line_list, list) {
910 while (ln->line > l)
911 show_one_line(fp, (l++) - lr->offset, false, false);
912 show_one_line(fp, (l++) - lr->offset, false, true);
913 }
Masami Hiramatsu5c8d1cb2010-02-25 08:36:04 -0500914
915 if (lr->end == INT_MAX)
916 lr->end = l + NR_ADDITIONAL_LINES;
917 while (l < lr->end && !feof(fp))
918 show_one_line(fp, (l++) - lr->offset, false, false);
919
Masami Hiramatsu631c9de2010-01-06 09:45:34 -0500920 fclose(fp);
921}
Masami Hiramatsue0faa8d2010-03-16 18:05:37 -0400922
923