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