aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-event.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-04-19 05:52:53 -0400
committerAvi Kivity <avi@redhat.com>2010-05-17 05:17:58 -0400
commit9beeaa2d689842f7760aa16c512e6bb8182d38b6 (patch)
tree62cea0772127c4b1c0b476e46dec6830d36809c1 /tools/perf/util/probe-event.c
parent3246af0ece6c61689847417977733f0b12dc4b6f (diff)
parenta1645ce12adb6c9cc9e19d7695466204e3f017fe (diff)
Merge branch 'perf'
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r--tools/perf/util/probe-event.c1572
1 files changed, 1205 insertions, 367 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 7c004b6ef24f..3967f8f63d0d 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -33,20 +33,27 @@
33#include <limits.h> 33#include <limits.h>
34 34
35#undef _GNU_SOURCE 35#undef _GNU_SOURCE
36#include "util.h"
36#include "event.h" 37#include "event.h"
37#include "string.h" 38#include "string.h"
38#include "strlist.h" 39#include "strlist.h"
39#include "debug.h" 40#include "debug.h"
40#include "cache.h" 41#include "cache.h"
41#include "color.h" 42#include "color.h"
42#include "parse-events.h" /* For debugfs_path */ 43#include "symbol.h"
44#include "thread.h"
45#include "debugfs.h"
46#include "trace-event.h" /* For __unused */
43#include "probe-event.h" 47#include "probe-event.h"
48#include "probe-finder.h"
44 49
45#define MAX_CMDLEN 256 50#define MAX_CMDLEN 256
46#define MAX_PROBE_ARGS 128 51#define MAX_PROBE_ARGS 128
47#define PERFPROBE_GROUP "probe" 52#define PERFPROBE_GROUP "probe"
48 53
49#define semantic_error(msg ...) die("Semantic error :" msg) 54bool probe_event_dry_run; /* Dry run flag */
55
56#define semantic_error(msg ...) pr_err("Semantic error :" msg)
50 57
51/* If there is no space to write, returns -E2BIG. */ 58/* If there is no space to write, returns -E2BIG. */
52static int e_snprintf(char *str, size_t size, const char *format, ...) 59static int e_snprintf(char *str, size_t size, const char *format, ...)
@@ -64,7 +71,270 @@ static int e_snprintf(char *str, size_t size, const char *format, ...)
64 return ret; 71 return ret;
65} 72}
66 73
67void parse_line_range_desc(const char *arg, struct line_range *lr) 74static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
75static struct map_groups kmap_groups;
76static struct map *kmaps[MAP__NR_TYPES];
77
78/* Initialize symbol maps and path of vmlinux */
79static int init_vmlinux(void)
80{
81 struct dso *kernel;
82 int ret;
83
84 symbol_conf.sort_by_name = true;
85 if (symbol_conf.vmlinux_name == NULL)
86 symbol_conf.try_vmlinux_path = true;
87 else
88 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
89 ret = symbol__init();
90 if (ret < 0) {
91 pr_debug("Failed to init symbol map.\n");
92 goto out;
93 }
94
95 kernel = dso__new_kernel(symbol_conf.vmlinux_name);
96 if (kernel == NULL)
97 die("Failed to create kernel dso.");
98
99 map_groups__init(&kmap_groups);
100 ret = __map_groups__create_kernel_maps(&kmap_groups, kmaps, kernel);
101 if (ret < 0)
102 pr_debug("Failed to create kernel maps.\n");
103
104out:
105 if (ret < 0)
106 pr_warning("Failed to init vmlinux path.\n");
107 return ret;
108}
109
110#ifdef DWARF_SUPPORT
111static int open_vmlinux(void)
112{
113 if (map__load(kmaps[MAP__FUNCTION], NULL) < 0) {
114 pr_debug("Failed to load kernel map.\n");
115 return -EINVAL;
116 }
117 pr_debug("Try to open %s\n", kmaps[MAP__FUNCTION]->dso->long_name);
118 return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY);
119}
120
121/* Convert trace point to probe point with debuginfo */
122static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
123 struct perf_probe_point *pp)
124{
125 struct symbol *sym;
126 int fd, ret = -ENOENT;
127
128 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
129 tp->symbol, NULL);
130 if (sym) {
131 fd = open_vmlinux();
132 if (fd >= 0) {
133 ret = find_perf_probe_point(fd,
134 sym->start + tp->offset, pp);
135 close(fd);
136 }
137 }
138 if (ret <= 0) {
139 pr_debug("Failed to find corresponding probes from "
140 "debuginfo. Use kprobe event information.\n");
141 pp->function = strdup(tp->symbol);
142 if (pp->function == NULL)
143 return -ENOMEM;
144 pp->offset = tp->offset;
145 }
146 pp->retprobe = tp->retprobe;
147
148 return 0;
149}
150
151/* Try to find perf_probe_event with debuginfo */
152static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
153 struct kprobe_trace_event **tevs)
154{
155 bool need_dwarf = perf_probe_event_need_dwarf(pev);
156 int fd, ntevs;
157
158 fd = open_vmlinux();
159 if (fd < 0) {
160 if (need_dwarf) {
161 pr_warning("Failed to open debuginfo file.\n");
162 return fd;
163 }
164 pr_debug("Could not open vmlinux. Try to use symbols.\n");
165 return 0;
166 }
167
168 /* Searching trace events corresponding to probe event */
169 ntevs = find_kprobe_trace_events(fd, pev, tevs);
170 close(fd);
171
172 if (ntevs > 0) { /* Succeeded to find trace events */
173 pr_debug("find %d kprobe_trace_events.\n", ntevs);
174 return ntevs;
175 }
176
177 if (ntevs == 0) { /* No error but failed to find probe point. */
178 pr_warning("Probe point '%s' not found.\n",
179 synthesize_perf_probe_point(&pev->point));
180 return -ENOENT;
181 }
182 /* Error path : ntevs < 0 */
183 if (need_dwarf) {
184 if (ntevs == -EBADF)
185 pr_warning("No dwarf info found in the vmlinux - "
186 "please rebuild with CONFIG_DEBUG_INFO=y.\n");
187 return ntevs;
188 }
189 pr_debug("An error occurred in debuginfo analysis."
190 " Try to use symbols.\n");
191 return 0;
192}
193
194#define LINEBUF_SIZE 256
195#define NR_ADDITIONAL_LINES 2
196
197static int show_one_line(FILE *fp, int l, bool skip, bool show_num)
198{
199 char buf[LINEBUF_SIZE];
200 const char *color = PERF_COLOR_BLUE;
201
202 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
203 goto error;
204 if (!skip) {
205 if (show_num)
206 fprintf(stdout, "%7d %s", l, buf);
207 else
208 color_fprintf(stdout, color, " %s", buf);
209 }
210
211 while (strlen(buf) == LINEBUF_SIZE - 1 &&
212 buf[LINEBUF_SIZE - 2] != '\n') {
213 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
214 goto error;
215 if (!skip) {
216 if (show_num)
217 fprintf(stdout, "%s", buf);
218 else
219 color_fprintf(stdout, color, "%s", buf);
220 }
221 }
222
223 return 0;
224error:
225 if (feof(fp))
226 pr_warning("Source file is shorter than expected.\n");
227 else
228 pr_warning("File read error: %s\n", strerror(errno));
229
230 return -1;
231}
232
233/*
234 * Show line-range always requires debuginfo to find source file and
235 * line number.
236 */
237int show_line_range(struct line_range *lr)
238{
239 int l = 1;
240 struct line_node *ln;
241 FILE *fp;
242 int fd, ret;
243
244 /* Search a line range */
245 ret = init_vmlinux();
246 if (ret < 0)
247 return ret;
248
249 fd = open_vmlinux();
250 if (fd < 0) {
251 pr_warning("Failed to open debuginfo file.\n");
252 return fd;
253 }
254
255 ret = find_line_range(fd, lr);
256 close(fd);
257 if (ret == 0) {
258 pr_warning("Specified source line is not found.\n");
259 return -ENOENT;
260 } else if (ret < 0) {
261 pr_warning("Debuginfo analysis failed. (%d)\n", ret);
262 return ret;
263 }
264
265 setup_pager();
266
267 if (lr->function)
268 fprintf(stdout, "<%s:%d>\n", lr->function,
269 lr->start - lr->offset);
270 else
271 fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
272
273 fp = fopen(lr->path, "r");
274 if (fp == NULL) {
275 pr_warning("Failed to open %s: %s\n", lr->path,
276 strerror(errno));
277 return -errno;
278 }
279 /* Skip to starting line number */
280 while (l < lr->start && ret >= 0)
281 ret = show_one_line(fp, l++, true, false);
282 if (ret < 0)
283 goto end;
284
285 list_for_each_entry(ln, &lr->line_list, list) {
286 while (ln->line > l && ret >= 0)
287 ret = show_one_line(fp, (l++) - lr->offset,
288 false, false);
289 if (ret >= 0)
290 ret = show_one_line(fp, (l++) - lr->offset,
291 false, true);
292 if (ret < 0)
293 goto end;
294 }
295
296 if (lr->end == INT_MAX)
297 lr->end = l + NR_ADDITIONAL_LINES;
298 while (l <= lr->end && !feof(fp) && ret >= 0)
299 ret = show_one_line(fp, (l++) - lr->offset, false, false);
300end:
301 fclose(fp);
302 return ret;
303}
304
305#else /* !DWARF_SUPPORT */
306
307static int convert_to_perf_probe_point(struct kprobe_trace_point *tp,
308 struct perf_probe_point *pp)
309{
310 pp->function = strdup(tp->symbol);
311 if (pp->function == NULL)
312 return -ENOMEM;
313 pp->offset = tp->offset;
314 pp->retprobe = tp->retprobe;
315
316 return 0;
317}
318
319static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev,
320 struct kprobe_trace_event **tevs __unused)
321{
322 if (perf_probe_event_need_dwarf(pev)) {
323 pr_warning("Debuginfo-analysis is not supported.\n");
324 return -ENOSYS;
325 }
326 return 0;
327}
328
329int show_line_range(struct line_range *lr __unused)
330{
331 pr_warning("Debuginfo-analysis is not supported.\n");
332 return -ENOSYS;
333}
334
335#endif
336
337int parse_line_range_desc(const char *arg, struct line_range *lr)
68{ 338{
69 const char *ptr; 339 const char *ptr;
70 char *tmp; 340 char *tmp;
@@ -75,29 +345,45 @@ void parse_line_range_desc(const char *arg, struct line_range *lr)
75 */ 345 */
76 ptr = strchr(arg, ':'); 346 ptr = strchr(arg, ':');
77 if (ptr) { 347 if (ptr) {
78 lr->start = (unsigned int)strtoul(ptr + 1, &tmp, 0); 348 lr->start = (int)strtoul(ptr + 1, &tmp, 0);
79 if (*tmp == '+') 349 if (*tmp == '+') {
80 lr->end = lr->start + (unsigned int)strtoul(tmp + 1, 350 lr->end = lr->start + (int)strtoul(tmp + 1, &tmp, 0);
81 &tmp, 0); 351 lr->end--; /*
82 else if (*tmp == '-') 352 * Adjust the number of lines here.
83 lr->end = (unsigned int)strtoul(tmp + 1, &tmp, 0); 353 * If the number of lines == 1, the
354 * the end of line should be equal to
355 * the start of line.
356 */
357 } else if (*tmp == '-')
358 lr->end = (int)strtoul(tmp + 1, &tmp, 0);
84 else 359 else
85 lr->end = 0; 360 lr->end = INT_MAX;
86 pr_debug("Line range is %u to %u\n", lr->start, lr->end); 361 pr_debug("Line range is %d to %d\n", lr->start, lr->end);
87 if (lr->end && lr->start > lr->end) 362 if (lr->start > lr->end) {
88 semantic_error("Start line must be smaller" 363 semantic_error("Start line must be smaller"
89 " than end line."); 364 " than end line.\n");
90 if (*tmp != '\0') 365 return -EINVAL;
91 semantic_error("Tailing with invalid character '%d'.", 366 }
367 if (*tmp != '\0') {
368 semantic_error("Tailing with invalid character '%d'.\n",
92 *tmp); 369 *tmp);
370 return -EINVAL;
371 }
93 tmp = strndup(arg, (ptr - arg)); 372 tmp = strndup(arg, (ptr - arg));
94 } else 373 } else {
95 tmp = strdup(arg); 374 tmp = strdup(arg);
375 lr->end = INT_MAX;
376 }
377
378 if (tmp == NULL)
379 return -ENOMEM;
96 380
97 if (strchr(tmp, '.')) 381 if (strchr(tmp, '.'))
98 lr->file = tmp; 382 lr->file = tmp;
99 else 383 else
100 lr->function = tmp; 384 lr->function = tmp;
385
386 return 0;
101} 387}
102 388
103/* Check the name is good for event/group */ 389/* Check the name is good for event/group */
@@ -113,8 +399,9 @@ static bool check_event_name(const char *name)
113} 399}
114 400
115/* Parse probepoint definition. */ 401/* Parse probepoint definition. */
116static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) 402static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
117{ 403{
404 struct perf_probe_point *pp = &pev->point;
118 char *ptr, *tmp; 405 char *ptr, *tmp;
119 char c, nc = 0; 406 char c, nc = 0;
120 /* 407 /*
@@ -129,13 +416,19 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
129 if (ptr && *ptr == '=') { /* Event name */ 416 if (ptr && *ptr == '=') { /* Event name */
130 *ptr = '\0'; 417 *ptr = '\0';
131 tmp = ptr + 1; 418 tmp = ptr + 1;
132 ptr = strchr(arg, ':'); 419 if (strchr(arg, ':')) {
133 if (ptr) /* Group name is not supported yet. */ 420 semantic_error("Group name is not supported yet.\n");
134 semantic_error("Group name is not supported yet."); 421 return -ENOTSUP;
135 if (!check_event_name(arg)) 422 }
423 if (!check_event_name(arg)) {
136 semantic_error("%s is bad for event name -it must " 424 semantic_error("%s is bad for event name -it must "
137 "follow C symbol-naming rule.", arg); 425 "follow C symbol-naming rule.\n", arg);
138 pp->event = strdup(arg); 426 return -EINVAL;
427 }
428 pev->event = strdup(arg);
429 if (pev->event == NULL)
430 return -ENOMEM;
431 pev->group = NULL;
139 arg = tmp; 432 arg = tmp;
140 } 433 }
141 434
@@ -145,12 +438,15 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
145 *ptr++ = '\0'; 438 *ptr++ = '\0';
146 } 439 }
147 440
441 tmp = strdup(arg);
442 if (tmp == NULL)
443 return -ENOMEM;
444
148 /* Check arg is function or file and copy it */ 445 /* Check arg is function or file and copy it */
149 if (strchr(arg, '.')) /* File */ 446 if (strchr(tmp, '.')) /* File */
150 pp->file = strdup(arg); 447 pp->file = tmp;
151 else /* Function */ 448 else /* Function */
152 pp->function = strdup(arg); 449 pp->function = tmp;
153 DIE_IF(pp->file == NULL && pp->function == NULL);
154 450
155 /* Parse other options */ 451 /* Parse other options */
156 while (ptr) { 452 while (ptr) {
@@ -158,6 +454,8 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
158 c = nc; 454 c = nc;
159 if (c == ';') { /* Lazy pattern must be the last part */ 455 if (c == ';') { /* Lazy pattern must be the last part */
160 pp->lazy_line = strdup(arg); 456 pp->lazy_line = strdup(arg);
457 if (pp->lazy_line == NULL)
458 return -ENOMEM;
161 break; 459 break;
162 } 460 }
163 ptr = strpbrk(arg, ";:+@%"); 461 ptr = strpbrk(arg, ";:+@%");
@@ -168,266 +466,658 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
168 switch (c) { 466 switch (c) {
169 case ':': /* Line number */ 467 case ':': /* Line number */
170 pp->line = strtoul(arg, &tmp, 0); 468 pp->line = strtoul(arg, &tmp, 0);
171 if (*tmp != '\0') 469 if (*tmp != '\0') {
172 semantic_error("There is non-digit char" 470 semantic_error("There is non-digit char"
173 " in line number."); 471 " in line number.\n");
472 return -EINVAL;
473 }
174 break; 474 break;
175 case '+': /* Byte offset from a symbol */ 475 case '+': /* Byte offset from a symbol */
176 pp->offset = strtoul(arg, &tmp, 0); 476 pp->offset = strtoul(arg, &tmp, 0);
177 if (*tmp != '\0') 477 if (*tmp != '\0') {
178 semantic_error("There is non-digit character" 478 semantic_error("There is non-digit character"
179 " in offset."); 479 " in offset.\n");
480 return -EINVAL;
481 }
180 break; 482 break;
181 case '@': /* File name */ 483 case '@': /* File name */
182 if (pp->file) 484 if (pp->file) {
183 semantic_error("SRC@SRC is not allowed."); 485 semantic_error("SRC@SRC is not allowed.\n");
486 return -EINVAL;
487 }
184 pp->file = strdup(arg); 488 pp->file = strdup(arg);
185 DIE_IF(pp->file == NULL); 489 if (pp->file == NULL)
490 return -ENOMEM;
186 break; 491 break;
187 case '%': /* Probe places */ 492 case '%': /* Probe places */
188 if (strcmp(arg, "return") == 0) { 493 if (strcmp(arg, "return") == 0) {
189 pp->retprobe = 1; 494 pp->retprobe = 1;
190 } else /* Others not supported yet */ 495 } else { /* Others not supported yet */
191 semantic_error("%%%s is not supported.", arg); 496 semantic_error("%%%s is not supported.\n", arg);
497 return -ENOTSUP;
498 }
192 break; 499 break;
193 default: 500 default: /* Buggy case */
194 DIE_IF("Program has a bug."); 501 pr_err("This program has a bug at %s:%d.\n",
502 __FILE__, __LINE__);
503 return -ENOTSUP;
195 break; 504 break;
196 } 505 }
197 } 506 }
198 507
199 /* Exclusion check */ 508 /* Exclusion check */
200 if (pp->lazy_line && pp->line) 509 if (pp->lazy_line && pp->line) {
201 semantic_error("Lazy pattern can't be used with line number."); 510 semantic_error("Lazy pattern can't be used with line number.");
511 return -EINVAL;
512 }
202 513
203 if (pp->lazy_line && pp->offset) 514 if (pp->lazy_line && pp->offset) {
204 semantic_error("Lazy pattern can't be used with offset."); 515 semantic_error("Lazy pattern can't be used with offset.");
516 return -EINVAL;
517 }
205 518
206 if (pp->line && pp->offset) 519 if (pp->line && pp->offset) {
207 semantic_error("Offset can't be used with line number."); 520 semantic_error("Offset can't be used with line number.");
521 return -EINVAL;
522 }
208 523
209 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) 524 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
210 semantic_error("File always requires line number or " 525 semantic_error("File always requires line number or "
211 "lazy pattern."); 526 "lazy pattern.");
527 return -EINVAL;
528 }
212 529
213 if (pp->offset && !pp->function) 530 if (pp->offset && !pp->function) {
214 semantic_error("Offset requires an entry function."); 531 semantic_error("Offset requires an entry function.");
532 return -EINVAL;
533 }
215 534
216 if (pp->retprobe && !pp->function) 535 if (pp->retprobe && !pp->function) {
217 semantic_error("Return probe requires an entry function."); 536 semantic_error("Return probe requires an entry function.");
537 return -EINVAL;
538 }
218 539
219 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) 540 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
220 semantic_error("Offset/Line/Lazy pattern can't be used with " 541 semantic_error("Offset/Line/Lazy pattern can't be used with "
221 "return probe."); 542 "return probe.");
543 return -EINVAL;
544 }
222 545
223 pr_debug("symbol:%s file:%s line:%d offset:%d return:%d lazy:%s\n", 546 pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
224 pp->function, pp->file, pp->line, pp->offset, pp->retprobe, 547 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
225 pp->lazy_line); 548 pp->lazy_line);
549 return 0;
226} 550}
227 551
228/* Parse perf-probe event definition */ 552/* Parse perf-probe event argument */
229void parse_perf_probe_event(const char *str, struct probe_point *pp, 553static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
230 bool *need_dwarf)
231{ 554{
232 char **argv; 555 char *tmp;
233 int argc, i; 556 struct perf_probe_arg_field **fieldp;
557
558 pr_debug("parsing arg: %s into ", str);
559
560 tmp = strchr(str, '=');
561 if (tmp) {
562 arg->name = strndup(str, tmp - str);
563 if (arg->name == NULL)
564 return -ENOMEM;
565 pr_debug("name:%s ", arg->name);
566 str = tmp + 1;
567 }
568
569 tmp = strchr(str, ':');
570 if (tmp) { /* Type setting */
571 *tmp = '\0';
572 arg->type = strdup(tmp + 1);
573 if (arg->type == NULL)
574 return -ENOMEM;
575 pr_debug("type:%s ", arg->type);
576 }
577
578 tmp = strpbrk(str, "-.");
579 if (!is_c_varname(str) || !tmp) {
580 /* A variable, register, symbol or special value */
581 arg->var = strdup(str);
582 if (arg->var == NULL)
583 return -ENOMEM;
584 pr_debug("%s\n", arg->var);
585 return 0;
586 }
234 587
235 *need_dwarf = false; 588 /* Structure fields */
589 arg->var = strndup(str, tmp - str);
590 if (arg->var == NULL)
591 return -ENOMEM;
592 pr_debug("%s, ", arg->var);
593 fieldp = &arg->field;
594
595 do {
596 *fieldp = zalloc(sizeof(struct perf_probe_arg_field));
597 if (*fieldp == NULL)
598 return -ENOMEM;
599 if (*tmp == '.') {
600 str = tmp + 1;
601 (*fieldp)->ref = false;
602 } else if (tmp[1] == '>') {
603 str = tmp + 2;
604 (*fieldp)->ref = true;
605 } else {
606 semantic_error("Argument parse error: %s\n", str);
607 return -EINVAL;
608 }
609
610 tmp = strpbrk(str, "-.");
611 if (tmp) {
612 (*fieldp)->name = strndup(str, tmp - str);
613 if ((*fieldp)->name == NULL)
614 return -ENOMEM;
615 pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
616 fieldp = &(*fieldp)->next;
617 }
618 } while (tmp);
619 (*fieldp)->name = strdup(str);
620 if ((*fieldp)->name == NULL)
621 return -ENOMEM;
622 pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
623
624 /* If no name is specified, set the last field name */
625 if (!arg->name) {
626 arg->name = strdup((*fieldp)->name);
627 if (arg->name == NULL)
628 return -ENOMEM;
629 }
630 return 0;
631}
236 632
237 argv = argv_split(str, &argc); 633/* Parse perf-probe event command */
238 if (!argv) 634int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
239 die("argv_split failed."); 635{
240 if (argc > MAX_PROBE_ARGS + 1) 636 char **argv;
241 semantic_error("Too many arguments"); 637 int argc, i, ret = 0;
242 638
639 argv = argv_split(cmd, &argc);
640 if (!argv) {
641 pr_debug("Failed to split arguments.\n");
642 return -ENOMEM;
643 }
644 if (argc - 1 > MAX_PROBE_ARGS) {
645 semantic_error("Too many probe arguments (%d).\n", argc - 1);
646 ret = -ERANGE;
647 goto out;
648 }
243 /* Parse probe point */ 649 /* Parse probe point */
244 parse_perf_probe_probepoint(argv[0], pp); 650 ret = parse_perf_probe_point(argv[0], pev);
245 if (pp->file || pp->line || pp->lazy_line) 651 if (ret < 0)
246 *need_dwarf = true; 652 goto out;
247 653
248 /* Copy arguments and ensure return probe has no C argument */ 654 /* Copy arguments and ensure return probe has no C argument */
249 pp->nr_args = argc - 1; 655 pev->nargs = argc - 1;
250 pp->args = zalloc(sizeof(char *) * pp->nr_args); 656 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
251 for (i = 0; i < pp->nr_args; i++) { 657 if (pev->args == NULL) {
252 pp->args[i] = strdup(argv[i + 1]); 658 ret = -ENOMEM;
253 if (!pp->args[i]) 659 goto out;
254 die("Failed to copy argument."); 660 }
255 if (is_c_varname(pp->args[i])) { 661 for (i = 0; i < pev->nargs && ret >= 0; i++) {
256 if (pp->retprobe) 662 ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
257 semantic_error("You can't specify local" 663 if (ret >= 0 &&
258 " variable for kretprobe"); 664 is_c_varname(pev->args[i].var) && pev->point.retprobe) {
259 *need_dwarf = true; 665 semantic_error("You can't specify local variable for"
666 " kretprobe.\n");
667 ret = -EINVAL;
260 } 668 }
261 } 669 }
262 670out:
263 argv_free(argv); 671 argv_free(argv);
672
673 return ret;
674}
675
676/* Return true if this perf_probe_event requires debuginfo */
677bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
678{
679 int i;
680
681 if (pev->point.file || pev->point.line || pev->point.lazy_line)
682 return true;
683
684 for (i = 0; i < pev->nargs; i++)
685 if (is_c_varname(pev->args[i].var))
686 return true;
687
688 return false;
264} 689}
265 690
266/* Parse kprobe_events event into struct probe_point */ 691/* Parse kprobe_events event into struct probe_point */
267void parse_trace_kprobe_event(const char *str, struct probe_point *pp) 692int parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
268{ 693{
694 struct kprobe_trace_point *tp = &tev->point;
269 char pr; 695 char pr;
270 char *p; 696 char *p;
271 int ret, i, argc; 697 int ret, i, argc;
272 char **argv; 698 char **argv;
273 699
274 pr_debug("Parsing kprobe_events: %s\n", str); 700 pr_debug("Parsing kprobe_events: %s\n", cmd);
275 argv = argv_split(str, &argc); 701 argv = argv_split(cmd, &argc);
276 if (!argv) 702 if (!argv) {
277 die("argv_split failed."); 703 pr_debug("Failed to split arguments.\n");
278 if (argc < 2) 704 return -ENOMEM;
279 semantic_error("Too less arguments."); 705 }
706 if (argc < 2) {
707 semantic_error("Too few probe arguments.\n");
708 ret = -ERANGE;
709 goto out;
710 }
280 711
281 /* Scan event and group name. */ 712 /* Scan event and group name. */
282 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", 713 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
283 &pr, (float *)(void *)&pp->group, 714 &pr, (float *)(void *)&tev->group,
284 (float *)(void *)&pp->event); 715 (float *)(void *)&tev->event);
285 if (ret != 3) 716 if (ret != 3) {
286 semantic_error("Failed to parse event name: %s", argv[0]); 717 semantic_error("Failed to parse event name: %s\n", argv[0]);
287 pr_debug("Group:%s Event:%s probe:%c\n", pp->group, pp->event, pr); 718 ret = -EINVAL;
719 goto out;
720 }
721 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
288 722
289 pp->retprobe = (pr == 'r'); 723 tp->retprobe = (pr == 'r');
290 724
291 /* Scan function name and offset */ 725 /* Scan function name and offset */
292 ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function, 726 ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol,
293 &pp->offset); 727 &tp->offset);
294 if (ret == 1) 728 if (ret == 1)
295 pp->offset = 0; 729 tp->offset = 0;
296 730
297 /* kprobe_events doesn't have this information */ 731 tev->nargs = argc - 2;
298 pp->line = 0; 732 tev->args = zalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
299 pp->file = NULL; 733 if (tev->args == NULL) {
300 734 ret = -ENOMEM;
301 pp->nr_args = argc - 2; 735 goto out;
302 pp->args = zalloc(sizeof(char *) * pp->nr_args); 736 }
303 for (i = 0; i < pp->nr_args; i++) { 737 for (i = 0; i < tev->nargs; i++) {
304 p = strchr(argv[i + 2], '='); 738 p = strchr(argv[i + 2], '=');
305 if (p) /* We don't need which register is assigned. */ 739 if (p) /* We don't need which register is assigned. */
306 *p = '\0'; 740 *p++ = '\0';
307 pp->args[i] = strdup(argv[i + 2]); 741 else
308 if (!pp->args[i]) 742 p = argv[i + 2];
309 die("Failed to copy argument."); 743 tev->args[i].name = strdup(argv[i + 2]);
744 /* TODO: parse regs and offset */
745 tev->args[i].value = strdup(p);
746 if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
747 ret = -ENOMEM;
748 goto out;
749 }
310 } 750 }
311 751 ret = 0;
752out:
312 argv_free(argv); 753 argv_free(argv);
754 return ret;
313} 755}
314 756
315/* Synthesize only probe point (not argument) */ 757/* Compose only probe arg */
316int synthesize_perf_probe_point(struct probe_point *pp) 758int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
317{ 759{
318 char *buf; 760 struct perf_probe_arg_field *field = pa->field;
319 char offs[64] = "", line[64] = "";
320 int ret; 761 int ret;
762 char *tmp = buf;
321 763
322 pp->probes[0] = buf = zalloc(MAX_CMDLEN); 764 if (pa->name && pa->var)
323 pp->found = 1; 765 ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var);
324 if (!buf) 766 else
325 die("Failed to allocate memory by zalloc."); 767 ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var);
768 if (ret <= 0)
769 goto error;
770 tmp += ret;
771 len -= ret;
772
773 while (field) {
774 ret = e_snprintf(tmp, len, "%s%s", field->ref ? "->" : ".",
775 field->name);
776 if (ret <= 0)
777 goto error;
778 tmp += ret;
779 len -= ret;
780 field = field->next;
781 }
782
783 if (pa->type) {
784 ret = e_snprintf(tmp, len, ":%s", pa->type);
785 if (ret <= 0)
786 goto error;
787 tmp += ret;
788 len -= ret;
789 }
790
791 return tmp - buf;
792error:
793 pr_debug("Failed to synthesize perf probe argument: %s",
794 strerror(-ret));
795 return ret;
796}
797
798/* Compose only probe point (not argument) */
799static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
800{
801 char *buf, *tmp;
802 char offs[32] = "", line[32] = "", file[32] = "";
803 int ret, len;
804
805 buf = zalloc(MAX_CMDLEN);
806 if (buf == NULL) {
807 ret = -ENOMEM;
808 goto error;
809 }
326 if (pp->offset) { 810 if (pp->offset) {
327 ret = e_snprintf(offs, 64, "+%d", pp->offset); 811 ret = e_snprintf(offs, 32, "+%lu", pp->offset);
328 if (ret <= 0) 812 if (ret <= 0)
329 goto error; 813 goto error;
330 } 814 }
331 if (pp->line) { 815 if (pp->line) {
332 ret = e_snprintf(line, 64, ":%d", pp->line); 816 ret = e_snprintf(line, 32, ":%d", pp->line);
817 if (ret <= 0)
818 goto error;
819 }
820 if (pp->file) {
821 len = strlen(pp->file) - 31;
822 if (len < 0)
823 len = 0;
824 tmp = strchr(pp->file + len, '/');
825 if (!tmp)
826 tmp = pp->file + len;
827 ret = e_snprintf(file, 32, "@%s", tmp + 1);
333 if (ret <= 0) 828 if (ret <= 0)
334 goto error; 829 goto error;
335 } 830 }
336 831
337 if (pp->function) 832 if (pp->function)
338 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->function, 833 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
339 offs, pp->retprobe ? "%return" : "", line); 834 offs, pp->retprobe ? "%return" : "", line,
835 file);
340 else 836 else
341 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line); 837 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
342 if (ret <= 0) { 838 if (ret <= 0)
839 goto error;
840
841 return buf;
343error: 842error:
344 free(pp->probes[0]); 843 pr_debug("Failed to synthesize perf probe point: %s",
345 pp->probes[0] = NULL; 844 strerror(-ret));
346 pp->found = 0; 845 if (buf)
347 } 846 free(buf);
348 return ret; 847 return NULL;
349} 848}
350 849
351int synthesize_perf_probe_event(struct probe_point *pp) 850#if 0
851char *synthesize_perf_probe_command(struct perf_probe_event *pev)
352{ 852{
353 char *buf; 853 char *buf;
354 int i, len, ret; 854 int i, len, ret;
355 855
356 len = synthesize_perf_probe_point(pp); 856 buf = synthesize_perf_probe_point(&pev->point);
357 if (len < 0) 857 if (!buf)
358 return 0; 858 return NULL;
359 859
360 buf = pp->probes[0]; 860 len = strlen(buf);
361 for (i = 0; i < pp->nr_args; i++) { 861 for (i = 0; i < pev->nargs; i++) {
362 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", 862 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
363 pp->args[i]); 863 pev->args[i].name);
364 if (ret <= 0) 864 if (ret <= 0) {
365 goto error; 865 free(buf);
866 return NULL;
867 }
366 len += ret; 868 len += ret;
367 } 869 }
368 pp->found = 1;
369 870
370 return pp->found; 871 return buf;
371error: 872}
372 free(pp->probes[0]); 873#endif
373 pp->probes[0] = NULL; 874
875static int __synthesize_kprobe_trace_arg_ref(struct kprobe_trace_arg_ref *ref,
876 char **buf, size_t *buflen,
877 int depth)
878{
879 int ret;
880 if (ref->next) {
881 depth = __synthesize_kprobe_trace_arg_ref(ref->next, buf,
882 buflen, depth + 1);
883 if (depth < 0)
884 goto out;
885 }
886
887 ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset);
888 if (ret < 0)
889 depth = ret;
890 else {
891 *buf += ret;
892 *buflen -= ret;
893 }
894out:
895 return depth;
374 896
375 return ret;
376} 897}
377 898
378int synthesize_trace_kprobe_event(struct probe_point *pp) 899static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg,
900 char *buf, size_t buflen)
379{ 901{
902 int ret, depth = 0;
903 char *tmp = buf;
904
905 /* Argument name or separator */
906 if (arg->name)
907 ret = e_snprintf(buf, buflen, " %s=", arg->name);
908 else
909 ret = e_snprintf(buf, buflen, " ");
910 if (ret < 0)
911 return ret;
912 buf += ret;
913 buflen -= ret;
914
915 /* Dereferencing arguments */
916 if (arg->ref) {
917 depth = __synthesize_kprobe_trace_arg_ref(arg->ref, &buf,
918 &buflen, 1);
919 if (depth < 0)
920 return depth;
921 }
922
923 /* Print argument value */
924 ret = e_snprintf(buf, buflen, "%s", arg->value);
925 if (ret < 0)
926 return ret;
927 buf += ret;
928 buflen -= ret;
929
930 /* Closing */
931 while (depth--) {
932 ret = e_snprintf(buf, buflen, ")");
933 if (ret < 0)
934 return ret;
935 buf += ret;
936 buflen -= ret;
937 }
938 /* Print argument type */
939 if (arg->type) {
940 ret = e_snprintf(buf, buflen, ":%s", arg->type);
941 if (ret <= 0)
942 return ret;
943 buf += ret;
944 }
945
946 return buf - tmp;
947}
948
949char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev)
950{
951 struct kprobe_trace_point *tp = &tev->point;
380 char *buf; 952 char *buf;
381 int i, len, ret; 953 int i, len, ret;
382 954
383 pp->probes[0] = buf = zalloc(MAX_CMDLEN); 955 buf = zalloc(MAX_CMDLEN);
384 if (!buf) 956 if (buf == NULL)
385 die("Failed to allocate memory by zalloc."); 957 return NULL;
386 ret = e_snprintf(buf, MAX_CMDLEN, "%s+%d", pp->function, pp->offset); 958
387 if (ret <= 0) 959 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu",
960 tp->retprobe ? 'r' : 'p',
961 tev->group, tev->event,
962 tp->symbol, tp->offset);
963 if (len <= 0)
388 goto error; 964 goto error;
389 len = ret;
390 965
391 for (i = 0; i < pp->nr_args; i++) { 966 for (i = 0; i < tev->nargs; i++) {
392 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", 967 ret = synthesize_kprobe_trace_arg(&tev->args[i], buf + len,
393 pp->args[i]); 968 MAX_CMDLEN - len);
394 if (ret <= 0) 969 if (ret <= 0)
395 goto error; 970 goto error;
396 len += ret; 971 len += ret;
397 } 972 }
398 pp->found = 1;
399 973
400 return pp->found; 974 return buf;
401error: 975error:
402 free(pp->probes[0]); 976 free(buf);
403 pp->probes[0] = NULL; 977 return NULL;
978}
979
980int convert_to_perf_probe_event(struct kprobe_trace_event *tev,
981 struct perf_probe_event *pev)
982{
983 char buf[64] = "";
984 int i, ret;
985
986 /* Convert event/group name */
987 pev->event = strdup(tev->event);
988 pev->group = strdup(tev->group);
989 if (pev->event == NULL || pev->group == NULL)
990 return -ENOMEM;
991
992 /* Convert trace_point to probe_point */
993 ret = convert_to_perf_probe_point(&tev->point, &pev->point);
994 if (ret < 0)
995 return ret;
996
997 /* Convert trace_arg to probe_arg */
998 pev->nargs = tev->nargs;
999 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
1000 if (pev->args == NULL)
1001 return -ENOMEM;
1002 for (i = 0; i < tev->nargs && ret >= 0; i++) {
1003 if (tev->args[i].name)
1004 pev->args[i].name = strdup(tev->args[i].name);
1005 else {
1006 ret = synthesize_kprobe_trace_arg(&tev->args[i],
1007 buf, 64);
1008 pev->args[i].name = strdup(buf);
1009 }
1010 if (pev->args[i].name == NULL && ret >= 0)
1011 ret = -ENOMEM;
1012 }
1013
1014 if (ret < 0)
1015 clear_perf_probe_event(pev);
404 1016
405 return ret; 1017 return ret;
406} 1018}
407 1019
408static int open_kprobe_events(int flags, int mode) 1020void clear_perf_probe_event(struct perf_probe_event *pev)
1021{
1022 struct perf_probe_point *pp = &pev->point;
1023 struct perf_probe_arg_field *field, *next;
1024 int i;
1025
1026 if (pev->event)
1027 free(pev->event);
1028 if (pev->group)
1029 free(pev->group);
1030 if (pp->file)
1031 free(pp->file);
1032 if (pp->function)
1033 free(pp->function);
1034 if (pp->lazy_line)
1035 free(pp->lazy_line);
1036 for (i = 0; i < pev->nargs; i++) {
1037 if (pev->args[i].name)
1038 free(pev->args[i].name);
1039 if (pev->args[i].var)
1040 free(pev->args[i].var);
1041 if (pev->args[i].type)
1042 free(pev->args[i].type);
1043 field = pev->args[i].field;
1044 while (field) {
1045 next = field->next;
1046 if (field->name)
1047 free(field->name);
1048 free(field);
1049 field = next;
1050 }
1051 }
1052 if (pev->args)
1053 free(pev->args);
1054 memset(pev, 0, sizeof(*pev));
1055}
1056
1057void clear_kprobe_trace_event(struct kprobe_trace_event *tev)
1058{
1059 struct kprobe_trace_arg_ref *ref, *next;
1060 int i;
1061
1062 if (tev->event)
1063 free(tev->event);
1064 if (tev->group)
1065 free(tev->group);
1066 if (tev->point.symbol)
1067 free(tev->point.symbol);
1068 for (i = 0; i < tev->nargs; i++) {
1069 if (tev->args[i].name)
1070 free(tev->args[i].name);
1071 if (tev->args[i].value)
1072 free(tev->args[i].value);
1073 if (tev->args[i].type)
1074 free(tev->args[i].type);
1075 ref = tev->args[i].ref;
1076 while (ref) {
1077 next = ref->next;
1078 free(ref);
1079 ref = next;
1080 }
1081 }
1082 if (tev->args)
1083 free(tev->args);
1084 memset(tev, 0, sizeof(*tev));
1085}
1086
1087static int open_kprobe_events(bool readwrite)
409{ 1088{
410 char buf[PATH_MAX]; 1089 char buf[PATH_MAX];
1090 const char *__debugfs;
411 int ret; 1091 int ret;
412 1092
413 ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path); 1093 __debugfs = debugfs_find_mountpoint();
414 if (ret < 0) 1094 if (__debugfs == NULL) {
415 die("Failed to make kprobe_events path."); 1095 pr_warning("Debugfs is not mounted.\n");
1096 return -ENOENT;
1097 }
1098
1099 ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs);
1100 if (ret >= 0) {
1101 pr_debug("Opening %s write=%d\n", buf, readwrite);
1102 if (readwrite && !probe_event_dry_run)
1103 ret = open(buf, O_RDWR, O_APPEND);
1104 else
1105 ret = open(buf, O_RDONLY, 0);
1106 }
416 1107
417 ret = open(buf, flags, mode);
418 if (ret < 0) { 1108 if (ret < 0) {
419 if (errno == ENOENT) 1109 if (errno == ENOENT)
420 die("kprobe_events file does not exist -" 1110 pr_warning("kprobe_events file does not exist - please"
421 " please rebuild with CONFIG_KPROBE_EVENT."); 1111 " rebuild kernel with CONFIG_KPROBE_EVENT.\n");
422 else 1112 else
423 die("Could not open kprobe_events file: %s", 1113 pr_warning("Failed to open kprobe_events file: %s\n",
424 strerror(errno)); 1114 strerror(errno));
425 } 1115 }
426 return ret; 1116 return ret;
427} 1117}
428 1118
429/* Get raw string list of current kprobe_events */ 1119/* Get raw string list of current kprobe_events */
430static struct strlist *get_trace_kprobe_event_rawlist(int fd) 1120static struct strlist *get_kprobe_trace_command_rawlist(int fd)
431{ 1121{
432 int ret, idx; 1122 int ret, idx;
433 FILE *fp; 1123 FILE *fp;
@@ -447,271 +1137,485 @@ static struct strlist *get_trace_kprobe_event_rawlist(int fd)
447 if (p[idx] == '\n') 1137 if (p[idx] == '\n')
448 p[idx] = '\0'; 1138 p[idx] = '\0';
449 ret = strlist__add(sl, buf); 1139 ret = strlist__add(sl, buf);
450 if (ret < 0) 1140 if (ret < 0) {
451 die("strlist__add failed: %s", strerror(-ret)); 1141 pr_debug("strlist__add failed: %s\n", strerror(-ret));
1142 strlist__delete(sl);
1143 return NULL;
1144 }
452 } 1145 }
453 fclose(fp); 1146 fclose(fp);
454 1147
455 return sl; 1148 return sl;
456} 1149}
457 1150
458/* Free and zero clear probe_point */
459static void clear_probe_point(struct probe_point *pp)
460{
461 int i;
462
463 if (pp->event)
464 free(pp->event);
465 if (pp->group)
466 free(pp->group);
467 if (pp->function)
468 free(pp->function);
469 if (pp->file)
470 free(pp->file);
471 if (pp->lazy_line)
472 free(pp->lazy_line);
473 for (i = 0; i < pp->nr_args; i++)
474 free(pp->args[i]);
475 if (pp->args)
476 free(pp->args);
477 for (i = 0; i < pp->found; i++)
478 free(pp->probes[i]);
479 memset(pp, 0, sizeof(*pp));
480}
481
482/* Show an event */ 1151/* Show an event */
483static void show_perf_probe_event(const char *event, const char *place, 1152static int show_perf_probe_event(struct perf_probe_event *pev)
484 struct probe_point *pp)
485{ 1153{
486 int i, ret; 1154 int i, ret;
487 char buf[128]; 1155 char buf[128];
1156 char *place;
488 1157
489 ret = e_snprintf(buf, 128, "%s:%s", pp->group, event); 1158 /* Synthesize only event probe point */
1159 place = synthesize_perf_probe_point(&pev->point);
1160 if (!place)
1161 return -EINVAL;
1162
1163 ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
490 if (ret < 0) 1164 if (ret < 0)
491 die("Failed to copy event: %s", strerror(-ret)); 1165 return ret;
492 printf(" %-40s (on %s", buf, place); 1166
1167 printf(" %-20s (on %s", buf, place);
493 1168
494 if (pp->nr_args > 0) { 1169 if (pev->nargs > 0) {
495 printf(" with"); 1170 printf(" with");
496 for (i = 0; i < pp->nr_args; i++) 1171 for (i = 0; i < pev->nargs; i++) {
497 printf(" %s", pp->args[i]); 1172 ret = synthesize_perf_probe_arg(&pev->args[i],
1173 buf, 128);
1174 if (ret < 0)
1175 break;
1176 printf(" %s", buf);
1177 }
498 } 1178 }
499 printf(")\n"); 1179 printf(")\n");
1180 free(place);
1181 return ret;
500} 1182}
501 1183
502/* List up current perf-probe events */ 1184/* List up current perf-probe events */
503void show_perf_probe_events(void) 1185int show_perf_probe_events(void)
504{ 1186{
505 int fd; 1187 int fd, ret;
506 struct probe_point pp; 1188 struct kprobe_trace_event tev;
1189 struct perf_probe_event pev;
507 struct strlist *rawlist; 1190 struct strlist *rawlist;
508 struct str_node *ent; 1191 struct str_node *ent;
509 1192
510 setup_pager(); 1193 setup_pager();
511 memset(&pp, 0, sizeof(pp)); 1194 ret = init_vmlinux();
1195 if (ret < 0)
1196 return ret;
1197
1198 memset(&tev, 0, sizeof(tev));
1199 memset(&pev, 0, sizeof(pev));
1200
1201 fd = open_kprobe_events(false);
1202 if (fd < 0)
1203 return fd;
512 1204
513 fd = open_kprobe_events(O_RDONLY, 0); 1205 rawlist = get_kprobe_trace_command_rawlist(fd);
514 rawlist = get_trace_kprobe_event_rawlist(fd);
515 close(fd); 1206 close(fd);
1207 if (!rawlist)
1208 return -ENOENT;
516 1209
517 strlist__for_each(ent, rawlist) { 1210 strlist__for_each(ent, rawlist) {
518 parse_trace_kprobe_event(ent->s, &pp); 1211 ret = parse_kprobe_trace_command(ent->s, &tev);
519 /* Synthesize only event probe point */ 1212 if (ret >= 0) {
520 synthesize_perf_probe_point(&pp); 1213 ret = convert_to_perf_probe_event(&tev, &pev);
521 /* Show an event */ 1214 if (ret >= 0)
522 show_perf_probe_event(pp.event, pp.probes[0], &pp); 1215 ret = show_perf_probe_event(&pev);
523 clear_probe_point(&pp); 1216 }
1217 clear_perf_probe_event(&pev);
1218 clear_kprobe_trace_event(&tev);
1219 if (ret < 0)
1220 break;
524 } 1221 }
525
526 strlist__delete(rawlist); 1222 strlist__delete(rawlist);
1223
1224 return ret;
527} 1225}
528 1226
529/* Get current perf-probe event names */ 1227/* Get current perf-probe event names */
530static struct strlist *get_perf_event_names(int fd, bool include_group) 1228static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group)
531{ 1229{
532 char buf[128]; 1230 char buf[128];
533 struct strlist *sl, *rawlist; 1231 struct strlist *sl, *rawlist;
534 struct str_node *ent; 1232 struct str_node *ent;
535 struct probe_point pp; 1233 struct kprobe_trace_event tev;
1234 int ret = 0;
536 1235
537 memset(&pp, 0, sizeof(pp)); 1236 memset(&tev, 0, sizeof(tev));
538 rawlist = get_trace_kprobe_event_rawlist(fd);
539 1237
1238 rawlist = get_kprobe_trace_command_rawlist(fd);
540 sl = strlist__new(true, NULL); 1239 sl = strlist__new(true, NULL);
541 strlist__for_each(ent, rawlist) { 1240 strlist__for_each(ent, rawlist) {
542 parse_trace_kprobe_event(ent->s, &pp); 1241 ret = parse_kprobe_trace_command(ent->s, &tev);
1242 if (ret < 0)
1243 break;
543 if (include_group) { 1244 if (include_group) {
544 if (e_snprintf(buf, 128, "%s:%s", pp.group, 1245 ret = e_snprintf(buf, 128, "%s:%s", tev.group,
545 pp.event) < 0) 1246 tev.event);
546 die("Failed to copy group:event name."); 1247 if (ret >= 0)
547 strlist__add(sl, buf); 1248 ret = strlist__add(sl, buf);
548 } else 1249 } else
549 strlist__add(sl, pp.event); 1250 ret = strlist__add(sl, tev.event);
550 clear_probe_point(&pp); 1251 clear_kprobe_trace_event(&tev);
1252 if (ret < 0)
1253 break;
551 } 1254 }
552
553 strlist__delete(rawlist); 1255 strlist__delete(rawlist);
554 1256
1257 if (ret < 0) {
1258 strlist__delete(sl);
1259 return NULL;
1260 }
555 return sl; 1261 return sl;
556} 1262}
557 1263
558static void write_trace_kprobe_event(int fd, const char *buf) 1264static int write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev)
559{ 1265{
560 int ret; 1266 int ret;
1267 char *buf = synthesize_kprobe_trace_command(tev);
1268
1269 if (!buf) {
1270 pr_debug("Failed to synthesize kprobe trace event.\n");
1271 return -EINVAL;
1272 }
561 1273
562 pr_debug("Writing event: %s\n", buf); 1274 pr_debug("Writing event: %s\n", buf);
563 ret = write(fd, buf, strlen(buf)); 1275 if (!probe_event_dry_run) {
564 if (ret <= 0) 1276 ret = write(fd, buf, strlen(buf));
565 die("Failed to write event: %s", strerror(errno)); 1277 if (ret <= 0)
1278 pr_warning("Failed to write event: %s\n",
1279 strerror(errno));
1280 }
1281 free(buf);
1282 return ret;
566} 1283}
567 1284
568static void get_new_event_name(char *buf, size_t len, const char *base, 1285static int get_new_event_name(char *buf, size_t len, const char *base,
569 struct strlist *namelist, bool allow_suffix) 1286 struct strlist *namelist, bool allow_suffix)
570{ 1287{
571 int i, ret; 1288 int i, ret;
572 1289
573 /* Try no suffix */ 1290 /* Try no suffix */
574 ret = e_snprintf(buf, len, "%s", base); 1291 ret = e_snprintf(buf, len, "%s", base);
575 if (ret < 0) 1292 if (ret < 0) {
576 die("snprintf() failed: %s", strerror(-ret)); 1293 pr_debug("snprintf() failed: %s\n", strerror(-ret));
1294 return ret;
1295 }
577 if (!strlist__has_entry(namelist, buf)) 1296 if (!strlist__has_entry(namelist, buf))
578 return; 1297 return 0;
579 1298
580 if (!allow_suffix) { 1299 if (!allow_suffix) {
581 pr_warning("Error: event \"%s\" already exists. " 1300 pr_warning("Error: event \"%s\" already exists. "
582 "(Use -f to force duplicates.)\n", base); 1301 "(Use -f to force duplicates.)\n", base);
583 die("Can't add new event."); 1302 return -EEXIST;
584 } 1303 }
585 1304
586 /* Try to add suffix */ 1305 /* Try to add suffix */
587 for (i = 1; i < MAX_EVENT_INDEX; i++) { 1306 for (i = 1; i < MAX_EVENT_INDEX; i++) {
588 ret = e_snprintf(buf, len, "%s_%d", base, i); 1307 ret = e_snprintf(buf, len, "%s_%d", base, i);
589 if (ret < 0) 1308 if (ret < 0) {
590 die("snprintf() failed: %s", strerror(-ret)); 1309 pr_debug("snprintf() failed: %s\n", strerror(-ret));
1310 return ret;
1311 }
591 if (!strlist__has_entry(namelist, buf)) 1312 if (!strlist__has_entry(namelist, buf))
592 break; 1313 break;
593 } 1314 }
594 if (i == MAX_EVENT_INDEX) 1315 if (i == MAX_EVENT_INDEX) {
595 die("Too many events are on the same function."); 1316 pr_warning("Too many events are on the same function.\n");
1317 ret = -ERANGE;
1318 }
1319
1320 return ret;
596} 1321}
597 1322
598void add_trace_kprobe_events(struct probe_point *probes, int nr_probes, 1323static int __add_kprobe_trace_events(struct perf_probe_event *pev,
599 bool force_add) 1324 struct kprobe_trace_event *tevs,
1325 int ntevs, bool allow_suffix)
600{ 1326{
601 int i, j, fd; 1327 int i, fd, ret;
602 struct probe_point *pp; 1328 struct kprobe_trace_event *tev = NULL;
603 char buf[MAX_CMDLEN]; 1329 char buf[64];
604 char event[64]; 1330 const char *event, *group;
605 struct strlist *namelist; 1331 struct strlist *namelist;
606 bool allow_suffix;
607 1332
608 fd = open_kprobe_events(O_RDWR, O_APPEND); 1333 fd = open_kprobe_events(true);
1334 if (fd < 0)
1335 return fd;
609 /* Get current event names */ 1336 /* Get current event names */
610 namelist = get_perf_event_names(fd, false); 1337 namelist = get_kprobe_trace_event_names(fd, false);
611 1338 if (!namelist) {
612 for (j = 0; j < nr_probes; j++) { 1339 pr_debug("Failed to get current event list.\n");
613 pp = probes + j; 1340 return -EIO;
614 if (!pp->event) 1341 }
615 pp->event = strdup(pp->function); 1342
616 if (!pp->group) 1343 ret = 0;
617 pp->group = strdup(PERFPROBE_GROUP); 1344 printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":");
618 DIE_IF(!pp->event || !pp->group); 1345 for (i = 0; i < ntevs; i++) {
619 /* If force_add is true, suffix search is allowed */ 1346 tev = &tevs[i];
620 allow_suffix = force_add; 1347 if (pev->event)
621 for (i = 0; i < pp->found; i++) { 1348 event = pev->event;
622 /* Get an unused new event name */ 1349 else
623 get_new_event_name(event, 64, pp->event, namelist, 1350 if (pev->point.function)
624 allow_suffix); 1351 event = pev->point.function;
625 snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n", 1352 else
626 pp->retprobe ? 'r' : 'p', 1353 event = tev->point.symbol;
627 pp->group, event, 1354 if (pev->group)
628 pp->probes[i]); 1355 group = pev->group;
629 write_trace_kprobe_event(fd, buf); 1356 else
630 printf("Added new event:\n"); 1357 group = PERFPROBE_GROUP;
631 /* Get the first parameter (probe-point) */ 1358
632 sscanf(pp->probes[i], "%s", buf); 1359 /* Get an unused new event name */
633 show_perf_probe_event(event, buf, pp); 1360 ret = get_new_event_name(buf, 64, event,
634 /* Add added event name to namelist */ 1361 namelist, allow_suffix);
635 strlist__add(namelist, event); 1362 if (ret < 0)
636 /* 1363 break;
637 * Probes after the first probe which comes from same 1364 event = buf;
638 * user input are always allowed to add suffix, because 1365
639 * there might be several addresses corresponding to 1366 tev->event = strdup(event);
640 * one code line. 1367 tev->group = strdup(group);
641 */ 1368 if (tev->event == NULL || tev->group == NULL) {
642 allow_suffix = true; 1369 ret = -ENOMEM;
1370 break;
643 } 1371 }
1372 ret = write_kprobe_trace_event(fd, tev);
1373 if (ret < 0)
1374 break;
1375 /* Add added event name to namelist */
1376 strlist__add(namelist, event);
1377
1378 /* Trick here - save current event/group */
1379 event = pev->event;
1380 group = pev->group;
1381 pev->event = tev->event;
1382 pev->group = tev->group;
1383 show_perf_probe_event(pev);
1384 /* Trick here - restore current event/group */
1385 pev->event = (char *)event;
1386 pev->group = (char *)group;
1387
1388 /*
1389 * Probes after the first probe which comes from same
1390 * user input are always allowed to add suffix, because
1391 * there might be several addresses corresponding to
1392 * one code line.
1393 */
1394 allow_suffix = true;
1395 }
1396
1397 if (ret >= 0) {
1398 /* Show how to use the event. */
1399 printf("\nYou can now use it on all perf tools, such as:\n\n");
1400 printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
1401 tev->event);
644 } 1402 }
645 /* Show how to use the event. */
646 printf("\nYou can now use it on all perf tools, such as:\n\n");
647 printf("\tperf record -e %s:%s -a sleep 1\n\n", PERFPROBE_GROUP, event);
648 1403
649 strlist__delete(namelist); 1404 strlist__delete(namelist);
650 close(fd); 1405 close(fd);
1406 return ret;
651} 1407}
652 1408
653static void __del_trace_kprobe_event(int fd, struct str_node *ent) 1409static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
1410 struct kprobe_trace_event **tevs)
1411{
1412 struct symbol *sym;
1413 int ret = 0, i;
1414 struct kprobe_trace_event *tev;
1415
1416 /* Convert perf_probe_event with debuginfo */
1417 ret = try_to_find_kprobe_trace_events(pev, tevs);
1418 if (ret != 0)
1419 return ret;
1420
1421 /* Allocate trace event buffer */
1422 tev = *tevs = zalloc(sizeof(struct kprobe_trace_event));
1423 if (tev == NULL)
1424 return -ENOMEM;
1425
1426 /* Copy parameters */
1427 tev->point.symbol = strdup(pev->point.function);
1428 if (tev->point.symbol == NULL) {
1429 ret = -ENOMEM;
1430 goto error;
1431 }
1432 tev->point.offset = pev->point.offset;
1433 tev->nargs = pev->nargs;
1434 if (tev->nargs) {
1435 tev->args = zalloc(sizeof(struct kprobe_trace_arg)
1436 * tev->nargs);
1437 if (tev->args == NULL) {
1438 ret = -ENOMEM;
1439 goto error;
1440 }
1441 for (i = 0; i < tev->nargs; i++) {
1442 if (pev->args[i].name) {
1443 tev->args[i].name = strdup(pev->args[i].name);
1444 if (tev->args[i].name == NULL) {
1445 ret = -ENOMEM;
1446 goto error;
1447 }
1448 }
1449 tev->args[i].value = strdup(pev->args[i].var);
1450 if (tev->args[i].value == NULL) {
1451 ret = -ENOMEM;
1452 goto error;
1453 }
1454 if (pev->args[i].type) {
1455 tev->args[i].type = strdup(pev->args[i].type);
1456 if (tev->args[i].type == NULL) {
1457 ret = -ENOMEM;
1458 goto error;
1459 }
1460 }
1461 }
1462 }
1463
1464 /* Currently just checking function name from symbol map */
1465 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
1466 tev->point.symbol, NULL);
1467 if (!sym) {
1468 pr_warning("Kernel symbol \'%s\' not found.\n",
1469 tev->point.symbol);
1470 ret = -ENOENT;
1471 goto error;
1472 }
1473
1474 return 1;
1475error:
1476 clear_kprobe_trace_event(tev);
1477 free(tev);
1478 *tevs = NULL;
1479 return ret;
1480}
1481
1482struct __event_package {
1483 struct perf_probe_event *pev;
1484 struct kprobe_trace_event *tevs;
1485 int ntevs;
1486};
1487
1488int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
1489 bool force_add)
1490{
1491 int i, j, ret;
1492 struct __event_package *pkgs;
1493
1494 pkgs = zalloc(sizeof(struct __event_package) * npevs);
1495 if (pkgs == NULL)
1496 return -ENOMEM;
1497
1498 /* Init vmlinux path */
1499 ret = init_vmlinux();
1500 if (ret < 0)
1501 return ret;
1502
1503 /* Loop 1: convert all events */
1504 for (i = 0; i < npevs; i++) {
1505 pkgs[i].pev = &pevs[i];
1506 /* Convert with or without debuginfo */
1507 ret = convert_to_kprobe_trace_events(pkgs[i].pev,
1508 &pkgs[i].tevs);
1509 if (ret < 0)
1510 goto end;
1511 pkgs[i].ntevs = ret;
1512 }
1513
1514 /* Loop 2: add all events */
1515 for (i = 0; i < npevs && ret >= 0; i++)
1516 ret = __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs,
1517 pkgs[i].ntevs, force_add);
1518end:
1519 /* Loop 3: cleanup trace events */
1520 for (i = 0; i < npevs; i++)
1521 for (j = 0; j < pkgs[i].ntevs; j++)
1522 clear_kprobe_trace_event(&pkgs[i].tevs[j]);
1523
1524 return ret;
1525}
1526
1527static int __del_trace_kprobe_event(int fd, struct str_node *ent)
654{ 1528{
655 char *p; 1529 char *p;
656 char buf[128]; 1530 char buf[128];
1531 int ret;
657 1532
658 /* Convert from perf-probe event to trace-kprobe event */ 1533 /* Convert from perf-probe event to trace-kprobe event */
659 if (e_snprintf(buf, 128, "-:%s", ent->s) < 0) 1534 ret = e_snprintf(buf, 128, "-:%s", ent->s);
660 die("Failed to copy event."); 1535 if (ret < 0)
1536 goto error;
1537
661 p = strchr(buf + 2, ':'); 1538 p = strchr(buf + 2, ':');
662 if (!p) 1539 if (!p) {
663 die("Internal error: %s should have ':' but not.", ent->s); 1540 pr_debug("Internal error: %s should have ':' but not.\n",
1541 ent->s);
1542 ret = -ENOTSUP;
1543 goto error;
1544 }
664 *p = '/'; 1545 *p = '/';
665 1546
666 write_trace_kprobe_event(fd, buf); 1547 pr_debug("Writing event: %s\n", buf);
1548 ret = write(fd, buf, strlen(buf));
1549 if (ret < 0)
1550 goto error;
1551
667 printf("Remove event: %s\n", ent->s); 1552 printf("Remove event: %s\n", ent->s);
1553 return 0;
1554error:
1555 pr_warning("Failed to delete event: %s\n", strerror(-ret));
1556 return ret;
668} 1557}
669 1558
670static void del_trace_kprobe_event(int fd, const char *group, 1559static int del_trace_kprobe_event(int fd, const char *group,
671 const char *event, struct strlist *namelist) 1560 const char *event, struct strlist *namelist)
672{ 1561{
673 char buf[128]; 1562 char buf[128];
674 struct str_node *ent, *n; 1563 struct str_node *ent, *n;
675 int found = 0; 1564 int found = 0, ret = 0;
676 1565
677 if (e_snprintf(buf, 128, "%s:%s", group, event) < 0) 1566 ret = e_snprintf(buf, 128, "%s:%s", group, event);
678 die("Failed to copy event."); 1567 if (ret < 0) {
1568 pr_err("Failed to copy event.");
1569 return ret;
1570 }
679 1571
680 if (strpbrk(buf, "*?")) { /* Glob-exp */ 1572 if (strpbrk(buf, "*?")) { /* Glob-exp */
681 strlist__for_each_safe(ent, n, namelist) 1573 strlist__for_each_safe(ent, n, namelist)
682 if (strglobmatch(ent->s, buf)) { 1574 if (strglobmatch(ent->s, buf)) {
683 found++; 1575 found++;
684 __del_trace_kprobe_event(fd, ent); 1576 ret = __del_trace_kprobe_event(fd, ent);
1577 if (ret < 0)
1578 break;
685 strlist__remove(namelist, ent); 1579 strlist__remove(namelist, ent);
686 } 1580 }
687 } else { 1581 } else {
688 ent = strlist__find(namelist, buf); 1582 ent = strlist__find(namelist, buf);
689 if (ent) { 1583 if (ent) {
690 found++; 1584 found++;
691 __del_trace_kprobe_event(fd, ent); 1585 ret = __del_trace_kprobe_event(fd, ent);
692 strlist__remove(namelist, ent); 1586 if (ret >= 0)
1587 strlist__remove(namelist, ent);
693 } 1588 }
694 } 1589 }
695 if (found == 0) 1590 if (found == 0 && ret >= 0)
696 pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf); 1591 pr_info("Info: Event \"%s\" does not exist.\n", buf);
1592
1593 return ret;
697} 1594}
698 1595
699void del_trace_kprobe_events(struct strlist *dellist) 1596int del_perf_probe_events(struct strlist *dellist)
700{ 1597{
701 int fd; 1598 int fd, ret = 0;
702 const char *group, *event; 1599 const char *group, *event;
703 char *p, *str; 1600 char *p, *str;
704 struct str_node *ent; 1601 struct str_node *ent;
705 struct strlist *namelist; 1602 struct strlist *namelist;
706 1603
707 fd = open_kprobe_events(O_RDWR, O_APPEND); 1604 fd = open_kprobe_events(true);
1605 if (fd < 0)
1606 return fd;
1607
708 /* Get current event names */ 1608 /* Get current event names */
709 namelist = get_perf_event_names(fd, true); 1609 namelist = get_kprobe_trace_event_names(fd, true);
1610 if (namelist == NULL)
1611 return -EINVAL;
710 1612
711 strlist__for_each(ent, dellist) { 1613 strlist__for_each(ent, dellist) {
712 str = strdup(ent->s); 1614 str = strdup(ent->s);
713 if (!str) 1615 if (str == NULL) {
714 die("Failed to copy event."); 1616 ret = -ENOMEM;
1617 break;
1618 }
715 pr_debug("Parsing: %s\n", str); 1619 pr_debug("Parsing: %s\n", str);
716 p = strchr(str, ':'); 1620 p = strchr(str, ':');
717 if (p) { 1621 if (p) {
@@ -723,80 +1627,14 @@ void del_trace_kprobe_events(struct strlist *dellist)
723 event = str; 1627 event = str;
724 } 1628 }
725 pr_debug("Group: %s, Event: %s\n", group, event); 1629 pr_debug("Group: %s, Event: %s\n", group, event);
726 del_trace_kprobe_event(fd, group, event, namelist); 1630 ret = del_trace_kprobe_event(fd, group, event, namelist);
727 free(str); 1631 free(str);
1632 if (ret < 0)
1633 break;
728 } 1634 }
729 strlist__delete(namelist); 1635 strlist__delete(namelist);
730 close(fd); 1636 close(fd);
731}
732 1637
733#define LINEBUF_SIZE 256 1638 return ret;
734#define NR_ADDITIONAL_LINES 2
735
736static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num)
737{
738 char buf[LINEBUF_SIZE];
739 const char *color = PERF_COLOR_BLUE;
740
741 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
742 goto error;
743 if (!skip) {
744 if (show_num)
745 fprintf(stdout, "%7u %s", l, buf);
746 else
747 color_fprintf(stdout, color, " %s", buf);
748 }
749
750 while (strlen(buf) == LINEBUF_SIZE - 1 &&
751 buf[LINEBUF_SIZE - 2] != '\n') {
752 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
753 goto error;
754 if (!skip) {
755 if (show_num)
756 fprintf(stdout, "%s", buf);
757 else
758 color_fprintf(stdout, color, "%s", buf);
759 }
760 }
761 return;
762error:
763 if (feof(fp))
764 die("Source file is shorter than expected.");
765 else
766 die("File read error: %s", strerror(errno));
767} 1639}
768 1640
769void show_line_range(struct line_range *lr)
770{
771 unsigned int l = 1;
772 struct line_node *ln;
773 FILE *fp;
774
775 setup_pager();
776
777 if (lr->function)
778 fprintf(stdout, "<%s:%d>\n", lr->function,
779 lr->start - lr->offset);
780 else
781 fprintf(stdout, "<%s:%d>\n", lr->file, lr->start);
782
783 fp = fopen(lr->path, "r");
784 if (fp == NULL)
785 die("Failed to open %s: %s", lr->path, strerror(errno));
786 /* Skip to starting line number */
787 while (l < lr->start)
788 show_one_line(fp, l++, true, false);
789
790 list_for_each_entry(ln, &lr->line_list, list) {
791 while (ln->line > l)
792 show_one_line(fp, (l++) - lr->offset, false, false);
793 show_one_line(fp, (l++) - lr->offset, false, true);
794 }
795
796 if (lr->end == INT_MAX)
797 lr->end = l + NR_ADDITIONAL_LINES;
798 while (l < lr->end && !feof(fp))
799 show_one_line(fp, (l++) - lr->offset, false, false);
800
801 fclose(fp);
802}