probe-event.c (7c7145f6acc68100dbdc5d3c5c64fe3af1c99c89) | probe-event.c (48481938b02471d505296d7557ed296eb093d496) |
---|---|
1/* 2 * probe-event.c : perf-probe definition to kprobe_events format converter 3 * 4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 19 unchanged lines hidden (view full) --- 28#include <stdio.h> 29#include <unistd.h> 30#include <stdlib.h> 31#include <string.h> 32#include <stdarg.h> 33#include <limits.h> 34 35#undef _GNU_SOURCE | 1/* 2 * probe-event.c : perf-probe definition to kprobe_events format converter 3 * 4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or --- 19 unchanged lines hidden (view full) --- 28#include <stdio.h> 29#include <unistd.h> 30#include <stdlib.h> 31#include <string.h> 32#include <stdarg.h> 33#include <limits.h> 34 35#undef _GNU_SOURCE |
36#include "util.h" |
|
36#include "event.h" 37#include "string.h" 38#include "strlist.h" 39#include "debug.h" 40#include "cache.h" 41#include "color.h" | 37#include "event.h" 38#include "string.h" 39#include "strlist.h" 40#include "debug.h" 41#include "cache.h" 42#include "color.h" |
42#include "parse-events.h" /* For debugfs_path */ | 43#include "symbol.h" 44#include "thread.h" 45#include "trace-event.h" /* For __unused */ 46#include "parse-events.h" /* For debugfs_path */ |
43#include "probe-event.h" | 47#include "probe-event.h" |
48#include "probe-finder.h" |
|
44 45#define MAX_CMDLEN 256 46#define MAX_PROBE_ARGS 128 47#define PERFPROBE_GROUP "probe" 48 | 49 50#define MAX_CMDLEN 256 51#define MAX_PROBE_ARGS 128 52#define PERFPROBE_GROUP "probe" 53 |
54bool probe_event_dry_run; /* Dry run flag */ 55 |
|
49#define semantic_error(msg ...) die("Semantic error :" msg) 50 51/* If there is no space to write, returns -E2BIG. */ 52static int e_snprintf(char *str, size_t size, const char *format, ...) 53 __attribute__((format(printf, 3, 4))); 54 55static int e_snprintf(char *str, size_t size, const char *format, ...) 56{ 57 int ret; 58 va_list ap; 59 va_start(ap, format); 60 ret = vsnprintf(str, size, format, ap); 61 va_end(ap); 62 if (ret >= (int)size) 63 ret = -E2BIG; 64 return ret; 65} 66 | 56#define semantic_error(msg ...) die("Semantic error :" msg) 57 58/* If there is no space to write, returns -E2BIG. */ 59static int e_snprintf(char *str, size_t size, const char *format, ...) 60 __attribute__((format(printf, 3, 4))); 61 62static int e_snprintf(char *str, size_t size, const char *format, ...) 63{ 64 int ret; 65 va_list ap; 66 va_start(ap, format); 67 ret = vsnprintf(str, size, format, ap); 68 va_end(ap); 69 if (ret >= (int)size) 70 ret = -E2BIG; 71 return ret; 72} 73 |
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 void init_vmlinux(void) 80{ 81 symbol_conf.sort_by_name = true; 82 if (symbol_conf.vmlinux_name == NULL) 83 symbol_conf.try_vmlinux_path = true; 84 else 85 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name); 86 if (symbol__init() < 0) 87 die("Failed to init symbol map."); 88 89 map_groups__init(&kmap_groups); 90 if (map_groups__create_kernel_maps(&kmap_groups, kmaps) < 0) 91 die("Failed to create kernel maps."); 92} 93 94#ifdef DWARF_SUPPORT 95static int open_vmlinux(void) 96{ 97 if (map__load(kmaps[MAP__FUNCTION], NULL) < 0) { 98 pr_debug("Failed to load kernel map.\n"); 99 return -EINVAL; 100 } 101 pr_debug("Try to open %s\n", kmaps[MAP__FUNCTION]->dso->long_name); 102 return open(kmaps[MAP__FUNCTION]->dso->long_name, O_RDONLY); 103} 104 105static void convert_to_perf_probe_point(struct kprobe_trace_point *tp, 106 struct perf_probe_point *pp) 107{ 108 struct symbol *sym; 109 int fd, ret = 0; 110 111 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION], 112 tp->symbol, NULL); 113 if (sym) { 114 fd = open_vmlinux(); 115 ret = find_perf_probe_point(fd, sym->start + tp->offset, pp); 116 close(fd); 117 } 118 if (ret <= 0) { 119 pp->function = xstrdup(tp->symbol); 120 pp->offset = tp->offset; 121 } 122 pp->retprobe = tp->retprobe; 123} 124 125/* Try to find perf_probe_event with debuginfo */ 126static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, 127 struct kprobe_trace_event **tevs) 128{ 129 bool need_dwarf = perf_probe_event_need_dwarf(pev); 130 int fd, ntevs; 131 132 fd = open_vmlinux(); 133 if (fd < 0) { 134 if (need_dwarf) 135 die("Could not open debuginfo file."); 136 137 pr_debug("Could not open vmlinux. Try to use symbols.\n"); 138 return 0; 139 } 140 141 /* Searching trace events corresponding to probe event */ 142 ntevs = find_kprobe_trace_events(fd, pev, tevs); 143 close(fd); 144 145 if (ntevs > 0) /* Succeeded to find trace events */ 146 return ntevs; 147 148 if (ntevs == 0) /* No error but failed to find probe point. */ 149 die("Probe point '%s' not found. - probe not added.", 150 synthesize_perf_probe_point(&pev->point)); 151 152 /* Error path */ 153 if (need_dwarf) { 154 if (ntevs == -ENOENT) 155 pr_warning("No dwarf info found in the vmlinux - " 156 "please rebuild with CONFIG_DEBUG_INFO=y.\n"); 157 die("Could not analyze debuginfo."); 158 } 159 pr_debug("An error occurred in debuginfo analysis." 160 " Try to use symbols.\n"); 161 return 0; 162 163} 164 165#define LINEBUF_SIZE 256 166#define NR_ADDITIONAL_LINES 2 167 168static void show_one_line(FILE *fp, unsigned int l, bool skip, bool show_num) 169{ 170 char buf[LINEBUF_SIZE]; 171 const char *color = PERF_COLOR_BLUE; 172 173 if (fgets(buf, LINEBUF_SIZE, fp) == NULL) 174 goto error; 175 if (!skip) { 176 if (show_num) 177 fprintf(stdout, "%7u %s", l, buf); 178 else 179 color_fprintf(stdout, color, " %s", buf); 180 } 181 182 while (strlen(buf) == LINEBUF_SIZE - 1 && 183 buf[LINEBUF_SIZE - 2] != '\n') { 184 if (fgets(buf, LINEBUF_SIZE, fp) == NULL) 185 goto error; 186 if (!skip) { 187 if (show_num) 188 fprintf(stdout, "%s", buf); 189 else 190 color_fprintf(stdout, color, "%s", buf); 191 } 192 } 193 return; 194error: 195 if (feof(fp)) 196 die("Source file is shorter than expected."); 197 else 198 die("File read error: %s", strerror(errno)); 199} 200 201/* 202 * Show line-range always requires debuginfo to find source file and 203 * line number. 204 */ 205void show_line_range(struct line_range *lr) 206{ 207 unsigned int l = 1; 208 struct line_node *ln; 209 FILE *fp; 210 int fd, ret; 211 212 /* Search a line range */ 213 init_vmlinux(); 214 fd = open_vmlinux(); 215 if (fd < 0) 216 die("Could not open debuginfo file."); 217 ret = find_line_range(fd, lr); 218 if (ret <= 0) 219 die("Source line is not found.\n"); 220 close(fd); 221 222 setup_pager(); 223 224 if (lr->function) 225 fprintf(stdout, "<%s:%d>\n", lr->function, 226 lr->start - lr->offset); 227 else 228 fprintf(stdout, "<%s:%d>\n", lr->file, lr->start); 229 230 fp = fopen(lr->path, "r"); 231 if (fp == NULL) 232 die("Failed to open %s: %s", lr->path, strerror(errno)); 233 /* Skip to starting line number */ 234 while (l < lr->start) 235 show_one_line(fp, l++, true, false); 236 237 list_for_each_entry(ln, &lr->line_list, list) { 238 while (ln->line > l) 239 show_one_line(fp, (l++) - lr->offset, false, false); 240 show_one_line(fp, (l++) - lr->offset, false, true); 241 } 242 243 if (lr->end == INT_MAX) 244 lr->end = l + NR_ADDITIONAL_LINES; 245 while (l < lr->end && !feof(fp)) 246 show_one_line(fp, (l++) - lr->offset, false, false); 247 248 fclose(fp); 249} 250 251#else /* !DWARF_SUPPORT */ 252 253static void convert_to_perf_probe_point(struct kprobe_trace_point *tp, 254 struct perf_probe_point *pp) 255{ 256 pp->function = xstrdup(tp->symbol); 257 pp->offset = tp->offset; 258 pp->retprobe = tp->retprobe; 259} 260 261static int try_to_find_kprobe_trace_events(struct perf_probe_event *pev, 262 struct kprobe_trace_event **tevs __unused) 263{ 264 if (perf_probe_event_need_dwarf(pev)) 265 die("Debuginfo-analysis is not supported"); 266 return 0; 267} 268 269void show_line_range(struct line_range *lr __unused) 270{ 271 die("Debuginfo-analysis is not supported"); 272} 273 274#endif 275 |
|
67void parse_line_range_desc(const char *arg, struct line_range *lr) 68{ 69 const char *ptr; 70 char *tmp; 71 /* 72 * <Syntax> 73 * SRC:SLN[+NUM|-ELN] 74 * FUNC[:SLN[+NUM|-ELN]] --- 10 unchanged lines hidden (view full) --- 85 lr->end = 0; 86 pr_debug("Line range is %u to %u\n", lr->start, lr->end); 87 if (lr->end && lr->start > lr->end) 88 semantic_error("Start line must be smaller" 89 " than end line."); 90 if (*tmp != '\0') 91 semantic_error("Tailing with invalid character '%d'.", 92 *tmp); | 276void parse_line_range_desc(const char *arg, struct line_range *lr) 277{ 278 const char *ptr; 279 char *tmp; 280 /* 281 * <Syntax> 282 * SRC:SLN[+NUM|-ELN] 283 * FUNC[:SLN[+NUM|-ELN]] --- 10 unchanged lines hidden (view full) --- 294 lr->end = 0; 295 pr_debug("Line range is %u to %u\n", lr->start, lr->end); 296 if (lr->end && lr->start > lr->end) 297 semantic_error("Start line must be smaller" 298 " than end line."); 299 if (*tmp != '\0') 300 semantic_error("Tailing with invalid character '%d'.", 301 *tmp); |
93 tmp = strndup(arg, (ptr - arg)); | 302 tmp = xstrndup(arg, (ptr - arg)); |
94 } else | 303 } else |
95 tmp = strdup(arg); | 304 tmp = xstrdup(arg); |
96 97 if (strchr(tmp, '.')) 98 lr->file = tmp; 99 else 100 lr->function = tmp; 101} 102 103/* Check the name is good for event/group */ --- 4 unchanged lines hidden (view full) --- 108 while (*++name != '\0') { 109 if (!isalpha(*name) && !isdigit(*name) && *name != '_') 110 return false; 111 } 112 return true; 113} 114 115/* Parse probepoint definition. */ | 305 306 if (strchr(tmp, '.')) 307 lr->file = tmp; 308 else 309 lr->function = tmp; 310} 311 312/* Check the name is good for event/group */ --- 4 unchanged lines hidden (view full) --- 317 while (*++name != '\0') { 318 if (!isalpha(*name) && !isdigit(*name) && *name != '_') 319 return false; 320 } 321 return true; 322} 323 324/* Parse probepoint definition. */ |
116static void parse_perf_probe_probepoint(char *arg, struct probe_point *pp) | 325static void parse_perf_probe_point(char *arg, struct perf_probe_event *pev) |
117{ | 326{ |
327 struct perf_probe_point *pp = &pev->point; |
|
118 char *ptr, *tmp; 119 char c, nc = 0; 120 /* 121 * <Syntax> 122 * perf probe [EVENT=]SRC[:LN|;PTN] 123 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] 124 * 125 * TODO:Group name support --- 4 unchanged lines hidden (view full) --- 130 *ptr = '\0'; 131 tmp = ptr + 1; 132 ptr = strchr(arg, ':'); 133 if (ptr) /* Group name is not supported yet. */ 134 semantic_error("Group name is not supported yet."); 135 if (!check_event_name(arg)) 136 semantic_error("%s is bad for event name -it must " 137 "follow C symbol-naming rule.", arg); | 328 char *ptr, *tmp; 329 char c, nc = 0; 330 /* 331 * <Syntax> 332 * perf probe [EVENT=]SRC[:LN|;PTN] 333 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] 334 * 335 * TODO:Group name support --- 4 unchanged lines hidden (view full) --- 340 *ptr = '\0'; 341 tmp = ptr + 1; 342 ptr = strchr(arg, ':'); 343 if (ptr) /* Group name is not supported yet. */ 344 semantic_error("Group name is not supported yet."); 345 if (!check_event_name(arg)) 346 semantic_error("%s is bad for event name -it must " 347 "follow C symbol-naming rule.", arg); |
138 pp->event = strdup(arg); | 348 pev->event = xstrdup(arg); 349 pev->group = NULL; |
139 arg = tmp; 140 } 141 142 ptr = strpbrk(arg, ";:+@%"); 143 if (ptr) { 144 nc = *ptr; 145 *ptr++ = '\0'; 146 } 147 148 /* Check arg is function or file and copy it */ 149 if (strchr(arg, '.')) /* File */ | 350 arg = tmp; 351 } 352 353 ptr = strpbrk(arg, ";:+@%"); 354 if (ptr) { 355 nc = *ptr; 356 *ptr++ = '\0'; 357 } 358 359 /* Check arg is function or file and copy it */ 360 if (strchr(arg, '.')) /* File */ |
150 pp->file = strdup(arg); | 361 pp->file = xstrdup(arg); |
151 else /* Function */ | 362 else /* Function */ |
152 pp->function = strdup(arg); 153 DIE_IF(pp->file == NULL && pp->function == NULL); | 363 pp->function = xstrdup(arg); |
154 155 /* Parse other options */ 156 while (ptr) { 157 arg = ptr; 158 c = nc; 159 if (c == ';') { /* Lazy pattern must be the last part */ | 364 365 /* Parse other options */ 366 while (ptr) { 367 arg = ptr; 368 c = nc; 369 if (c == ';') { /* Lazy pattern must be the last part */ |
160 pp->lazy_line = strdup(arg); | 370 pp->lazy_line = xstrdup(arg); |
161 break; 162 } 163 ptr = strpbrk(arg, ";:+@%"); 164 if (ptr) { 165 nc = *ptr; 166 *ptr++ = '\0'; 167 } 168 switch (c) { --- 7 unchanged lines hidden (view full) --- 176 pp->offset = strtoul(arg, &tmp, 0); 177 if (*tmp != '\0') 178 semantic_error("There is non-digit character" 179 " in offset."); 180 break; 181 case '@': /* File name */ 182 if (pp->file) 183 semantic_error("SRC@SRC is not allowed."); | 371 break; 372 } 373 ptr = strpbrk(arg, ";:+@%"); 374 if (ptr) { 375 nc = *ptr; 376 *ptr++ = '\0'; 377 } 378 switch (c) { --- 7 unchanged lines hidden (view full) --- 386 pp->offset = strtoul(arg, &tmp, 0); 387 if (*tmp != '\0') 388 semantic_error("There is non-digit character" 389 " in offset."); 390 break; 391 case '@': /* File name */ 392 if (pp->file) 393 semantic_error("SRC@SRC is not allowed."); |
184 pp->file = strdup(arg); 185 DIE_IF(pp->file == NULL); | 394 pp->file = xstrdup(arg); |
186 break; 187 case '%': /* Probe places */ 188 if (strcmp(arg, "return") == 0) { 189 pp->retprobe = 1; 190 } else /* Others not supported yet */ 191 semantic_error("%%%s is not supported.", arg); 192 break; 193 default: --- 21 unchanged lines hidden (view full) --- 215 216 if (pp->retprobe && !pp->function) 217 semantic_error("Return probe requires an entry function."); 218 219 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) 220 semantic_error("Offset/Line/Lazy pattern can't be used with " 221 "return probe."); 222 | 395 break; 396 case '%': /* Probe places */ 397 if (strcmp(arg, "return") == 0) { 398 pp->retprobe = 1; 399 } else /* Others not supported yet */ 400 semantic_error("%%%s is not supported.", arg); 401 break; 402 default: --- 21 unchanged lines hidden (view full) --- 424 425 if (pp->retprobe && !pp->function) 426 semantic_error("Return probe requires an entry function."); 427 428 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) 429 semantic_error("Offset/Line/Lazy pattern can't be used with " 430 "return probe."); 431 |
223 pr_debug("symbol:%s file:%s line:%d offset:%d return:%d lazy:%s\n", | 432 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, 225 pp->lazy_line); 226} 227 | 433 pp->function, pp->file, pp->line, pp->offset, pp->retprobe, 434 pp->lazy_line); 435} 436 |
228/* Parse perf-probe event definition */ 229void parse_perf_probe_event(const char *str, struct probe_point *pp, 230 bool *need_dwarf) | 437/* Parse perf-probe event argument */ 438static void parse_perf_probe_arg(const char *str, struct perf_probe_arg *arg) |
231{ | 439{ |
440 char *tmp; 441 struct perf_probe_arg_field **fieldp; 442 443 pr_debug("parsing arg: %s into ", str); 444 445 tmp = strchr(str, '='); 446 if (tmp) { 447 arg->name = xstrndup(str, tmp - str); 448 str = tmp + 1; 449 } 450 451 tmp = strpbrk(str, "-."); 452 if (!is_c_varname(str) || !tmp) { 453 /* A variable, register, symbol or special value */ 454 arg->var = xstrdup(str); 455 pr_debug("%s\n", arg->var); 456 return; 457 } 458 459 /* Structure fields */ 460 arg->var = xstrndup(str, tmp - str); 461 pr_debug("%s, ", arg->var); 462 fieldp = &arg->field; 463 464 do { 465 *fieldp = xzalloc(sizeof(struct perf_probe_arg_field)); 466 if (*tmp == '.') { 467 str = tmp + 1; 468 (*fieldp)->ref = false; 469 } else if (tmp[1] == '>') { 470 str = tmp + 2; 471 (*fieldp)->ref = true; 472 } else 473 semantic_error("Argument parse error: %s", str); 474 475 tmp = strpbrk(str, "-."); 476 if (tmp) { 477 (*fieldp)->name = xstrndup(str, tmp - str); 478 pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref); 479 fieldp = &(*fieldp)->next; 480 } 481 } while (tmp); 482 (*fieldp)->name = xstrdup(str); 483 pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref); 484} 485 486/* Parse perf-probe event command */ 487void parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev) 488{ |
|
232 char **argv; 233 int argc, i; 234 | 489 char **argv; 490 int argc, i; 491 |
235 *need_dwarf = false; 236 237 argv = argv_split(str, &argc); | 492 argv = argv_split(cmd, &argc); |
238 if (!argv) 239 die("argv_split failed."); 240 if (argc > MAX_PROBE_ARGS + 1) 241 semantic_error("Too many arguments"); 242 243 /* Parse probe point */ | 493 if (!argv) 494 die("argv_split failed."); 495 if (argc > MAX_PROBE_ARGS + 1) 496 semantic_error("Too many arguments"); 497 498 /* Parse probe point */ |
244 parse_perf_probe_probepoint(argv[0], pp); 245 if (pp->file || pp->line || pp->lazy_line) 246 *need_dwarf = true; | 499 parse_perf_probe_point(argv[0], pev); |
247 248 /* Copy arguments and ensure return probe has no C argument */ | 500 501 /* Copy arguments and ensure return probe has no C argument */ |
249 pp->nr_args = argc - 1; 250 pp->args = zalloc(sizeof(char *) * pp->nr_args); 251 for (i = 0; i < pp->nr_args; i++) { 252 pp->args[i] = strdup(argv[i + 1]); 253 if (!pp->args[i]) 254 die("Failed to copy argument."); 255 if (is_c_varname(pp->args[i])) { 256 if (pp->retprobe) 257 semantic_error("You can't specify local" 258 " variable for kretprobe"); 259 *need_dwarf = true; 260 } | 502 pev->nargs = argc - 1; 503 pev->args = xzalloc(sizeof(struct perf_probe_arg) * pev->nargs); 504 for (i = 0; i < pev->nargs; i++) { 505 parse_perf_probe_arg(argv[i + 1], &pev->args[i]); 506 if (is_c_varname(pev->args[i].var) && pev->point.retprobe) 507 semantic_error("You can't specify local variable for" 508 " kretprobe"); |
261 } 262 263 argv_free(argv); 264} 265 | 509 } 510 511 argv_free(argv); 512} 513 |
514/* Return true if this perf_probe_event requires debuginfo */ 515bool perf_probe_event_need_dwarf(struct perf_probe_event *pev) 516{ 517 int i; 518 519 if (pev->point.file || pev->point.line || pev->point.lazy_line) 520 return true; 521 522 for (i = 0; i < pev->nargs; i++) 523 if (is_c_varname(pev->args[i].var)) 524 return true; 525 526 return false; 527} 528 |
|
266/* Parse kprobe_events event into struct probe_point */ | 529/* Parse kprobe_events event into struct probe_point */ |
267void parse_trace_kprobe_event(const char *str, struct probe_point *pp) | 530void parse_kprobe_trace_command(const char *cmd, struct kprobe_trace_event *tev) |
268{ | 531{ |
532 struct kprobe_trace_point *tp = &tev->point; |
|
269 char pr; 270 char *p; 271 int ret, i, argc; 272 char **argv; 273 | 533 char pr; 534 char *p; 535 int ret, i, argc; 536 char **argv; 537 |
274 pr_debug("Parsing kprobe_events: %s\n", str); 275 argv = argv_split(str, &argc); | 538 pr_debug("Parsing kprobe_events: %s\n", cmd); 539 argv = argv_split(cmd, &argc); |
276 if (!argv) 277 die("argv_split failed."); 278 if (argc < 2) 279 semantic_error("Too less arguments."); 280 281 /* Scan event and group name. */ 282 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", | 540 if (!argv) 541 die("argv_split failed."); 542 if (argc < 2) 543 semantic_error("Too less arguments."); 544 545 /* Scan event and group name. */ 546 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", |
283 &pr, (float *)(void *)&pp->group, 284 (float *)(void *)&pp->event); | 547 &pr, (float *)(void *)&tev->group, 548 (float *)(void *)&tev->event); |
285 if (ret != 3) 286 semantic_error("Failed to parse event name: %s", argv[0]); | 549 if (ret != 3) 550 semantic_error("Failed to parse event name: %s", argv[0]); |
287 pr_debug("Group:%s Event:%s probe:%c\n", pp->group, pp->event, pr); | 551 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); |
288 | 552 |
289 pp->retprobe = (pr == 'r'); | 553 tp->retprobe = (pr == 'r'); |
290 291 /* Scan function name and offset */ | 554 555 /* Scan function name and offset */ |
292 ret = sscanf(argv[1], "%a[^+]+%d", (float *)(void *)&pp->function, 293 &pp->offset); | 556 ret = sscanf(argv[1], "%a[^+]+%lu", (float *)(void *)&tp->symbol, 557 &tp->offset); |
294 if (ret == 1) | 558 if (ret == 1) |
295 pp->offset = 0; | 559 tp->offset = 0; |
296 | 560 |
297 /* kprobe_events doesn't have this information */ 298 pp->line = 0; 299 pp->file = NULL; 300 301 pp->nr_args = argc - 2; 302 pp->args = zalloc(sizeof(char *) * pp->nr_args); 303 for (i = 0; i < pp->nr_args; i++) { | 561 tev->nargs = argc - 2; 562 tev->args = xzalloc(sizeof(struct kprobe_trace_arg) * tev->nargs); 563 for (i = 0; i < tev->nargs; i++) { |
304 p = strchr(argv[i + 2], '='); 305 if (p) /* We don't need which register is assigned. */ | 564 p = strchr(argv[i + 2], '='); 565 if (p) /* We don't need which register is assigned. */ |
306 *p = '\0'; 307 pp->args[i] = strdup(argv[i + 2]); 308 if (!pp->args[i]) 309 die("Failed to copy argument."); | 566 *p++ = '\0'; 567 else 568 p = argv[i + 2]; 569 tev->args[i].name = xstrdup(argv[i + 2]); 570 /* TODO: parse regs and offset */ 571 tev->args[i].value = xstrdup(p); |
310 } 311 312 argv_free(argv); 313} 314 | 572 } 573 574 argv_free(argv); 575} 576 |
315/* Synthesize only probe point (not argument) */ 316int synthesize_perf_probe_point(struct probe_point *pp) | 577/* Compose only probe arg */ 578int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len) |
317{ | 579{ |
318 char *buf; 319 char offs[64] = "", line[64] = ""; | 580 struct perf_probe_arg_field *field = pa->field; |
320 int ret; | 581 int ret; |
582 char *tmp = buf; |
|
321 | 583 |
322 pp->probes[0] = buf = zalloc(MAX_CMDLEN); 323 pp->found = 1; 324 if (!buf) 325 die("Failed to allocate memory by zalloc."); | 584 if (pa->name && pa->var) 585 ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var); 586 else 587 ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var); 588 if (ret <= 0) 589 goto error; 590 tmp += ret; 591 len -= ret; 592 593 while (field) { 594 ret = e_snprintf(tmp, len, "%s%s", field->ref ? "->" : ".", 595 field->name); 596 if (ret <= 0) 597 goto error; 598 tmp += ret; 599 len -= ret; 600 field = field->next; 601 } 602 return tmp - buf; 603error: 604 die("Failed to synthesize perf probe argument: %s", strerror(-ret)); 605} 606 607/* Compose only probe point (not argument) */ 608static char *synthesize_perf_probe_point(struct perf_probe_point *pp) 609{ 610 char *buf, *tmp; 611 char offs[32] = "", line[32] = "", file[32] = ""; 612 int ret, len; 613 614 buf = xzalloc(MAX_CMDLEN); |
326 if (pp->offset) { | 615 if (pp->offset) { |
327 ret = e_snprintf(offs, 64, "+%d", pp->offset); | 616 ret = e_snprintf(offs, 32, "+%lu", pp->offset); |
328 if (ret <= 0) 329 goto error; 330 } 331 if (pp->line) { | 617 if (ret <= 0) 618 goto error; 619 } 620 if (pp->line) { |
332 ret = e_snprintf(line, 64, ":%d", pp->line); | 621 ret = e_snprintf(line, 32, ":%d", pp->line); |
333 if (ret <= 0) 334 goto error; 335 } | 622 if (ret <= 0) 623 goto error; 624 } |
625 if (pp->file) { 626 len = strlen(pp->file) - 32; 627 if (len < 0) 628 len = 0; 629 tmp = strchr(pp->file + len, '/'); 630 if (!tmp) 631 tmp = pp->file + len - 1; 632 ret = e_snprintf(file, 32, "@%s", tmp + 1); 633 if (ret <= 0) 634 goto error; 635 } |
|
336 337 if (pp->function) | 636 637 if (pp->function) |
338 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s", pp->function, 339 offs, pp->retprobe ? "%return" : "", line); | 638 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function, 639 offs, pp->retprobe ? "%return" : "", line, 640 file); |
340 else | 641 else |
341 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", pp->file, line); 342 if (ret <= 0) { | 642 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line); 643 if (ret <= 0) 644 goto error; 645 646 return buf; |
343error: | 647error: |
344 free(pp->probes[0]); 345 pp->probes[0] = NULL; 346 pp->found = 0; 347 } 348 return ret; | 648 die("Failed to synthesize perf probe point: %s", strerror(-ret)); |
349} 350 | 649} 650 |
351int synthesize_perf_probe_event(struct probe_point *pp) | 651#if 0 652char *synthesize_perf_probe_command(struct perf_probe_event *pev) |
352{ 353 char *buf; 354 int i, len, ret; 355 | 653{ 654 char *buf; 655 int i, len, ret; 656 |
356 len = synthesize_perf_probe_point(pp); 357 if (len < 0) 358 return 0; | 657 buf = synthesize_perf_probe_point(&pev->point); 658 if (!buf) 659 return NULL; |
359 | 660 |
360 buf = pp->probes[0]; 361 for (i = 0; i < pp->nr_args; i++) { | 661 len = strlen(buf); 662 for (i = 0; i < pev->nargs; i++) { |
362 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", | 663 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", |
363 pp->args[i]); 364 if (ret <= 0) 365 goto error; | 664 pev->args[i].name); 665 if (ret <= 0) { 666 free(buf); 667 return NULL; 668 } |
366 len += ret; 367 } | 669 len += ret; 670 } |
368 pp->found = 1; | |
369 | 671 |
370 return pp->found; 371error: 372 free(pp->probes[0]); 373 pp->probes[0] = NULL; | 672 return buf; 673} 674#endif |
374 | 675 |
375 return ret; | 676static int __synthesize_kprobe_trace_arg_ref(struct kprobe_trace_arg_ref *ref, 677 char **buf, size_t *buflen, 678 int depth) 679{ 680 int ret; 681 if (ref->next) { 682 depth = __synthesize_kprobe_trace_arg_ref(ref->next, buf, 683 buflen, depth + 1); 684 if (depth < 0) 685 goto out; 686 } 687 688 ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset); 689 if (ret < 0) 690 depth = ret; 691 else { 692 *buf += ret; 693 *buflen -= ret; 694 } 695out: 696 return depth; 697 |
376} 377 | 698} 699 |
378int synthesize_trace_kprobe_event(struct probe_point *pp) | 700static int synthesize_kprobe_trace_arg(struct kprobe_trace_arg *arg, 701 char *buf, size_t buflen) |
379{ | 702{ |
703 int ret, depth = 0; 704 char *tmp = buf; 705 706 /* Argument name or separator */ 707 if (arg->name) 708 ret = e_snprintf(buf, buflen, " %s=", arg->name); 709 else 710 ret = e_snprintf(buf, buflen, " "); 711 if (ret < 0) 712 return ret; 713 buf += ret; 714 buflen -= ret; 715 716 /* Dereferencing arguments */ 717 if (arg->ref) { 718 depth = __synthesize_kprobe_trace_arg_ref(arg->ref, &buf, 719 &buflen, 1); 720 if (depth < 0) 721 return depth; 722 } 723 724 /* Print argument value */ 725 ret = e_snprintf(buf, buflen, "%s", arg->value); 726 if (ret < 0) 727 return ret; 728 buf += ret; 729 buflen -= ret; 730 731 /* Closing */ 732 while (depth--) { 733 ret = e_snprintf(buf, buflen, ")"); 734 if (ret < 0) 735 return ret; 736 buf += ret; 737 buflen -= ret; 738 } 739 740 return buf - tmp; 741} 742 743char *synthesize_kprobe_trace_command(struct kprobe_trace_event *tev) 744{ 745 struct kprobe_trace_point *tp = &tev->point; |
|
380 char *buf; 381 int i, len, ret; 382 | 746 char *buf; 747 int i, len, ret; 748 |
383 pp->probes[0] = buf = zalloc(MAX_CMDLEN); 384 if (!buf) 385 die("Failed to allocate memory by zalloc."); 386 ret = e_snprintf(buf, MAX_CMDLEN, "%s+%d", pp->function, pp->offset); 387 if (ret <= 0) | 749 buf = xzalloc(MAX_CMDLEN); 750 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s+%lu", 751 tp->retprobe ? 'r' : 'p', 752 tev->group, tev->event, 753 tp->symbol, tp->offset); 754 if (len <= 0) |
388 goto error; | 755 goto error; |
389 len = ret; | |
390 | 756 |
391 for (i = 0; i < pp->nr_args; i++) { 392 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", 393 pp->args[i]); | 757 for (i = 0; i < tev->nargs; i++) { 758 ret = synthesize_kprobe_trace_arg(&tev->args[i], buf + len, 759 MAX_CMDLEN - len); |
394 if (ret <= 0) 395 goto error; 396 len += ret; 397 } | 760 if (ret <= 0) 761 goto error; 762 len += ret; 763 } |
398 pp->found = 1; | |
399 | 764 |
400 return pp->found; | 765 return buf; |
401error: | 766error: |
402 free(pp->probes[0]); 403 pp->probes[0] = NULL; | 767 free(buf); 768 return NULL; 769} |
404 | 770 |
405 return ret; | 771void convert_to_perf_probe_event(struct kprobe_trace_event *tev, 772 struct perf_probe_event *pev) 773{ 774 char buf[64]; 775 int i; 776 777 /* Convert event/group name */ 778 pev->event = xstrdup(tev->event); 779 pev->group = xstrdup(tev->group); 780 781 /* Convert trace_point to probe_point */ 782 convert_to_perf_probe_point(&tev->point, &pev->point); 783 784 /* Convert trace_arg to probe_arg */ 785 pev->nargs = tev->nargs; 786 pev->args = xzalloc(sizeof(struct perf_probe_arg) * pev->nargs); 787 for (i = 0; i < tev->nargs; i++) 788 if (tev->args[i].name) 789 pev->args[i].name = xstrdup(tev->args[i].name); 790 else { 791 synthesize_kprobe_trace_arg(&tev->args[i], buf, 64); 792 pev->args[i].name = xstrdup(buf); 793 } |
406} 407 | 794} 795 |
408static int open_kprobe_events(int flags, int mode) | 796void clear_perf_probe_event(struct perf_probe_event *pev) |
409{ | 797{ |
798 struct perf_probe_point *pp = &pev->point; 799 struct perf_probe_arg_field *field, *next; 800 int i; 801 802 if (pev->event) 803 free(pev->event); 804 if (pev->group) 805 free(pev->group); 806 if (pp->file) 807 free(pp->file); 808 if (pp->function) 809 free(pp->function); 810 if (pp->lazy_line) 811 free(pp->lazy_line); 812 for (i = 0; i < pev->nargs; i++) { 813 if (pev->args[i].name) 814 free(pev->args[i].name); 815 if (pev->args[i].var) 816 free(pev->args[i].var); 817 field = pev->args[i].field; 818 while (field) { 819 next = field->next; 820 if (field->name) 821 free(field->name); 822 free(field); 823 field = next; 824 } 825 } 826 if (pev->args) 827 free(pev->args); 828 memset(pev, 0, sizeof(*pev)); 829} 830 831void clear_kprobe_trace_event(struct kprobe_trace_event *tev) 832{ 833 struct kprobe_trace_arg_ref *ref, *next; 834 int i; 835 836 if (tev->event) 837 free(tev->event); 838 if (tev->group) 839 free(tev->group); 840 if (tev->point.symbol) 841 free(tev->point.symbol); 842 for (i = 0; i < tev->nargs; i++) { 843 if (tev->args[i].name) 844 free(tev->args[i].name); 845 if (tev->args[i].value) 846 free(tev->args[i].value); 847 ref = tev->args[i].ref; 848 while (ref) { 849 next = ref->next; 850 free(ref); 851 ref = next; 852 } 853 } 854 if (tev->args) 855 free(tev->args); 856 memset(tev, 0, sizeof(*tev)); 857} 858 859static int open_kprobe_events(bool readwrite) 860{ |
|
410 char buf[PATH_MAX]; 411 int ret; 412 413 ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path); 414 if (ret < 0) 415 die("Failed to make kprobe_events path."); 416 | 861 char buf[PATH_MAX]; 862 int ret; 863 864 ret = e_snprintf(buf, PATH_MAX, "%s/../kprobe_events", debugfs_path); 865 if (ret < 0) 866 die("Failed to make kprobe_events path."); 867 |
417 ret = open(buf, flags, mode); | 868 if (readwrite && !probe_event_dry_run) 869 ret = open(buf, O_RDWR, O_APPEND); 870 else 871 ret = open(buf, O_RDONLY, 0); 872 |
418 if (ret < 0) { 419 if (errno == ENOENT) 420 die("kprobe_events file does not exist -" 421 " please rebuild with CONFIG_KPROBE_EVENT."); 422 else 423 die("Could not open kprobe_events file: %s", 424 strerror(errno)); 425 } 426 return ret; 427} 428 429/* Get raw string list of current kprobe_events */ | 873 if (ret < 0) { 874 if (errno == ENOENT) 875 die("kprobe_events file does not exist -" 876 " please rebuild with CONFIG_KPROBE_EVENT."); 877 else 878 die("Could not open kprobe_events file: %s", 879 strerror(errno)); 880 } 881 return ret; 882} 883 884/* Get raw string list of current kprobe_events */ |
430static struct strlist *get_trace_kprobe_event_rawlist(int fd) | 885static struct strlist *get_kprobe_trace_command_rawlist(int fd) |
431{ 432 int ret, idx; 433 FILE *fp; 434 char buf[MAX_CMDLEN]; 435 char *p; 436 struct strlist *sl; 437 438 sl = strlist__new(true, NULL); --- 11 unchanged lines hidden (view full) --- 450 if (ret < 0) 451 die("strlist__add failed: %s", strerror(-ret)); 452 } 453 fclose(fp); 454 455 return sl; 456} 457 | 886{ 887 int ret, idx; 888 FILE *fp; 889 char buf[MAX_CMDLEN]; 890 char *p; 891 struct strlist *sl; 892 893 sl = strlist__new(true, NULL); --- 11 unchanged lines hidden (view full) --- 905 if (ret < 0) 906 die("strlist__add failed: %s", strerror(-ret)); 907 } 908 fclose(fp); 909 910 return sl; 911} 912 |
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 */ | 913/* Show an event */ |
483static void show_perf_probe_event(const char *event, const char *place, 484 struct probe_point *pp) | 914static void show_perf_probe_event(struct perf_probe_event *pev) |
485{ 486 int i, ret; 487 char buf[128]; | 915{ 916 int i, ret; 917 char buf[128]; |
918 char *place; |
|
488 | 919 |
489 ret = e_snprintf(buf, 128, "%s:%s", pp->group, event); | 920 /* Synthesize only event probe point */ 921 place = synthesize_perf_probe_point(&pev->point); 922 923 ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event); |
490 if (ret < 0) 491 die("Failed to copy event: %s", strerror(-ret)); | 924 if (ret < 0) 925 die("Failed to copy event: %s", strerror(-ret)); |
492 printf(" %-40s (on %s", buf, place); | 926 printf(" %-20s (on %s", buf, place); |
493 | 927 |
494 if (pp->nr_args > 0) { | 928 if (pev->nargs > 0) { |
495 printf(" with"); | 929 printf(" with"); |
496 for (i = 0; i < pp->nr_args; i++) 497 printf(" %s", pp->args[i]); | 930 for (i = 0; i < pev->nargs; i++) { 931 synthesize_perf_probe_arg(&pev->args[i], buf, 128); 932 printf(" %s", buf); 933 } |
498 } 499 printf(")\n"); | 934 } 935 printf(")\n"); |
936 free(place); |
|
500} 501 502/* List up current perf-probe events */ 503void show_perf_probe_events(void) 504{ 505 int fd; | 937} 938 939/* List up current perf-probe events */ 940void show_perf_probe_events(void) 941{ 942 int fd; |
506 struct probe_point pp; | 943 struct kprobe_trace_event tev; 944 struct perf_probe_event pev; |
507 struct strlist *rawlist; 508 struct str_node *ent; 509 510 setup_pager(); | 945 struct strlist *rawlist; 946 struct str_node *ent; 947 948 setup_pager(); |
511 memset(&pp, 0, sizeof(pp)); | 949 init_vmlinux(); |
512 | 950 |
513 fd = open_kprobe_events(O_RDONLY, 0); 514 rawlist = get_trace_kprobe_event_rawlist(fd); | 951 memset(&tev, 0, sizeof(tev)); 952 memset(&pev, 0, sizeof(pev)); 953 954 fd = open_kprobe_events(false); 955 rawlist = get_kprobe_trace_command_rawlist(fd); |
515 close(fd); 516 517 strlist__for_each(ent, rawlist) { | 956 close(fd); 957 958 strlist__for_each(ent, rawlist) { |
518 parse_trace_kprobe_event(ent->s, &pp); 519 /* Synthesize only event probe point */ 520 synthesize_perf_probe_point(&pp); | 959 parse_kprobe_trace_command(ent->s, &tev); 960 convert_to_perf_probe_event(&tev, &pev); |
521 /* Show an event */ | 961 /* Show an event */ |
522 show_perf_probe_event(pp.event, pp.probes[0], &pp); 523 clear_probe_point(&pp); | 962 show_perf_probe_event(&pev); 963 clear_perf_probe_event(&pev); 964 clear_kprobe_trace_event(&tev); |
524 } 525 526 strlist__delete(rawlist); 527} 528 529/* Get current perf-probe event names */ | 965 } 966 967 strlist__delete(rawlist); 968} 969 970/* Get current perf-probe event names */ |
530static struct strlist *get_perf_event_names(int fd, bool include_group) | 971static struct strlist *get_kprobe_trace_event_names(int fd, bool include_group) |
531{ 532 char buf[128]; 533 struct strlist *sl, *rawlist; 534 struct str_node *ent; | 972{ 973 char buf[128]; 974 struct strlist *sl, *rawlist; 975 struct str_node *ent; |
535 struct probe_point pp; | 976 struct kprobe_trace_event tev; |
536 | 977 |
537 memset(&pp, 0, sizeof(pp)); 538 rawlist = get_trace_kprobe_event_rawlist(fd); | 978 memset(&tev, 0, sizeof(tev)); |
539 | 979 |
980 rawlist = get_kprobe_trace_command_rawlist(fd); |
|
540 sl = strlist__new(true, NULL); 541 strlist__for_each(ent, rawlist) { | 981 sl = strlist__new(true, NULL); 982 strlist__for_each(ent, rawlist) { |
542 parse_trace_kprobe_event(ent->s, &pp); | 983 parse_kprobe_trace_command(ent->s, &tev); |
543 if (include_group) { | 984 if (include_group) { |
544 if (e_snprintf(buf, 128, "%s:%s", pp.group, 545 pp.event) < 0) | 985 if (e_snprintf(buf, 128, "%s:%s", tev.group, 986 tev.event) < 0) |
546 die("Failed to copy group:event name."); 547 strlist__add(sl, buf); 548 } else | 987 die("Failed to copy group:event name."); 988 strlist__add(sl, buf); 989 } else |
549 strlist__add(sl, pp.event); 550 clear_probe_point(&pp); | 990 strlist__add(sl, tev.event); 991 clear_kprobe_trace_event(&tev); |
551 } 552 553 strlist__delete(rawlist); 554 555 return sl; 556} 557 | 992 } 993 994 strlist__delete(rawlist); 995 996 return sl; 997} 998 |
558static void write_trace_kprobe_event(int fd, const char *buf) | 999static void write_kprobe_trace_event(int fd, struct kprobe_trace_event *tev) |
559{ 560 int ret; | 1000{ 1001 int ret; |
1002 char *buf = synthesize_kprobe_trace_command(tev); |
|
561 562 pr_debug("Writing event: %s\n", buf); | 1003 1004 pr_debug("Writing event: %s\n", buf); |
563 ret = write(fd, buf, strlen(buf)); 564 if (ret <= 0) 565 die("Failed to write event: %s", strerror(errno)); | 1005 if (!probe_event_dry_run) { 1006 ret = write(fd, buf, strlen(buf)); 1007 if (ret <= 0) 1008 die("Failed to write event: %s", strerror(errno)); 1009 } 1010 free(buf); |
566} 567 568static void get_new_event_name(char *buf, size_t len, const char *base, 569 struct strlist *namelist, bool allow_suffix) 570{ 571 int i, ret; 572 573 /* Try no suffix */ --- 16 unchanged lines hidden (view full) --- 590 die("snprintf() failed: %s", strerror(-ret)); 591 if (!strlist__has_entry(namelist, buf)) 592 break; 593 } 594 if (i == MAX_EVENT_INDEX) 595 die("Too many events are on the same function."); 596} 597 | 1011} 1012 1013static void get_new_event_name(char *buf, size_t len, const char *base, 1014 struct strlist *namelist, bool allow_suffix) 1015{ 1016 int i, ret; 1017 1018 /* Try no suffix */ --- 16 unchanged lines hidden (view full) --- 1035 die("snprintf() failed: %s", strerror(-ret)); 1036 if (!strlist__has_entry(namelist, buf)) 1037 break; 1038 } 1039 if (i == MAX_EVENT_INDEX) 1040 die("Too many events are on the same function."); 1041} 1042 |
598void add_trace_kprobe_events(struct probe_point *probes, int nr_probes, 599 bool force_add) | 1043static void __add_kprobe_trace_events(struct perf_probe_event *pev, 1044 struct kprobe_trace_event *tevs, 1045 int ntevs, bool allow_suffix) |
600{ | 1046{ |
601 int i, j, fd; 602 struct probe_point *pp; 603 char buf[MAX_CMDLEN]; 604 char event[64]; | 1047 int i, fd; 1048 struct kprobe_trace_event *tev = NULL; 1049 char buf[64]; 1050 const char *event, *group; |
605 struct strlist *namelist; | 1051 struct strlist *namelist; |
606 bool allow_suffix; | |
607 | 1052 |
608 fd = open_kprobe_events(O_RDWR, O_APPEND); | 1053 fd = open_kprobe_events(true); |
609 /* Get current event names */ | 1054 /* Get current event names */ |
610 namelist = get_perf_event_names(fd, false); | 1055 namelist = get_kprobe_trace_event_names(fd, false); |
611 | 1056 |
612 for (j = 0; j < nr_probes; j++) { 613 pp = probes + j; 614 if (!pp->event) 615 pp->event = strdup(pp->function); 616 if (!pp->group) 617 pp->group = strdup(PERFPROBE_GROUP); 618 DIE_IF(!pp->event || !pp->group); 619 /* If force_add is true, suffix search is allowed */ 620 allow_suffix = force_add; 621 for (i = 0; i < pp->found; i++) { 622 /* Get an unused new event name */ 623 get_new_event_name(event, 64, pp->event, namelist, 624 allow_suffix); 625 snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s\n", 626 pp->retprobe ? 'r' : 'p', 627 pp->group, event, 628 pp->probes[i]); 629 write_trace_kprobe_event(fd, buf); 630 printf("Added new event:\n"); 631 /* Get the first parameter (probe-point) */ 632 sscanf(pp->probes[i], "%s", buf); 633 show_perf_probe_event(event, buf, pp); 634 /* Add added event name to namelist */ 635 strlist__add(namelist, event); 636 /* 637 * Probes after the first probe which comes from same 638 * user input are always allowed to add suffix, because 639 * there might be several addresses corresponding to 640 * one code line. 641 */ 642 allow_suffix = true; 643 } | 1057 printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":"); 1058 for (i = 0; i < ntevs; i++) { 1059 tev = &tevs[i]; 1060 if (pev->event) 1061 event = pev->event; 1062 else 1063 if (pev->point.function) 1064 event = pev->point.function; 1065 else 1066 event = tev->point.symbol; 1067 if (pev->group) 1068 group = pev->group; 1069 else 1070 group = PERFPROBE_GROUP; 1071 1072 /* Get an unused new event name */ 1073 get_new_event_name(buf, 64, event, namelist, allow_suffix); 1074 event = buf; 1075 1076 tev->event = xstrdup(event); 1077 tev->group = xstrdup(group); 1078 write_kprobe_trace_event(fd, tev); 1079 /* Add added event name to namelist */ 1080 strlist__add(namelist, event); 1081 1082 /* Trick here - save current event/group */ 1083 event = pev->event; 1084 group = pev->group; 1085 pev->event = tev->event; 1086 pev->group = tev->group; 1087 show_perf_probe_event(pev); 1088 /* Trick here - restore current event/group */ 1089 pev->event = (char *)event; 1090 pev->group = (char *)group; 1091 1092 /* 1093 * Probes after the first probe which comes from same 1094 * user input are always allowed to add suffix, because 1095 * there might be several addresses corresponding to 1096 * one code line. 1097 */ 1098 allow_suffix = true; |
644 } 645 /* Show how to use the event. */ 646 printf("\nYou can now use it on all perf tools, such as:\n\n"); | 1099 } 1100 /* Show how to use the event. */ 1101 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); | 1102 printf("\tperf record -e %s:%s -a sleep 1\n\n", tev->group, tev->event); |
648 649 strlist__delete(namelist); 650 close(fd); 651} 652 | 1103 1104 strlist__delete(namelist); 1105 close(fd); 1106} 1107 |
1108static int convert_to_kprobe_trace_events(struct perf_probe_event *pev, 1109 struct kprobe_trace_event **tevs) 1110{ 1111 struct symbol *sym; 1112 int ntevs = 0, i; 1113 struct kprobe_trace_event *tev; 1114 1115 /* Convert perf_probe_event with debuginfo */ 1116 ntevs = try_to_find_kprobe_trace_events(pev, tevs); 1117 if (ntevs > 0) 1118 return ntevs; 1119 1120 /* Allocate trace event buffer */ 1121 ntevs = 1; 1122 tev = *tevs = xzalloc(sizeof(struct kprobe_trace_event)); 1123 1124 /* Copy parameters */ 1125 tev->point.symbol = xstrdup(pev->point.function); 1126 tev->point.offset = pev->point.offset; 1127 tev->nargs = pev->nargs; 1128 if (tev->nargs) { 1129 tev->args = xzalloc(sizeof(struct kprobe_trace_arg) 1130 * tev->nargs); 1131 for (i = 0; i < tev->nargs; i++) { 1132 if (pev->args[i].name) 1133 tev->args[i].name = xstrdup(pev->args[i].name); 1134 tev->args[i].value = xstrdup(pev->args[i].var); 1135 } 1136 } 1137 1138 /* Currently just checking function name from symbol map */ 1139 sym = map__find_symbol_by_name(kmaps[MAP__FUNCTION], 1140 tev->point.symbol, NULL); 1141 if (!sym) 1142 die("Kernel symbol \'%s\' not found - probe not added.", 1143 tev->point.symbol); 1144 1145 return ntevs; 1146} 1147 1148struct __event_package { 1149 struct perf_probe_event *pev; 1150 struct kprobe_trace_event *tevs; 1151 int ntevs; 1152}; 1153 1154void add_perf_probe_events(struct perf_probe_event *pevs, int npevs, 1155 bool force_add) 1156{ 1157 int i; 1158 struct __event_package *pkgs; 1159 1160 pkgs = xzalloc(sizeof(struct __event_package) * npevs); 1161 1162 /* Init vmlinux path */ 1163 init_vmlinux(); 1164 1165 /* Loop 1: convert all events */ 1166 for (i = 0; i < npevs; i++) { 1167 pkgs[i].pev = &pevs[i]; 1168 /* Convert with or without debuginfo */ 1169 pkgs[i].ntevs = convert_to_kprobe_trace_events(pkgs[i].pev, 1170 &pkgs[i].tevs); 1171 } 1172 1173 /* Loop 2: add all events */ 1174 for (i = 0; i < npevs; i++) 1175 __add_kprobe_trace_events(pkgs[i].pev, pkgs[i].tevs, 1176 pkgs[i].ntevs, force_add); 1177 /* TODO: cleanup all trace events? */ 1178} 1179 |
|
653static void __del_trace_kprobe_event(int fd, struct str_node *ent) 654{ 655 char *p; 656 char buf[128]; | 1180static void __del_trace_kprobe_event(int fd, struct str_node *ent) 1181{ 1182 char *p; 1183 char buf[128]; |
1184 int ret; |
|
657 658 /* Convert from perf-probe event to trace-kprobe event */ 659 if (e_snprintf(buf, 128, "-:%s", ent->s) < 0) 660 die("Failed to copy event."); 661 p = strchr(buf + 2, ':'); 662 if (!p) 663 die("Internal error: %s should have ':' but not.", ent->s); 664 *p = '/'; 665 | 1185 1186 /* Convert from perf-probe event to trace-kprobe event */ 1187 if (e_snprintf(buf, 128, "-:%s", ent->s) < 0) 1188 die("Failed to copy event."); 1189 p = strchr(buf + 2, ':'); 1190 if (!p) 1191 die("Internal error: %s should have ':' but not.", ent->s); 1192 *p = '/'; 1193 |
666 write_trace_kprobe_event(fd, buf); | 1194 pr_debug("Writing event: %s\n", buf); 1195 ret = write(fd, buf, strlen(buf)); 1196 if (ret <= 0) 1197 die("Failed to write event: %s", strerror(errno)); |
667 printf("Remove event: %s\n", ent->s); 668} 669 670static void del_trace_kprobe_event(int fd, const char *group, 671 const char *event, struct strlist *namelist) 672{ 673 char buf[128]; 674 struct str_node *ent, *n; --- 16 unchanged lines hidden (view full) --- 691 __del_trace_kprobe_event(fd, ent); 692 strlist__remove(namelist, ent); 693 } 694 } 695 if (found == 0) 696 pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf); 697} 698 | 1198 printf("Remove event: %s\n", ent->s); 1199} 1200 1201static void del_trace_kprobe_event(int fd, const char *group, 1202 const char *event, struct strlist *namelist) 1203{ 1204 char buf[128]; 1205 struct str_node *ent, *n; --- 16 unchanged lines hidden (view full) --- 1222 __del_trace_kprobe_event(fd, ent); 1223 strlist__remove(namelist, ent); 1224 } 1225 } 1226 if (found == 0) 1227 pr_info("Info: event \"%s\" does not exist, could not remove it.\n", buf); 1228} 1229 |
699void del_trace_kprobe_events(struct strlist *dellist) | 1230void del_perf_probe_events(struct strlist *dellist) |
700{ 701 int fd; 702 const char *group, *event; 703 char *p, *str; 704 struct str_node *ent; 705 struct strlist *namelist; 706 | 1231{ 1232 int fd; 1233 const char *group, *event; 1234 char *p, *str; 1235 struct str_node *ent; 1236 struct strlist *namelist; 1237 |
707 fd = open_kprobe_events(O_RDWR, O_APPEND); | 1238 fd = open_kprobe_events(true); |
708 /* Get current event names */ | 1239 /* Get current event names */ |
709 namelist = get_perf_event_names(fd, true); | 1240 namelist = get_kprobe_trace_event_names(fd, true); |
710 711 strlist__for_each(ent, dellist) { | 1241 1242 strlist__for_each(ent, dellist) { |
712 str = strdup(ent->s); 713 if (!str) 714 die("Failed to copy event."); | 1243 str = xstrdup(ent->s); |
715 pr_debug("Parsing: %s\n", str); 716 p = strchr(str, ':'); 717 if (p) { 718 group = str; 719 *p = '\0'; 720 event = p + 1; 721 } else { 722 group = "*"; 723 event = str; 724 } 725 pr_debug("Group: %s, Event: %s\n", group, event); 726 del_trace_kprobe_event(fd, group, event, namelist); 727 free(str); 728 } 729 strlist__delete(namelist); 730 close(fd); 731} 732 | 1244 pr_debug("Parsing: %s\n", str); 1245 p = strchr(str, ':'); 1246 if (p) { 1247 group = str; 1248 *p = '\0'; 1249 event = p + 1; 1250 } else { 1251 group = "*"; 1252 event = str; 1253 } 1254 pr_debug("Group: %s, Event: %s\n", group, event); 1255 del_trace_kprobe_event(fd, group, event, namelist); 1256 free(str); 1257 } 1258 strlist__delete(namelist); 1259 close(fd); 1260} 1261 |
733#define LINEBUF_SIZE 256 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} 768 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} | |