aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/probe-event.c
diff options
context:
space:
mode:
authorMasami Hiramatsu <mhiramat@redhat.com>2010-03-16 18:06:12 -0400
committerIngo Molnar <mingo@elte.hu>2010-03-17 06:32:31 -0400
commit4235b0454ebeefc2295ad8417e18a8761425b19e (patch)
treee6b0a3c66618dede18117a71fd16d2e65f93cba1 /tools/perf/util/probe-event.c
parentf4d7da499e4fc1fdff8f26fdeb1a058d475a7a6c (diff)
perf probe: Introduce kprobe_trace_event and perf_probe_event
Introduce kprobe_trace_event and perf_probe_event and replace old probe_point structure with it. probe_point structure is not enough flexible nor extensible. New data structures will help implementing further features. Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com> Cc: systemtap <systemtap@sources.redhat.com> Cc: DLE <dle-develop@lists.sourceforge.net> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Mike Galbraith <efault@gmx.de> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> LKML-Reference: <20100316220612.32050.33806.stgit@localhost6.localdomain6> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/probe-event.c')
-rw-r--r--tools/perf/util/probe-event.c626
1 files changed, 400 insertions, 226 deletions
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index ac41578a3552..b44ddfb030d7 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -44,6 +44,7 @@
44#include "thread.h" 44#include "thread.h"
45#include "parse-events.h" /* For debugfs_path */ 45#include "parse-events.h" /* For debugfs_path */
46#include "probe-event.h" 46#include "probe-event.h"
47#include "probe-finder.h"
47 48
48#define MAX_CMDLEN 256 49#define MAX_CMDLEN 256
49#define MAX_PROBE_ARGS 128 50#define MAX_PROBE_ARGS 128
@@ -150,8 +151,9 @@ static bool check_event_name(const char *name)
150} 151}
151 152
152/* Parse probepoint definition. */ 153/* Parse probepoint definition. */
153static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) 154static void parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
154{ 155{
156 struct perf_probe_point *pp = &pev->point;
155 char *ptr, *tmp; 157 char *ptr, *tmp;
156 char c, nc = 0; 158 char c, nc = 0;
157 /* 159 /*
@@ -172,7 +174,8 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
172 if (!check_event_name(arg)) 174 if (!check_event_name(arg))
173 semantic_error("%s is bad for event name -it must " 175 semantic_error("%s is bad for event name -it must "
174 "follow C symbol-naming rule.", arg); 176 "follow C symbol-naming rule.", arg);
175 pp->event = xstrdup(arg); 177 pev->event = xstrdup(arg);
178 pev->group = NULL;
176 arg = tmp; 179 arg = tmp;
177 } 180 }
178 181
@@ -255,57 +258,65 @@ static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp)
255 semantic_error("Offset/Line/Lazy pattern can't be used with " 258 semantic_error("Offset/Line/Lazy pattern can't be used with "
256 "return probe."); 259 "return probe.");
257 260
258 pr_debug("symbol:%s file:%s line:%d offset:%d return:%d lazy:%s\n", 261 pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
259 pp->function, pp->file, pp->line, pp->offset, pp->retprobe, 262 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
260 pp->lazy_line); 263 pp->lazy_line);
261} 264}
262 265
263/* Parse perf-probe event definition */ 266/* Parse perf-probe event command */
264void parse_perf_probe_event(const char *str, struct probe_point *pp, 267void parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
265 bool *need_dwarf)
266{ 268{
267 char **argv; 269 char **argv;
268 int argc, i; 270 int argc, i;
269 271
270 *need_dwarf = false; 272 argv = argv_split(cmd, &argc);
271
272 argv = argv_split(str, &argc);
273 if (!argv) 273 if (!argv)
274 die("argv_split failed."); 274 die("argv_split failed.");
275 if (argc > MAX_PROBE_ARGS + 1) 275 if (argc > MAX_PROBE_ARGS + 1)
276 semantic_error("Too many arguments"); 276 semantic_error("Too many arguments");
277 277
278 /* Parse probe point */ 278 /* Parse probe point */
279 parse_perf_probe_probepoint(argv[0], pp); 279 parse_perf_probe_point(argv[0], pev);
280 if (pp->file || pp->line || pp->lazy_line)
281 *need_dwarf = true;
282 280
283 /* Copy arguments and ensure return probe has no C argument */ 281 /* Copy arguments and ensure return probe has no C argument */
284 pp->nr_args = argc - 1; 282 pev->nargs = argc - 1;
285 pp->args = xzalloc(sizeof(char *) * pp->nr_args); 283 pev->args = xzalloc(sizeof(struct perf_probe_arg) * pev->nargs);
286 for (i = 0; i < pp->nr_args; i++) { 284 for (i = 0; i < pev->nargs; i++) {
287 pp->args[i] = xstrdup(argv[i + 1]); 285 pev->args[i].name = xstrdup(argv[i + 1]);
288 if (is_c_varname(pp->args[i])) { 286 if (is_c_varname(pev->args[i].name) && pev->point.retprobe)
289 if (pp->retprobe) 287 semantic_error("You can't specify local variable for"
290 semantic_error("You can't specify local" 288 " kretprobe");
291 " variable for kretprobe");
292 *need_dwarf = true;
293 }
294 } 289 }
295 290
296 argv_free(argv); 291 argv_free(argv);
297} 292}
298 293
294/* Return true if this perf_probe_event requires debuginfo */
295bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
296{
297 int i;
298
299 if (pev->point.file || pev->point.line || pev->point.lazy_line)
300 return true;
301
302 for (i = 0; i < pev->nargs; i++)
303 if (is_c_varname(pev->args[i].name))
304 return true;
305
306 return false;
307}
308
299/* Parse kprobe_events event into struct probe_point */ 309/* Parse kprobe_events event into struct probe_point */
300void parse_trace_kprobe_event(const char *str, struct probe_point *pp) 310void parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev)
301{ 311{
312 struct kprobe_trace_point *tp = &tev->point;
302 char pr; 313 char pr;
303 char *p; 314 char *p;
304 int ret, i, argc; 315 int ret, i, argc;
305 char **argv; 316 char **argv;
306 317
307 pr_debug("Parsing kprobe_events: %s\n", str); 318 pr_debug("Parsing kprobe_events: %s\n", cmd);
308 argv = argv_split(str, &argc); 319 argv = argv_split(cmd, &argc);
309 if (!argv) 320 if (!argv)
310 die("argv_split failed."); 321 die("argv_split failed.");
311 if (argc < 2) 322 if (argc < 2)
@@ -313,47 +324,46 @@ void parse_trace_kprobe_event(const char *str, struct probe_point *pp)
313 324
314 /* Scan event and group name. */ 325 /* Scan event and group name. */
315 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", 326 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
316 &pr, (float *)(void *)&pp->group, 327 &pr, (float *)(void *)&tev->group,
317 (float *)(void *)&pp->event); 328 (float *)(void *)&tev->event);
318 if (ret != 3) 329 if (ret != 3)
319 semantic_error("Failed to parse event name: %s", argv[0]); 330 semantic_error("Failed to parse event name: %s", argv[0]);
320 pr_debug("Group:%s Event:%s probe:%c\n", pp->group, pp->event, pr); 331 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
321 332
322 pp->retprobe = (pr == 'r'); 333 tp->retprobe = (pr == 'r');
323 334
324 /* Scan function name and offset */ 335 /* Scan function name and offset */
325 ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function, 336 ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol,
326 &pp->offset); 337 &tp->offset);
327 if (ret == 1) 338 if (ret == 1)
328 pp->offset = 0; 339 tp->offset = 0;
329
330 /* kprobe_events doesn't have this information */
331 pp->line = 0;
332 pp->file = NULL;
333 340
334 pp->nr_args = argc - 2; 341 tev->nargs = argc - 2;
335 pp->args = xzalloc(sizeof(char *) * pp->nr_args); 342 tev->args = xzalloc(sizeof(struct kprobe_trace_arg) * tev->nargs);
336 for (i = 0; i < pp->nr_args; i++) { 343 for (i = 0; i < tev->nargs; i++) {
337 p = strchr(argv[i + 2], '='); 344 p = strchr(argv[i + 2], '=');
338 if (p) /* We don't need which register is assigned. */ 345 if (p) /* We don't need which register is assigned. */
339 *p = '\0'; 346 *p++ = '\0';
340 pp->args[i] = xstrdup(argv[i + 2]); 347 else
348 p = argv[i + 2];
349 tev->args[i].name = xstrdup(argv[i + 2]);
350 /* TODO: parse regs and offset */
351 tev->args[i].value = xstrdup(p);
341 } 352 }
342 353
343 argv_free(argv); 354 argv_free(argv);
344} 355}
345 356
346/* Synthesize only probe point (not argument) */ 357/* Compose only probe point (not argument) */
347int synthesize_perf_probe_point(struct probe_point *pp) 358static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
348{ 359{
349 char *buf; 360 char *buf;
350 char offs[64] = "", line[64] = ""; 361 char offs[64] = "", line[64] = "";
351 int ret; 362 int ret;
352 363
353 pp->probes[0] = buf = xzalloc(MAX_CMDLEN); 364 buf = xzalloc(MAX_CMDLEN);
354 pp->found = 1;
355 if (pp->offset) { 365 if (pp->offset) {
356 ret = e_snprintf(offs, 64, "+%d", pp->offset); 366 ret = e_snprintf(offs, 64, "+%lu", pp->offset);
357 if (ret <= 0) 367 if (ret <= 0)
358 goto error; 368 goto error;
359 } 369 }
@@ -368,68 +378,209 @@ int synthesize_perf_probe_point(struct probe_point *pp)
368 offs, pp->retprobe ? "%return" : "", line); 378 offs, pp->retprobe ? "%return" : "", line);
369 else 379 else
370 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line); 380 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line);
371 if (ret <= 0) { 381 if (ret <= 0)
382 goto error;
383
384 return buf;
372error: 385error:
373 free(pp->probes[0]); 386 die("Failed to synthesize perf probe point: %s", strerror(-ret));
374 pp->probes[0] = NULL;
375 pp->found = 0;
376 }
377 return ret;
378} 387}
379 388
380int synthesize_perf_probe_event(struct probe_point *pp) 389#if 0
390char *synthesize_perf_probe_command(struct perf_probe_event *pev)
381{ 391{
382 char *buf; 392 char *buf;
383 int i, len, ret; 393 int i, len, ret;
384 394
385 len = synthesize_perf_probe_point(pp); 395 buf = synthesize_perf_probe_point(&pev->point);
386 if (len < 0) 396 if (!buf)
387 return 0; 397 return NULL;
388 398
389 buf = pp->probes[0]; 399 len = strlen(buf);
390 for (i = 0; i < pp->nr_args; i++) { 400 for (i = 0; i < pev->nargs; i++) {
391 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", 401 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
392 pp->args[i]); 402 pev->args[i].name);
393 if (ret <= 0) 403 if (ret <= 0) {
394 goto error; 404 free(buf);
405 return NULL;
406 }
395 len += ret; 407 len += ret;
396 } 408 }
397 pp->found = 1;
398 409
399 return pp->found; 410 return buf;
400error: 411}
401 free(pp->probes[0]); 412#endif
402 pp->probes[0] = NULL; 413
414static int __synthesize_kprobe_trace_arg_ref(struct kprobe_trace_arg_ref *ref,
415 char **buf, size_t *buflen,
416 int depth)
417{
418 int ret;
419 if (ref->next) {
420 depth = __synthesize_kprobe_trace_arg_ref(ref->next, buf,
421 buflen, depth + 1);
422 if (depth < 0)
423 goto out;
424 }
425
426 ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset);
427 if (ret < 0)
428 depth = ret;
429 else {
430 *buf += ret;
431 *buflen -= ret;
432 }
433out:
434 return depth;
403 435
404 return ret;
405} 436}
406 437
407int synthesize_trace_kprobe_event(struct probe_point *pp) 438static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg,
439 char *buf, size_t buflen)
408{ 440{
441 int ret, depth = 0;
442 char *tmp = buf;
443
444 /* Argument name or separator */
445 if (arg->name)
446 ret = e_snprintf(buf, buflen, " %s=", arg->name);
447 else
448 ret = e_snprintf(buf, buflen, " ");
449 if (ret < 0)
450 return ret;
451 buf += ret;
452 buflen -= ret;
453
454 /* Dereferencing arguments */
455 if (arg->ref) {
456 depth = __synthesize_kprobe_trace_arg_ref(arg->ref, &buf,
457 &buflen, 1);
458 if (depth < 0)
459 return depth;
460 }
461
462 /* Print argument value */
463 ret = e_snprintf(buf, buflen, "%s", arg->value);
464 if (ret < 0)
465 return ret;
466 buf += ret;
467 buflen -= ret;
468
469 /* Closing */
470 while (depth--) {
471 ret = e_snprintf(buf, buflen, ")");
472 if (ret < 0)
473 return ret;
474 buf += ret;
475 buflen -= ret;
476 }
477
478 return buf - tmp;
479}
480
481char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev)
482{
483 struct kprobe_trace_point *tp = &tev->point;
409 char *buf; 484 char *buf;
410 int i, len, ret; 485 int i, len, ret;
411 486
412 pp->probes[0] = buf = xzalloc(MAX_CMDLEN); 487 buf = xzalloc(MAX_CMDLEN);
413 ret = e_snprintf(buf, MAX_CMDLEN, "%s+%d", pp->function, pp->offset); 488 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu",
414 if (ret <= 0) 489 tp->retprobe ? 'r' : 'p',
490 tev->group, tev->event,
491 tp->symbol, tp->offset);
492 if (len <= 0)
415 goto error; 493 goto error;
416 len = ret;
417 494
418 for (i = 0; i < pp->nr_args; i++) { 495 for (i = 0; i < tev->nargs; i++) {
419 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", 496 ret = synthesize_kprobe_trace_arg(&tev->args[i], buf + len,
420 pp->args[i]); 497 MAX_CMDLEN - len);
421 if (ret <= 0) 498 if (ret <= 0)
422 goto error; 499 goto error;
423 len += ret; 500 len += ret;
424 } 501 }
425 pp->found = 1;
426 502
427 return pp->found; 503 return buf;
428error: 504error:
429 free(pp->probes[0]); 505 free(buf);
430 pp->probes[0] = NULL; 506 return NULL;
507}
431 508
432 return ret; 509void convert_to_perf_probe_event(struct kprobe_trace_event *tev,
510 struct perf_probe_event *pev)
511{
512 char buf[64];
513 int i;
514
515 pev->event = xstrdup(tev->event);
516 pev->group = xstrdup(tev->group);
517
518 /* Convert trace_point to probe_point */
519 pev->point.function = xstrdup(tev->point.symbol);
520 pev->point.offset = tev->point.offset;
521 pev->point.retprobe = tev->point.retprobe;
522
523 /* Convert trace_arg to probe_arg */
524 pev->nargs = tev->nargs;
525 pev->args = xzalloc(sizeof(struct perf_probe_arg) * pev->nargs);
526 for (i = 0; i < tev->nargs; i++)
527 if (tev->args[i].name)
528 pev->args[i].name = xstrdup(tev->args[i].name);
529 else {
530 synthesize_kprobe_trace_arg(&tev->args[i], buf, 64);
531 pev->args[i].name = xstrdup(buf);
532 }
533}
534
535void clear_perf_probe_event(struct perf_probe_event *pev)
536{
537 struct perf_probe_point *pp = &pev->point;
538 int i;
539
540 if (pev->event)
541 free(pev->event);
542 if (pev->group)
543 free(pev->group);
544 if (pp->file)
545 free(pp->file);
546 if (pp->function)
547 free(pp->function);
548 if (pp->lazy_line)
549 free(pp->lazy_line);
550 for (i = 0; i < pev->nargs; i++)
551 if (pev->args[i].name)
552 free(pev->args[i].name);
553 if (pev->args)
554 free(pev->args);
555 memset(pev, 0, sizeof(*pev));
556}
557
558void clear_kprobe_trace_event(struct kprobe_trace_event *tev)
559{
560 struct kprobe_trace_arg_ref *ref, *next;
561 int i;
562
563 if (tev->event)
564 free(tev->event);
565 if (tev->group)
566 free(tev->group);
567 if (tev->point.symbol)
568 free(tev->point.symbol);
569 for (i = 0; i < tev->nargs; i++) {
570 if (tev->args[i].name)
571 free(tev->args[i].name);
572 if (tev->args[i].value)
573 free(tev->args[i].value);
574 ref = tev->args[i].ref;
575 while (ref) {
576 next = ref->next;
577 free(ref);
578 ref = next;
579 }
580 }
581 if (tev->args)
582 free(tev->args);
583 memset(tev, 0, sizeof(*tev));
433} 584}
434 585
435static int open_kprobe_events(bool readwrite) 586static int open_kprobe_events(bool readwrite)
@@ -458,7 +609,7 @@ static int open_kprobe_events(bool readwrite)
458} 609}
459 610
460/* Get raw string list of current kprobe_events */ 611/* Get raw string list of current kprobe_events */
461static struct strlist *get_trace_kprobe_event_rawlist(int fd) 612static struct strlist *get_kprobe_trace_command_rawlist(int fd)
462{ 613{
463 int ret, idx; 614 int ret, idx;
464 FILE *fp; 615 FILE *fp;
@@ -486,99 +637,82 @@ static struct strlist *get_trace_kprobe_event_rawlist(int fd)
486 return sl; 637 return sl;
487} 638}
488 639
489/* Free and zero clear probe_point */
490static void clear_probe_point(struct probe_point *pp)
491{
492 int i;
493
494 if (pp->event)
495 free(pp->event);
496 if (pp->group)
497 free(pp->group);
498 if (pp->function)
499 free(pp->function);
500 if (pp->file)
501 free(pp->file);
502 if (pp->lazy_line)
503 free(pp->lazy_line);
504 for (i = 0; i < pp->nr_args; i++)
505 free(pp->args[i]);
506 if (pp->args)
507 free(pp->args);
508 for (i = 0; i < pp->found; i++)
509 free(pp->probes[i]);
510 memset(pp, 0, sizeof(*pp));
511}
512
513/* Show an event */ 640/* Show an event */
514static void show_perf_probe_event(const char *event, const char *place, 641static void show_perf_probe_event(struct perf_probe_event *pev)
515 struct probe_point *pp)
516{ 642{
517 int i, ret; 643 int i, ret;
518 char buf[128]; 644 char buf[128];
645 char *place;
519 646
520 ret = e_snprintf(buf, 128, "%s:%s", pp->group, event); 647 /* Synthesize only event probe point */
648 place = synthesize_perf_probe_point(&pev->point);
649
650 ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
521 if (ret < 0) 651 if (ret < 0)
522 die("Failed to copy event: %s", strerror(-ret)); 652 die("Failed to copy event: %s", strerror(-ret));
523 printf(" %-40s (on %s", buf, place); 653 printf(" %-40s (on %s", buf, place);
524 654
525 if (pp->nr_args > 0) { 655 if (pev->nargs > 0) {
526 printf(" with"); 656 printf(" with");
527 for (i = 0; i < pp->nr_args; i++) 657 for (i = 0; i < pev->nargs; i++)
528 printf(" %s", pp->args[i]); 658 printf(" %s", pev->args[i].name);
529 } 659 }
530 printf(")\n"); 660 printf(")\n");
661 free(place);
531} 662}
532 663
533/* List up current perf-probe events */ 664/* List up current perf-probe events */
534void show_perf_probe_events(void) 665void show_perf_probe_events(void)
535{ 666{
536 int fd; 667 int fd;
537 struct probe_point pp; 668 struct kprobe_trace_event tev;
669 struct perf_probe_event pev;
538 struct strlist *rawlist; 670 struct strlist *rawlist;
539 struct str_node *ent; 671 struct str_node *ent;
540 672
541 setup_pager(); 673 setup_pager();
542 memset(&pp, 0, sizeof(pp)); 674
675 memset(&tev, 0, sizeof(tev));
676 memset(&pev, 0, sizeof(pev));
543 677
544 fd = open_kprobe_events(false); 678 fd = open_kprobe_events(false);
545 rawlist = get_trace_kprobe_event_rawlist(fd); 679 rawlist = get_kprobe_trace_command_rawlist(fd);
546 close(fd); 680 close(fd);
547 681
548 strlist__for_each(ent, rawlist) { 682 strlist__for_each(ent, rawlist) {
549 parse_trace_kprobe_event(ent->s, &pp); 683 parse_kprobe_trace_command(ent->s, &tev);
550 /* Synthesize only event probe point */ 684 convert_to_perf_probe_event(&tev, &pev);
551 synthesize_perf_probe_point(&pp);
552 /* Show an event */ 685 /* Show an event */
553 show_perf_probe_event(pp.event, pp.probes[0], &pp); 686 show_perf_probe_event(&pev);
554 clear_probe_point(&pp); 687 clear_perf_probe_event(&pev);
688 clear_kprobe_trace_event(&tev);
555 } 689 }
556 690
557 strlist__delete(rawlist); 691 strlist__delete(rawlist);
558} 692}
559 693
560/* Get current perf-probe event names */ 694/* Get current perf-probe event names */
561static struct strlist *get_perf_event_names(int fd, bool include_group) 695static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group)
562{ 696{
563 char buf[128]; 697 char buf[128];
564 struct strlist *sl, *rawlist; 698 struct strlist *sl, *rawlist;
565 struct str_node *ent; 699 struct str_node *ent;
566 struct probe_point pp; 700 struct kprobe_trace_event tev;
567 701
568 memset(&pp, 0, sizeof(pp)); 702 memset(&tev, 0, sizeof(tev));
569 rawlist = get_trace_kprobe_event_rawlist(fd);
570 703
704 rawlist = get_kprobe_trace_command_rawlist(fd);
571 sl = strlist__new(true, NULL); 705 sl = strlist__new(true, NULL);
572 strlist__for_each(ent, rawlist) { 706 strlist__for_each(ent, rawlist) {
573 parse_trace_kprobe_event(ent->s, &pp); 707 parse_kprobe_trace_command(ent->s, &tev);
574 if (include_group) { 708 if (include_group) {
575 if (e_snprintf(buf, 128, "%s:%s", pp.group, 709 if (e_snprintf(buf, 128, "%s:%s", tev.group,
576 pp.event) < 0) 710 tev.event) < 0)
577 die("Failed to copy group:event name."); 711 die("Failed to copy group:event name.");
578 strlist__add(sl, buf); 712 strlist__add(sl, buf);
579 } else 713 } else
580 strlist__add(sl, pp.event); 714 strlist__add(sl, tev.event);
581 clear_probe_point(&pp); 715 clear_kprobe_trace_event(&tev);
582 } 716 }
583 717
584 strlist__delete(rawlist); 718 strlist__delete(rawlist);
@@ -586,9 +720,10 @@ static struct strlist *get_perf_event_names(int fd, bool include_group)
586 return sl; 720 return sl;
587} 721}
588 722
589static void write_trace_kprobe_event(int fd, const char *buf) 723static void write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev)
590{ 724{
591 int ret; 725 int ret;
726 char *buf = synthesize_kprobe_trace_command(tev);
592 727
593 pr_debug("Writing event: %s\n", buf); 728 pr_debug("Writing event: %s\n", buf);
594 if (!probe_event_dry_run) { 729 if (!probe_event_dry_run) {
@@ -596,6 +731,7 @@ static void write_trace_kprobe_event(int fd, const char *buf)
596 if (ret <= 0) 731 if (ret <= 0)
597 die("Failed to write event: %s", strerror(errno)); 732 die("Failed to write event: %s", strerror(errno));
598 } 733 }
734 free(buf);
599} 735}
600 736
601static void get_new_event_name(char *buf, size_t len, const char *base, 737static void get_new_event_name(char *buf, size_t len, const char *base,
@@ -628,81 +764,83 @@ static void get_new_event_name(char *buf, size_t len, const char *base,
628 die("Too many events are on the same function."); 764 die("Too many events are on the same function.");
629} 765}
630 766
631static void __add_trace_kprobe_events(struct probe_point *probes, 767static void __add_kprobe_trace_events(struct perf_probe_event *pev,
632 int nr_probes, bool force_add) 768 struct kprobe_trace_event *tevs,
769 int ntevs, bool allow_suffix)
633{ 770{
634 int i, j, fd; 771 int i, fd;
635 struct probe_point *pp; 772 struct kprobe_trace_event *tev;
636 char buf[MAX_CMDLEN]; 773 char buf[64];
637 char event[64]; 774 const char *event, *group;
638 struct strlist *namelist; 775 struct strlist *namelist;
639 bool allow_suffix;
640 776
641 fd = open_kprobe_events(true); 777 fd = open_kprobe_events(true);
642 /* Get current event names */ 778 /* Get current event names */
643 namelist = get_perf_event_names(fd, false); 779 namelist = get_kprobe_trace_event_names(fd, false);
644 780
645 for (j = 0; j < nr_probes; j++) { 781 printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":");
646 pp = probes + j; 782 for (i = 0; i < ntevs; i++) {
647 if (!pp->event) 783 tev = &tevs[i];
648 pp->event = xstrdup(pp->function); 784 if (pev->event)
649 if (!pp->group) 785 event = pev->event;
650 pp->group = xstrdup(PERFPROBE_GROUP); 786 else
651 /* If force_add is true, suffix search is allowed */ 787 if (pev->point.function)
652 allow_suffix = force_add; 788 event = pev->point.function;
653 for (i = 0; i < pp->found; i++) { 789 else
654 /* Get an unused new event name */ 790 event = tev->point.symbol;
655 get_new_event_name(event, 64, pp->event, namelist, 791 if (pev->group)
656 allow_suffix); 792 group = pev->group;
657 snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n", 793 else
658 pp->retprobe ? 'r' : 'p', 794 group = PERFPROBE_GROUP;
659 pp->group, event, 795
660 pp->probes[i]); 796 /* Get an unused new event name */
661 write_trace_kprobe_event(fd, buf); 797 get_new_event_name(buf, 64, event, namelist, allow_suffix);
662 printf("Added new event:\n"); 798 event = buf;
663 /* Get the first parameter (probe-point) */ 799
664 sscanf(pp->probes[i], "%s", buf); 800 tev->event = xstrdup(event);
665 show_perf_probe_event(event, buf, pp); 801 tev->group = xstrdup(group);
666 /* Add added event name to namelist */ 802 write_kprobe_trace_event(fd, tev);
667 strlist__add(namelist, event); 803 /* Add added event name to namelist */
668 /* 804 strlist__add(namelist, event);
669 * Probes after the first probe which comes from same 805
670 * user input are always allowed to add suffix, because 806 /* Trick here - save current event/group */
671 * there might be several addresses corresponding to 807 event = pev->event;
672 * one code line. 808 group = pev->group;
673 */ 809 pev->event = tev->event;
674 allow_suffix = true; 810 pev->group = tev->group;
675 } 811 show_perf_probe_event(pev);
812 /* Trick here - restore current event/group */
813 pev->event = (char *)event;
814 pev->group = (char *)group;
815
816 /*
817 * Probes after the first probe which comes from same
818 * user input are always allowed to add suffix, because
819 * there might be several addresses corresponding to
820 * one code line.
821 */
822 allow_suffix = true;
676 } 823 }
677 /* Show how to use the event. */ 824 /* Show how to use the event. */
678 printf("\nYou can now use it on all perf tools, such as:\n\n"); 825 printf("\nYou can now use it on all perf tools, such as:\n\n");
679 printf("\tperf record -e %s:%s -a sleep 1\n\n", PERFPROBE_GROUP, event); 826 printf("\tperf record -e %s:%s -a sleep 1\n\n", tev->group, tev->event);
680 827
681 strlist__delete(namelist); 828 strlist__delete(namelist);
682 close(fd); 829 close(fd);
683} 830}
684 831
685/* Currently just checking function name from symbol map */ 832static int convert_to_kprobe_trace_events(struct perf_probe_event *pev,
686static void evaluate_probe_point(struct probe_point *pp) 833 struct kprobe_trace_event **tevs)
687{ 834{
688 struct symbol *sym; 835 struct symbol *sym;
689 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION], 836 bool need_dwarf;
690 pp->function, NULL);
691 if (!sym)
692 die("Kernel symbol \'%s\' not found - probe not added.",
693 pp->function);
694}
695
696void add_trace_kprobe_events(struct probe_point *probes, int nr_probes,
697 bool force_add, bool need_dwarf)
698{
699 int i, ret;
700 struct probe_point *pp;
701#ifndef NO_DWARF_SUPPORT 837#ifndef NO_DWARF_SUPPORT
702 int fd; 838 int fd;
703#endif 839#endif
704 /* Add probes */ 840 int ntevs = 0, i;
705 init_vmlinux(); 841 struct kprobe_trace_event *tev;
842
843 need_dwarf = perf_probe_event_need_dwarf(pev);
706 844
707 if (need_dwarf) 845 if (need_dwarf)
708#ifdef NO_DWARF_SUPPORT 846#ifdef NO_DWARF_SUPPORT
@@ -721,57 +859,90 @@ void add_trace_kprobe_events(struct probe_point *probes, int nr_probes,
721 } 859 }
722 860
723 /* Searching probe points */ 861 /* Searching probe points */
724 for (i = 0; i < nr_probes; i++) { 862 ntevs = find_kprobe_trace_events(fd, pev, tevs);
725 pp = &probes[i]; 863
726 if (pp->found) 864 if (ntevs > 0) /* Found */
727 continue; 865 goto found;
728 866
729 lseek(fd, SEEK_SET, 0); 867 if (ntevs == 0) /* No error but failed to find probe point. */
730 ret = find_probe_point(fd, pp); 868 die("Probe point '%s' not found. - probe not added.",
731 if (ret > 0) 869 synthesize_perf_probe_point(&pev->point));
732 continue; 870
733 if (ret == 0) { /* No error but failed to find probe point. */ 871 /* Error path */
734 synthesize_perf_probe_point(pp); 872 if (need_dwarf) {
735 die("Probe point '%s' not found. - probe not added.", 873 if (ntevs == -ENOENT)
736 pp->probes[0]); 874 pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO=y.\n");
737 } 875 die("Could not analyze debuginfo.");
738 /* Error path */
739 if (need_dwarf) {
740 if (ret == -ENOENT)
741 pr_warning("No dwarf info found in the vmlinux - please rebuild with CONFIG_DEBUG_INFO=y.\n");
742 die("Could not analyze debuginfo.");
743 }
744 pr_debug("An error occurred in debuginfo analysis."
745 " Try to use symbols.\n");
746 break;
747 } 876 }
748 close(fd); 877 pr_debug("An error occurred in debuginfo analysis."
878 " Try to use symbols.\n");
749 879
750end_dwarf: 880end_dwarf:
751#endif /* !NO_DWARF_SUPPORT */ 881#endif /* !NO_DWARF_SUPPORT */
752 882
753 /* Synthesize probes without dwarf */ 883 /* Allocate trace event buffer */
754 for (i = 0; i < nr_probes; i++) { 884 ntevs = 1;
755 pp = &probes[i]; 885 tev = *tevs = xzalloc(sizeof(struct kprobe_trace_event));
756 if (pp->found) /* This probe is already found. */ 886
757 continue; 887 /* Copy parameters */
888 tev->point.symbol = xstrdup(pev->point.function);
889 tev->point.offset = pev->point.offset;
890 tev->nargs = pev->nargs;
891 if (tev->nargs) {
892 tev->args = xzalloc(sizeof(struct kprobe_trace_arg)
893 * tev->nargs);
894 for (i = 0; i < tev->nargs; i++)
895 tev->args[i].value = xstrdup(pev->args[i].name);
896 }
897
898 /* Currently just checking function name from symbol map */
899 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION],
900 tev->point.symbol, NULL);
901 if (!sym)
902 die("Kernel symbol \'%s\' not found - probe not added.",
903 tev->point.symbol);
904found:
905 close(fd);
906 return ntevs;
907}
908
909struct __event_package {
910 struct perf_probe_event *pev;
911 struct kprobe_trace_event *tevs;
912 int ntevs;
913};
758 914
759 evaluate_probe_point(pp); 915void add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
760 ret = synthesize_trace_kprobe_event(pp); 916 bool force_add)
761 if (ret == -E2BIG) 917{
762 die("probe point definition becomes too long."); 918 int i;
763 else if (ret < 0) 919 struct __event_package *pkgs;
764 die("Failed to synthesize a probe point."); 920
921 pkgs = xzalloc(sizeof(struct __event_package) * npevs);
922
923 /* Init vmlinux path */
924 init_vmlinux();
925
926 /* Loop 1: convert all events */
927 for (i = 0; i < npevs; i++) {
928 pkgs[i].pev = &pevs[i];
929 /* Convert with or without debuginfo */
930 pkgs[i].ntevs = convert_to_kprobe_trace_events(pkgs[i].pev,
931 &pkgs[i].tevs);
765 } 932 }
766 933
767 /* Settng up probe points */ 934 /* Loop 2: add all events */
768 __add_trace_kprobe_events(probes, nr_probes, force_add); 935 for (i = 0; i < npevs; i++)
936 __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs,
937 pkgs[i].ntevs, force_add);
938 /* TODO: cleanup all trace events? */
769} 939}
770 940
771static void __del_trace_kprobe_event(int fd, struct str_node *ent) 941static void __del_trace_kprobe_event(int fd, struct str_node *ent)
772{ 942{
773 char *p; 943 char *p;
774 char buf[128]; 944 char buf[128];
945 int ret;
775 946
776 /* Convert from perf-probe event to trace-kprobe event */ 947 /* Convert from perf-probe event to trace-kprobe event */
777 if (e_snprintf(buf, 128, "-:%s", ent->s) < 0) 948 if (e_snprintf(buf, 128, "-:%s", ent->s) < 0)
@@ -781,7 +952,10 @@ static void __del_trace_kprobe_event(int fd, struct str_node *ent)
781 die("Internal error: %s should have ':' but not.", ent->s); 952 die("Internal error: %s should have ':' but not.", ent->s);
782 *p = '/'; 953 *p = '/';
783 954
784 write_trace_kprobe_event(fd, buf); 955 pr_debug("Writing event: %s\n", buf);
956 ret = write(fd, buf, strlen(buf));
957 if (ret <= 0)
958 die("Failed to write event: %s", strerror(errno));
785 printf("Remove event: %s\n", ent->s); 959 printf("Remove event: %s\n", ent->s);
786} 960}
787 961
@@ -814,7 +988,7 @@ static void del_trace_kprobe_event(int fd, const char *group,
814 pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf); 988 pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf);
815} 989}
816 990
817void del_trace_kprobe_events(struct strlist *dellist) 991void del_perf_probe_events(struct strlist *dellist)
818{ 992{
819 int fd; 993 int fd;
820 const char *group, *event; 994 const char *group, *event;
@@ -824,7 +998,7 @@ void del_trace_kprobe_events(struct strlist *dellist)
824 998
825 fd = open_kprobe_events(true); 999 fd = open_kprobe_events(true);
826 /* Get current event names */ 1000 /* Get current event names */
827 namelist = get_perf_event_names(fd, true); 1001 namelist = get_kprobe_trace_event_names(fd, true);
828 1002
829 strlist__for_each(ent, dellist) { 1003 strlist__for_each(ent, dellist) {
830 str = xstrdup(ent->s); 1004 str = xstrdup(ent->s);