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