1 #include "../perf.h" 2 #include "util.h" 3 #include "debug.h" 4 #include <api/fs/fs.h> 5 #include <sys/mman.h> 6 #ifdef HAVE_BACKTRACE_SUPPORT 7 #include <execinfo.h> 8 #endif 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 #include <errno.h> 13 #include <limits.h> 14 #include <byteswap.h> 15 #include <linux/kernel.h> 16 #include <unistd.h> 17 #include "callchain.h" 18 19 struct callchain_param callchain_param = { 20 .mode = CHAIN_GRAPH_REL, 21 .min_percent = 0.5, 22 .order = ORDER_CALLEE, 23 .key = CCKEY_FUNCTION 24 }; 25 26 /* 27 * XXX We need to find a better place for these things... 28 */ 29 unsigned int page_size; 30 int cacheline_size; 31 32 bool test_attr__enabled; 33 34 bool perf_host = true; 35 bool perf_guest = false; 36 37 char tracing_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing"; 38 char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events"; 39 40 void event_attr_init(struct perf_event_attr *attr) 41 { 42 if (!perf_host) 43 attr->exclude_host = 1; 44 if (!perf_guest) 45 attr->exclude_guest = 1; 46 /* to capture ABI version */ 47 attr->size = sizeof(*attr); 48 } 49 50 int mkdir_p(char *path, mode_t mode) 51 { 52 struct stat st; 53 int err; 54 char *d = path; 55 56 if (*d != '/') 57 return -1; 58 59 if (stat(path, &st) == 0) 60 return 0; 61 62 while (*++d == '/'); 63 64 while ((d = strchr(d, '/'))) { 65 *d = '\0'; 66 err = stat(path, &st) && mkdir(path, mode); 67 *d++ = '/'; 68 if (err) 69 return -1; 70 while (*d == '/') 71 ++d; 72 } 73 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0; 74 } 75 76 int rm_rf(char *path) 77 { 78 DIR *dir; 79 int ret = 0; 80 struct dirent *d; 81 char namebuf[PATH_MAX]; 82 83 dir = opendir(path); 84 if (dir == NULL) 85 return 0; 86 87 while ((d = readdir(dir)) != NULL && !ret) { 88 struct stat statbuf; 89 90 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) 91 continue; 92 93 scnprintf(namebuf, sizeof(namebuf), "%s/%s", 94 path, d->d_name); 95 96 ret = stat(namebuf, &statbuf); 97 if (ret < 0) { 98 pr_debug("stat failed: %s\n", namebuf); 99 break; 100 } 101 102 if (S_ISREG(statbuf.st_mode)) 103 ret = unlink(namebuf); 104 else if (S_ISDIR(statbuf.st_mode)) 105 ret = rm_rf(namebuf); 106 else { 107 pr_debug("unknown file: %s\n", namebuf); 108 ret = -1; 109 } 110 } 111 closedir(dir); 112 113 if (ret < 0) 114 return ret; 115 116 return rmdir(path); 117 } 118 119 static int slow_copyfile(const char *from, const char *to) 120 { 121 int err = -1; 122 char *line = NULL; 123 size_t n; 124 FILE *from_fp = fopen(from, "r"), *to_fp; 125 126 if (from_fp == NULL) 127 goto out; 128 129 to_fp = fopen(to, "w"); 130 if (to_fp == NULL) 131 goto out_fclose_from; 132 133 while (getline(&line, &n, from_fp) > 0) 134 if (fputs(line, to_fp) == EOF) 135 goto out_fclose_to; 136 err = 0; 137 out_fclose_to: 138 fclose(to_fp); 139 free(line); 140 out_fclose_from: 141 fclose(from_fp); 142 out: 143 return err; 144 } 145 146 int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) 147 { 148 void *ptr; 149 loff_t pgoff; 150 151 pgoff = off_in & ~(page_size - 1); 152 off_in -= pgoff; 153 154 ptr = mmap(NULL, off_in + size, PROT_READ, MAP_PRIVATE, ifd, pgoff); 155 if (ptr == MAP_FAILED) 156 return -1; 157 158 while (size) { 159 ssize_t ret = pwrite(ofd, ptr + off_in, size, off_out); 160 if (ret < 0 && errno == EINTR) 161 continue; 162 if (ret <= 0) 163 break; 164 165 size -= ret; 166 off_in += ret; 167 off_out -= ret; 168 } 169 munmap(ptr, off_in + size); 170 171 return size ? -1 : 0; 172 } 173 174 int copyfile_mode(const char *from, const char *to, mode_t mode) 175 { 176 int fromfd, tofd; 177 struct stat st; 178 int err = -1; 179 char *tmp = NULL, *ptr = NULL; 180 181 if (stat(from, &st)) 182 goto out; 183 184 /* extra 'x' at the end is to reserve space for '.' */ 185 if (asprintf(&tmp, "%s.XXXXXXx", to) < 0) { 186 tmp = NULL; 187 goto out; 188 } 189 ptr = strrchr(tmp, '/'); 190 if (!ptr) 191 goto out; 192 ptr = memmove(ptr + 1, ptr, strlen(ptr) - 1); 193 *ptr = '.'; 194 195 tofd = mkstemp(tmp); 196 if (tofd < 0) 197 goto out; 198 199 if (fchmod(tofd, mode)) 200 goto out_close_to; 201 202 if (st.st_size == 0) { /* /proc? do it slowly... */ 203 err = slow_copyfile(from, tmp); 204 goto out_close_to; 205 } 206 207 fromfd = open(from, O_RDONLY); 208 if (fromfd < 0) 209 goto out_close_to; 210 211 err = copyfile_offset(fromfd, 0, tofd, 0, st.st_size); 212 213 close(fromfd); 214 out_close_to: 215 close(tofd); 216 if (!err) 217 err = link(tmp, to); 218 unlink(tmp); 219 out: 220 free(tmp); 221 return err; 222 } 223 224 int copyfile(const char *from, const char *to) 225 { 226 return copyfile_mode(from, to, 0755); 227 } 228 229 unsigned long convert_unit(unsigned long value, char *unit) 230 { 231 *unit = ' '; 232 233 if (value > 1000) { 234 value /= 1000; 235 *unit = 'K'; 236 } 237 238 if (value > 1000) { 239 value /= 1000; 240 *unit = 'M'; 241 } 242 243 if (value > 1000) { 244 value /= 1000; 245 *unit = 'G'; 246 } 247 248 return value; 249 } 250 251 static ssize_t ion(bool is_read, int fd, void *buf, size_t n) 252 { 253 void *buf_start = buf; 254 size_t left = n; 255 256 while (left) { 257 ssize_t ret = is_read ? read(fd, buf, left) : 258 write(fd, buf, left); 259 260 if (ret < 0 && errno == EINTR) 261 continue; 262 if (ret <= 0) 263 return ret; 264 265 left -= ret; 266 buf += ret; 267 } 268 269 BUG_ON((size_t)(buf - buf_start) != n); 270 return n; 271 } 272 273 /* 274 * Read exactly 'n' bytes or return an error. 275 */ 276 ssize_t readn(int fd, void *buf, size_t n) 277 { 278 return ion(true, fd, buf, n); 279 } 280 281 /* 282 * Write exactly 'n' bytes or return an error. 283 */ 284 ssize_t writen(int fd, void *buf, size_t n) 285 { 286 return ion(false, fd, buf, n); 287 } 288 289 size_t hex_width(u64 v) 290 { 291 size_t n = 1; 292 293 while ((v >>= 4)) 294 ++n; 295 296 return n; 297 } 298 299 static int hex(char ch) 300 { 301 if ((ch >= '0') && (ch <= '9')) 302 return ch - '0'; 303 if ((ch >= 'a') && (ch <= 'f')) 304 return ch - 'a' + 10; 305 if ((ch >= 'A') && (ch <= 'F')) 306 return ch - 'A' + 10; 307 return -1; 308 } 309 310 /* 311 * While we find nice hex chars, build a long_val. 312 * Return number of chars processed. 313 */ 314 int hex2u64(const char *ptr, u64 *long_val) 315 { 316 const char *p = ptr; 317 *long_val = 0; 318 319 while (*p) { 320 const int hex_val = hex(*p); 321 322 if (hex_val < 0) 323 break; 324 325 *long_val = (*long_val << 4) | hex_val; 326 p++; 327 } 328 329 return p - ptr; 330 } 331 332 /* Obtain a backtrace and print it to stdout. */ 333 #ifdef HAVE_BACKTRACE_SUPPORT 334 void dump_stack(void) 335 { 336 void *array[16]; 337 size_t size = backtrace(array, ARRAY_SIZE(array)); 338 char **strings = backtrace_symbols(array, size); 339 size_t i; 340 341 printf("Obtained %zd stack frames.\n", size); 342 343 for (i = 0; i < size; i++) 344 printf("%s\n", strings[i]); 345 346 free(strings); 347 } 348 #else 349 void dump_stack(void) {} 350 #endif 351 352 void sighandler_dump_stack(int sig) 353 { 354 psignal(sig, "perf"); 355 dump_stack(); 356 exit(sig); 357 } 358 359 void get_term_dimensions(struct winsize *ws) 360 { 361 char *s = getenv("LINES"); 362 363 if (s != NULL) { 364 ws->ws_row = atoi(s); 365 s = getenv("COLUMNS"); 366 if (s != NULL) { 367 ws->ws_col = atoi(s); 368 if (ws->ws_row && ws->ws_col) 369 return; 370 } 371 } 372 #ifdef TIOCGWINSZ 373 if (ioctl(1, TIOCGWINSZ, ws) == 0 && 374 ws->ws_row && ws->ws_col) 375 return; 376 #endif 377 ws->ws_row = 25; 378 ws->ws_col = 80; 379 } 380 381 void set_term_quiet_input(struct termios *old) 382 { 383 struct termios tc; 384 385 tcgetattr(0, old); 386 tc = *old; 387 tc.c_lflag &= ~(ICANON | ECHO); 388 tc.c_cc[VMIN] = 0; 389 tc.c_cc[VTIME] = 0; 390 tcsetattr(0, TCSANOW, &tc); 391 } 392 393 static void set_tracing_events_path(const char *tracing, const char *mountpoint) 394 { 395 snprintf(tracing_path, sizeof(tracing_path), "%s/%s", 396 mountpoint, tracing); 397 snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s", 398 mountpoint, tracing, "events"); 399 } 400 401 static const char *__perf_tracefs_mount(const char *mountpoint) 402 { 403 const char *mnt; 404 405 mnt = tracefs_mount(mountpoint); 406 if (!mnt) 407 return NULL; 408 409 set_tracing_events_path("", mnt); 410 411 return mnt; 412 } 413 414 static const char *__perf_debugfs_mount(const char *mountpoint) 415 { 416 const char *mnt; 417 418 mnt = debugfs_mount(mountpoint); 419 if (!mnt) 420 return NULL; 421 422 set_tracing_events_path("tracing/", mnt); 423 424 return mnt; 425 } 426 427 const char *perf_debugfs_mount(const char *mountpoint) 428 { 429 const char *mnt; 430 431 mnt = __perf_tracefs_mount(mountpoint); 432 if (mnt) 433 return mnt; 434 435 mnt = __perf_debugfs_mount(mountpoint); 436 437 return mnt; 438 } 439 440 void perf_debugfs_set_path(const char *mntpt) 441 { 442 set_tracing_events_path("tracing/", mntpt); 443 } 444 445 char *get_tracing_file(const char *name) 446 { 447 char *file; 448 449 if (asprintf(&file, "%s/%s", tracing_path, name) < 0) 450 return NULL; 451 452 return file; 453 } 454 455 void put_tracing_file(char *file) 456 { 457 free(file); 458 } 459 460 int parse_nsec_time(const char *str, u64 *ptime) 461 { 462 u64 time_sec, time_nsec; 463 char *end; 464 465 time_sec = strtoul(str, &end, 10); 466 if (*end != '.' && *end != '\0') 467 return -1; 468 469 if (*end == '.') { 470 int i; 471 char nsec_buf[10]; 472 473 if (strlen(++end) > 9) 474 return -1; 475 476 strncpy(nsec_buf, end, 9); 477 nsec_buf[9] = '\0'; 478 479 /* make it nsec precision */ 480 for (i = strlen(nsec_buf); i < 9; i++) 481 nsec_buf[i] = '0'; 482 483 time_nsec = strtoul(nsec_buf, &end, 10); 484 if (*end != '\0') 485 return -1; 486 } else 487 time_nsec = 0; 488 489 *ptime = time_sec * NSEC_PER_SEC + time_nsec; 490 return 0; 491 } 492 493 unsigned long parse_tag_value(const char *str, struct parse_tag *tags) 494 { 495 struct parse_tag *i = tags; 496 497 while (i->tag) { 498 char *s; 499 500 s = strchr(str, i->tag); 501 if (s) { 502 unsigned long int value; 503 char *endptr; 504 505 value = strtoul(str, &endptr, 10); 506 if (s != endptr) 507 break; 508 509 if (value > ULONG_MAX / i->mult) 510 break; 511 value *= i->mult; 512 return value; 513 } 514 i++; 515 } 516 517 return (unsigned long) -1; 518 } 519 520 int get_stack_size(const char *str, unsigned long *_size) 521 { 522 char *endptr; 523 unsigned long size; 524 unsigned long max_size = round_down(USHRT_MAX, sizeof(u64)); 525 526 size = strtoul(str, &endptr, 0); 527 528 do { 529 if (*endptr) 530 break; 531 532 size = round_up(size, sizeof(u64)); 533 if (!size || size > max_size) 534 break; 535 536 *_size = size; 537 return 0; 538 539 } while (0); 540 541 pr_err("callchain: Incorrect stack dump size (max %ld): %s\n", 542 max_size, str); 543 return -1; 544 } 545 546 int parse_callchain_record(const char *arg, struct callchain_param *param) 547 { 548 char *tok, *name, *saveptr = NULL; 549 char *buf; 550 int ret = -1; 551 552 /* We need buffer that we know we can write to. */ 553 buf = malloc(strlen(arg) + 1); 554 if (!buf) 555 return -ENOMEM; 556 557 strcpy(buf, arg); 558 559 tok = strtok_r((char *)buf, ",", &saveptr); 560 name = tok ? : (char *)buf; 561 562 do { 563 /* Framepointer style */ 564 if (!strncmp(name, "fp", sizeof("fp"))) { 565 if (!strtok_r(NULL, ",", &saveptr)) { 566 param->record_mode = CALLCHAIN_FP; 567 ret = 0; 568 } else 569 pr_err("callchain: No more arguments " 570 "needed for --call-graph fp\n"); 571 break; 572 573 #ifdef HAVE_DWARF_UNWIND_SUPPORT 574 /* Dwarf style */ 575 } else if (!strncmp(name, "dwarf", sizeof("dwarf"))) { 576 const unsigned long default_stack_dump_size = 8192; 577 578 ret = 0; 579 param->record_mode = CALLCHAIN_DWARF; 580 param->dump_size = default_stack_dump_size; 581 582 tok = strtok_r(NULL, ",", &saveptr); 583 if (tok) { 584 unsigned long size = 0; 585 586 ret = get_stack_size(tok, &size); 587 param->dump_size = size; 588 } 589 #endif /* HAVE_DWARF_UNWIND_SUPPORT */ 590 } else if (!strncmp(name, "lbr", sizeof("lbr"))) { 591 if (!strtok_r(NULL, ",", &saveptr)) { 592 param->record_mode = CALLCHAIN_LBR; 593 ret = 0; 594 } else 595 pr_err("callchain: No more arguments " 596 "needed for --call-graph lbr\n"); 597 break; 598 } else { 599 pr_err("callchain: Unknown --call-graph option " 600 "value: %s\n", arg); 601 break; 602 } 603 604 } while (0); 605 606 free(buf); 607 return ret; 608 } 609 610 int filename__read_str(const char *filename, char **buf, size_t *sizep) 611 { 612 size_t size = 0, alloc_size = 0; 613 void *bf = NULL, *nbf; 614 int fd, n, err = 0; 615 char sbuf[STRERR_BUFSIZE]; 616 617 fd = open(filename, O_RDONLY); 618 if (fd < 0) 619 return -errno; 620 621 do { 622 if (size == alloc_size) { 623 alloc_size += BUFSIZ; 624 nbf = realloc(bf, alloc_size); 625 if (!nbf) { 626 err = -ENOMEM; 627 break; 628 } 629 630 bf = nbf; 631 } 632 633 n = read(fd, bf + size, alloc_size - size); 634 if (n < 0) { 635 if (size) { 636 pr_warning("read failed %d: %s\n", errno, 637 strerror_r(errno, sbuf, sizeof(sbuf))); 638 err = 0; 639 } else 640 err = -errno; 641 642 break; 643 } 644 645 size += n; 646 } while (n > 0); 647 648 if (!err) { 649 *sizep = size; 650 *buf = bf; 651 } else 652 free(bf); 653 654 close(fd); 655 return err; 656 } 657 658 const char *get_filename_for_perf_kvm(void) 659 { 660 const char *filename; 661 662 if (perf_host && !perf_guest) 663 filename = strdup("perf.data.host"); 664 else if (!perf_host && perf_guest) 665 filename = strdup("perf.data.guest"); 666 else 667 filename = strdup("perf.data.kvm"); 668 669 return filename; 670 } 671 672 int perf_event_paranoid(void) 673 { 674 int value; 675 676 if (sysctl__read_int("kernel/perf_event_paranoid", &value)) 677 return INT_MAX; 678 679 return value; 680 } 681 682 void mem_bswap_32(void *src, int byte_size) 683 { 684 u32 *m = src; 685 while (byte_size > 0) { 686 *m = bswap_32(*m); 687 byte_size -= sizeof(u32); 688 ++m; 689 } 690 } 691 692 void mem_bswap_64(void *src, int byte_size) 693 { 694 u64 *m = src; 695 696 while (byte_size > 0) { 697 *m = bswap_64(*m); 698 byte_size -= sizeof(u64); 699 ++m; 700 } 701 } 702 703 bool find_process(const char *name) 704 { 705 size_t len = strlen(name); 706 DIR *dir; 707 struct dirent *d; 708 int ret = -1; 709 710 dir = opendir(procfs__mountpoint()); 711 if (!dir) 712 return false; 713 714 /* Walk through the directory. */ 715 while (ret && (d = readdir(dir)) != NULL) { 716 char path[PATH_MAX]; 717 char *data; 718 size_t size; 719 720 if ((d->d_type != DT_DIR) || 721 !strcmp(".", d->d_name) || 722 !strcmp("..", d->d_name)) 723 continue; 724 725 scnprintf(path, sizeof(path), "%s/%s/comm", 726 procfs__mountpoint(), d->d_name); 727 728 if (filename__read_str(path, &data, &size)) 729 continue; 730 731 ret = strncmp(name, data, len); 732 free(data); 733 } 734 735 closedir(dir); 736 return ret ? false : true; 737 } 738