2 * probe-event.c : perf-probe definition to kprobe_events format converter
4 * Written by Masami Hiramatsu <mhiramat@redhat.com>
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.
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.
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.
23 #include <sys/utsname.h>
24 #include <sys/types.h>
43 #include "parse-events.h" /* For debugfs_path */
44 #include "probe-event.h"
46 #define MAX_CMDLEN 256
47 #define MAX_PROBE_ARGS 128
48 #define PERFPROBE_GROUP "probe"
50 #define semantic_error(msg ...) die("Semantic error :" msg)
52 /* If there is no space to write, returns -E2BIG. */
53 static int e_snprintf(char *str, size_t size, const char *format, ...)
54 __attribute__((format(printf, 3, 4)));
56 static int e_snprintf(char *str, size_t size, const char *format, ...)
61 ret = vsnprintf(str, size, format, ap);
68 void parse_line_range_desc(const char *arg, struct line_range *lr)
75 * FUNC[:SLN[+NUM|-ELN]]
77 ptr = strchr(arg, ':');
79 lr->start = (unsigned int)strtoul(ptr + 1, &tmp, 0);
81 lr->end = lr->start + (unsigned int)strtoul(tmp + 1,
84 lr->end = (unsigned int)strtoul(tmp + 1, &tmp, 0);
87 pr_debug("Line range is %u to %u\n", lr->start, lr->end);
88 if (lr->end && lr->start > lr->end)
89 semantic_error("Start line must be smaller"
92 semantic_error("Tailing with invalid character '%d'.",
94 tmp = xstrndup(arg, (ptr - arg));
104 /* Check the name is good for event/group */
105 static bool check_event_name(const char *name)
107 if (!isalpha(*name) && *name != '_')
109 while (*++name != '\0') {
110 if (!isalpha(*name) && !isdigit(*name) && *name != '_')
116 /* Parse probepoint definition. */
117 static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
123 * perf probe [EVENT=]SRC[:LN|;PTN]
124 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
126 * TODO:Group name support
129 ptr = strpbrk(arg, ";=@+%");
130 if (ptr && *ptr == '=') { /* Event name */
133 ptr = strchr(arg, ':');
134 if (ptr) /* Group name is not supported yet. */
135 semantic_error("Group name is not supported yet.");
136 if (!check_event_name(arg))
137 semantic_error("%s is bad for event name -it must "
138 "follow C symbol-naming rule.", arg);
139 pp->event = xstrdup(arg);
143 ptr = strpbrk(arg, ";:+@%");
149 /* Check arg is function or file and copy it */
150 if (strchr(arg, '.')) /* File */
151 pp->file = xstrdup(arg);
153 pp->function = xstrdup(arg);
155 /* Parse other options */
159 if (c == ';') { /* Lazy pattern must be the last part */
160 pp->lazy_line = xstrdup(arg);
163 ptr = strpbrk(arg, ";:+@%");
169 case ':': /* Line number */
170 pp->line = strtoul(arg, &tmp, 0);
172 semantic_error("There is non-digit char"
175 case '+': /* Byte offset from a symbol */
176 pp->offset = strtoul(arg, &tmp, 0);
178 semantic_error("There is non-digit character"
181 case '@': /* File name */
183 semantic_error("SRC@SRC is not allowed.");
184 pp->file = xstrdup(arg);
186 case '%': /* Probe places */
187 if (strcmp(arg, "return") == 0) {
189 } else /* Others not supported yet */
190 semantic_error("%%%s is not supported.", arg);
193 DIE_IF("Program has a bug.");
198 /* Exclusion check */
199 if (pp->lazy_line && pp->line)
200 semantic_error("Lazy pattern can't be used with line number.");
202 if (pp->lazy_line && pp->offset)
203 semantic_error("Lazy pattern can't be used with offset.");
205 if (pp->line && pp->offset)
206 semantic_error("Offset can't be used with line number.");
208 if (!pp->line && !pp->lazy_line && pp->file && !pp->function)
209 semantic_error("File always requires line number or "
212 if (pp->offset && !pp->function)
213 semantic_error("Offset requires an entry function.");
215 if (pp->retprobe && !pp->function)
216 semantic_error("Return probe requires an entry function.");
218 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe)
219 semantic_error("Offset/Line/Lazy pattern can't be used with "
222 pr_debug("symbol:%s file:%s line:%d offset:%d return:%d lazy:%s\n",
223 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
227 /* Parse perf-probe event definition */
228 void parse_perf_probe_event(const char *str, struct probe_point *pp,
236 argv = argv_split(str, &argc);
238 die("argv_split failed.");
239 if (argc > MAX_PROBE_ARGS + 1)
240 semantic_error("Too many arguments");
242 /* Parse probe point */
243 parse_perf_probe_probepoint(argv[0], pp);
244 if (pp->file || pp->line || pp->lazy_line)
247 /* Copy arguments and ensure return probe has no C argument */
248 pp->nr_args = argc - 1;
249 pp->args = xzalloc(sizeof(char *) * pp->nr_args);
250 for (i = 0; i < pp->nr_args; i++) {
251 pp->args[i] = xstrdup(argv[i + 1]);
252 if (is_c_varname(pp->args[i])) {
254 semantic_error("You can't specify local"
255 " variable for kretprobe");
263 /* Parse kprobe_events event into struct probe_point */
264 void parse_trace_kprobe_event(const char *str, struct probe_point *pp)
271 pr_debug("Parsing kprobe_events: %s\n", str);
272 argv = argv_split(str, &argc);
274 die("argv_split failed.");
276 semantic_error("Too less arguments.");
278 /* Scan event and group name. */
279 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
280 &pr, (float *)(void *)&pp->group,
281 (float *)(void *)&pp->event);
283 semantic_error("Failed to parse event name: %s", argv[0]);
284 pr_debug("Group:%s Event:%s probe:%c\n", pp->group, pp->event, pr);
286 pp->retprobe = (pr == 'r');
288 /* Scan function name and offset */
289 ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function,
294 /* kprobe_events doesn't have this information */
298 pp->nr_args = argc - 2;
299 pp->args = xzalloc(sizeof(char *) * pp->nr_args);
300 for (i = 0; i < pp->nr_args; i++) {
301 p = strchr(argv[i + 2], '=');
302 if (p) /* We don't need which register is assigned. */
304 pp->args[i] = xstrdup(argv[i + 2]);
310 /* Synthesize only probe point (not argument) */
311 int synthesize_perf_probe_point(struct probe_point *pp)
314 char offs[64] = "", line[64] = "";
317 pp->probes[0] = buf = xzalloc(MAX_CMDLEN);
320 ret = e_snprintf(offs, 64, "+%d", pp->offset);
325 ret = e_snprintf(line, 64, ":%d", pp->line);
331 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->function,
332 offs, pp->retprobe ? "%return" : "", line);
334 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line);
338 pp->probes[0] = NULL;
344 int synthesize_perf_probe_event(struct probe_point *pp)
349 len = synthesize_perf_probe_point(pp);
354 for (i = 0; i < pp->nr_args; i++) {
355 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
366 pp->probes[0] = NULL;
371 int synthesize_trace_kprobe_event(struct probe_point *pp)
376 pp->probes[0] = buf = xzalloc(MAX_CMDLEN);
377 ret = e_snprintf(buf, MAX_CMDLEN, "%s+%d", pp->function, pp->offset);
382 for (i = 0; i < pp->nr_args; i++) {
383 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
394 pp->probes[0] = NULL;
399 static int open_kprobe_events(int flags, int mode)
404 ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path);
406 die("Failed to make kprobe_events path.");
408 ret = open(buf, flags, mode);
411 die("kprobe_events file does not exist -"
412 " please rebuild with CONFIG_KPROBE_EVENT.");
414 die("Could not open kprobe_events file: %s",
420 /* Get raw string list of current kprobe_events */
421 static struct strlist *get_trace_kprobe_event_rawlist(int fd)
425 char buf[MAX_CMDLEN];
429 sl = strlist__new(true, NULL);
431 fp = fdopen(dup(fd), "r");
433 p = fgets(buf, MAX_CMDLEN, fp);
440 ret = strlist__add(sl, buf);
442 die("strlist__add failed: %s", strerror(-ret));
449 /* Free and zero clear probe_point */
450 static void clear_probe_point(struct probe_point *pp)
464 for (i = 0; i < pp->nr_args; i++)
468 for (i = 0; i < pp->found; i++)
470 memset(pp, 0, sizeof(*pp));
474 static void show_perf_probe_event(const char *event, const char *place,
475 struct probe_point *pp)
480 ret = e_snprintf(buf, 128, "%s:%s", pp->group, event);
482 die("Failed to copy event: %s", strerror(-ret));
483 printf(" %-40s (on %s", buf, place);
485 if (pp->nr_args > 0) {
487 for (i = 0; i < pp->nr_args; i++)
488 printf(" %s", pp->args[i]);
493 /* List up current perf-probe events */
494 void show_perf_probe_events(void)
497 struct probe_point pp;
498 struct strlist *rawlist;
499 struct str_node *ent;
502 memset(&pp, 0, sizeof(pp));
504 fd = open_kprobe_events(O_RDONLY, 0);
505 rawlist = get_trace_kprobe_event_rawlist(fd);
508 strlist__for_each(ent, rawlist) {
509 parse_trace_kprobe_event(ent->s, &pp);
510 /* Synthesize only event probe point */
511 synthesize_perf_probe_point(&pp);
513 show_perf_probe_event(pp.event, pp.probes[0], &pp);
514 clear_probe_point(&pp);
517 strlist__delete(rawlist);
520 /* Get current perf-probe event names */
521 static struct strlist *get_perf_event_names(int fd, bool include_group)
524 struct strlist *sl, *rawlist;
525 struct str_node *ent;
526 struct probe_point pp;
528 memset(&pp, 0, sizeof(pp));
529 rawlist = get_trace_kprobe_event_rawlist(fd);
531 sl = strlist__new(true, NULL);
532 strlist__for_each(ent, rawlist) {
533 parse_trace_kprobe_event(ent->s, &pp);
535 if (e_snprintf(buf, 128, "%s:%s", pp.group,
537 die("Failed to copy group:event name.");
538 strlist__add(sl, buf);
540 strlist__add(sl, pp.event);
541 clear_probe_point(&pp);
544 strlist__delete(rawlist);
549 static void write_trace_kprobe_event(int fd, const char *buf)
553 pr_debug("Writing event: %s\n", buf);
554 ret = write(fd, buf, strlen(buf));
556 die("Failed to write event: %s", strerror(errno));
559 static void get_new_event_name(char *buf, size_t len, const char *base,
560 struct strlist *namelist, bool allow_suffix)
565 ret = e_snprintf(buf, len, "%s", base);
567 die("snprintf() failed: %s", strerror(-ret));
568 if (!strlist__has_entry(namelist, buf))
572 pr_warning("Error: event \"%s\" already exists. "
573 "(Use -f to force duplicates.)\n", base);
574 die("Can't add new event.");
577 /* Try to add suffix */
578 for (i = 1; i < MAX_EVENT_INDEX; i++) {
579 ret = e_snprintf(buf, len, "%s_%d", base, i);
581 die("snprintf() failed: %s", strerror(-ret));
582 if (!strlist__has_entry(namelist, buf))
585 if (i == MAX_EVENT_INDEX)
586 die("Too many events are on the same function.");
589 void add_trace_kprobe_events(struct probe_point *probes, int nr_probes,
593 struct probe_point *pp;
594 char buf[MAX_CMDLEN];
596 struct strlist *namelist;
599 fd = open_kprobe_events(O_RDWR, O_APPEND);
600 /* Get current event names */
601 namelist = get_perf_event_names(fd, false);
603 for (j = 0; j < nr_probes; j++) {
606 pp->event = xstrdup(pp->function);
608 pp->group = xstrdup(PERFPROBE_GROUP);
609 /* If force_add is true, suffix search is allowed */
610 allow_suffix = force_add;
611 for (i = 0; i < pp->found; i++) {
612 /* Get an unused new event name */
613 get_new_event_name(event, 64, pp->event, namelist,
615 snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n",
616 pp->retprobe ? 'r' : 'p',
619 write_trace_kprobe_event(fd, buf);
620 printf("Added new event:\n");
621 /* Get the first parameter (probe-point) */
622 sscanf(pp->probes[i], "%s", buf);
623 show_perf_probe_event(event, buf, pp);
624 /* Add added event name to namelist */
625 strlist__add(namelist, event);
627 * Probes after the first probe which comes from same
628 * user input are always allowed to add suffix, because
629 * there might be several addresses corresponding to
635 /* Show how to use the event. */
636 printf("\nYou can now use it on all perf tools, such as:\n\n");
637 printf("\tperf record -e %s:%s -a sleep 1\n\n", PERFPROBE_GROUP, event);
639 strlist__delete(namelist);
643 static void __del_trace_kprobe_event(int fd, struct str_node *ent)
648 /* Convert from perf-probe event to trace-kprobe event */
649 if (e_snprintf(buf, 128, "-:%s", ent->s) < 0)
650 die("Failed to copy event.");
651 p = strchr(buf + 2, ':');
653 die("Internal error: %s should have ':' but not.", ent->s);
656 write_trace_kprobe_event(fd, buf);
657 printf("Remove event: %s\n", ent->s);
660 static void del_trace_kprobe_event(int fd, const char *group,
661 const char *event, struct strlist *namelist)
664 struct str_node *ent, *n;
667 if (e_snprintf(buf, 128, "%s:%s", group, event) < 0)
668 die("Failed to copy event.");
670 if (strpbrk(buf, "*?")) { /* Glob-exp */
671 strlist__for_each_safe(ent, n, namelist)
672 if (strglobmatch(ent->s, buf)) {
674 __del_trace_kprobe_event(fd, ent);
675 strlist__remove(namelist, ent);
678 ent = strlist__find(namelist, buf);
681 __del_trace_kprobe_event(fd, ent);
682 strlist__remove(namelist, ent);
686 pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf);
689 void del_trace_kprobe_events(struct strlist *dellist)
692 const char *group, *event;
694 struct str_node *ent;
695 struct strlist *namelist;
697 fd = open_kprobe_events(O_RDWR, O_APPEND);
698 /* Get current event names */
699 namelist = get_perf_event_names(fd, true);
701 strlist__for_each(ent, dellist) {
702 str = xstrdup(ent->s);
703 pr_debug("Parsing: %s\n", str);
704 p = strchr(str, ':');
713 pr_debug("Group: %s, Event: %s\n", group, event);
714 del_trace_kprobe_event(fd, group, event, namelist);
717 strlist__delete(namelist);
721 #define LINEBUF_SIZE 256
722 #define NR_ADDITIONAL_LINES 2
724 static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
726 char buf[LINEBUF_SIZE];
727 const char *color = PERF_COLOR_BLUE;
729 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
733 fprintf(stdout, "%7u %s", l, buf);
735 color_fprintf(stdout, color, " %s", buf);
738 while (strlen(buf) == LINEBUF_SIZE - 1 &&
739 buf[LINEBUF_SIZE - 2] != '\n') {
740 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
744 fprintf(stdout, "%s", buf);
746 color_fprintf(stdout, color, "%s", buf);
752 die("Source file is shorter than expected.");
754 die("File read error: %s", strerror(errno));
757 void show_line_range(struct line_range *lr)
760 struct line_node *ln;
766 fprintf(stdout, "<%s:%d>\n", lr->function,
767 lr->start - lr->offset);
769 fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
771 fp = fopen(lr->path, "r");
773 die("Failed to open %s: %s", lr->path, strerror(errno));
774 /* Skip to starting line number */
775 while (l < lr->start)
776 show_one_line(fp, l++, true, false);
778 list_for_each_entry(ln, &lr->line_list, list) {
780 show_one_line(fp, (l++) - lr->offset, false, false);
781 show_one_line(fp, (l++) - lr->offset, false, true);
784 if (lr->end == INT_MAX)
785 lr->end = l + NR_ADDITIONAL_LINES;
786 while (l < lr->end && !feof(fp))
787 show_one_line(fp, (l++) - lr->offset, false, false);