srcline.c (1ac731c529cd4d6adbce134754b51ff7d822b145) | srcline.c (149ad69e002d769d477d0a19229ad392301f3f30) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2#include <inttypes.h> 3#include <signal.h> 4#include <stdio.h> 5#include <stdlib.h> 6#include <string.h> 7#include <sys/types.h> 8 --- 7 unchanged lines hidden (view full) --- 16#include "util/debug.h" 17#include "util/callchain.h" 18#include "util/symbol_conf.h" 19#include "srcline.h" 20#include "string2.h" 21#include "symbol.h" 22#include "subcmd/run-command.h" 23 | 1// SPDX-License-Identifier: GPL-2.0 2#include <inttypes.h> 3#include <signal.h> 4#include <stdio.h> 5#include <stdlib.h> 6#include <string.h> 7#include <sys/types.h> 8 --- 7 unchanged lines hidden (view full) --- 16#include "util/debug.h" 17#include "util/callchain.h" 18#include "util/symbol_conf.h" 19#include "srcline.h" 20#include "string2.h" 21#include "symbol.h" 22#include "subcmd/run-command.h" 23 |
24/* If addr2line doesn't return data for 1 second then timeout. */ 25int addr2line_timeout_ms = 1 * 1000; |
|
24bool srcline_full_filename; 25 | 26bool srcline_full_filename; 27 |
28char *srcline__unknown = (char *)"??:0"; 29 |
|
26static const char *dso__name(struct dso *dso) 27{ 28 const char *dso_name; 29 30 if (dso->symsrc_filename) 31 dso_name = dso->symsrc_filename; 32 else 33 dso_name = dso->long_name; --- 346 unchanged lines hidden (view full) --- 380 return 0; 381 382 sep = strchr(filename, ':'); 383 if (sep) { 384 *sep++ = '\0'; 385 *line_nr = strtoul(sep, NULL, 0); 386 return 1; 387 } | 30static const char *dso__name(struct dso *dso) 31{ 32 const char *dso_name; 33 34 if (dso->symsrc_filename) 35 dso_name = dso->symsrc_filename; 36 else 37 dso_name = dso->long_name; --- 346 unchanged lines hidden (view full) --- 384 return 0; 385 386 sep = strchr(filename, ':'); 387 if (sep) { 388 *sep++ = '\0'; 389 *line_nr = strtoul(sep, NULL, 0); 390 return 1; 391 } |
388 | 392 pr_debug("addr2line missing ':' in filename split\n"); |
389 return 0; 390} 391 392static void addr2line_subprocess_cleanup(struct child_process *a2l) 393{ 394 if (a2l->pid != -1) { 395 kill(a2l->pid, SIGKILL); 396 finish_command(a2l); /* ignore result, we don't care */ 397 a2l->pid = -1; | 393 return 0; 394} 395 396static void addr2line_subprocess_cleanup(struct child_process *a2l) 397{ 398 if (a2l->pid != -1) { 399 kill(a2l->pid, SIGKILL); 400 finish_command(a2l); /* ignore result, we don't care */ 401 a2l->pid = -1; |
402 close(a2l->in); 403 close(a2l->out); |
|
398 } 399 400 free(a2l); 401} 402 403static struct child_process *addr2line_subprocess_init(const char *addr2line_path, 404 const char *binary_path) 405{ 406 const char *argv[] = { 407 addr2line_path ?: "addr2line", 408 "-e", binary_path, | 404 } 405 406 free(a2l); 407} 408 409static struct child_process *addr2line_subprocess_init(const char *addr2line_path, 410 const char *binary_path) 411{ 412 const char *argv[] = { 413 addr2line_path ?: "addr2line", 414 "-e", binary_path, |
409 "-i", "-f", NULL | 415 "-a", "-i", "-f", NULL |
410 }; 411 struct child_process *a2l = zalloc(sizeof(*a2l)); 412 int start_command_status = 0; 413 414 if (a2l == NULL) { 415 pr_err("Failed to allocate memory for addr2line"); 416 return NULL; 417 } --- 18 unchanged lines hidden (view full) --- 436} 437 438enum a2l_style { 439 BROKEN, 440 GNU_BINUTILS, 441 LLVM, 442}; 443 | 416 }; 417 struct child_process *a2l = zalloc(sizeof(*a2l)); 418 int start_command_status = 0; 419 420 if (a2l == NULL) { 421 pr_err("Failed to allocate memory for addr2line"); 422 return NULL; 423 } --- 18 unchanged lines hidden (view full) --- 442} 443 444enum a2l_style { 445 BROKEN, 446 GNU_BINUTILS, 447 LLVM, 448}; 449 |
444static enum a2l_style addr2line_configure(struct child_process *a2l) | 450static enum a2l_style addr2line_configure(struct child_process *a2l, const char *dso_name) |
445{ 446 static bool cached; 447 static enum a2l_style style; 448 449 if (!cached) { 450 char buf[128]; 451 struct io io; 452 int ch; | 451{ 452 static bool cached; 453 static enum a2l_style style; 454 455 if (!cached) { 456 char buf[128]; 457 struct io io; 458 int ch; |
459 int lines; |
|
453 454 if (write(a2l->in, ",\n", 2) != 2) 455 return BROKEN; 456 457 io__init(&io, a2l->out, buf, sizeof(buf)); 458 ch = io__get_char(&io); 459 if (ch == ',') { 460 style = LLVM; 461 cached = true; | 460 461 if (write(a2l->in, ",\n", 2) != 2) 462 return BROKEN; 463 464 io__init(&io, a2l->out, buf, sizeof(buf)); 465 ch = io__get_char(&io); 466 if (ch == ',') { 467 style = LLVM; 468 cached = true; |
462 } else if (ch == '?') { | 469 lines = 1; 470 pr_debug("Detected LLVM addr2line style\n"); 471 } else if (ch == '0') { |
463 style = GNU_BINUTILS; 464 cached = true; | 472 style = GNU_BINUTILS; 473 cached = true; |
474 lines = 3; 475 pr_debug("Detected binutils addr2line style\n"); |
|
465 } else { | 476 } else { |
466 style = BROKEN; | 477 if (!symbol_conf.disable_add2line_warn) { 478 char *output = NULL; 479 size_t output_len; 480 481 io__getline(&io, &output, &output_len); 482 pr_warning("%s %s: addr2line configuration failed\n", 483 __func__, dso_name); 484 pr_warning("\t%c%s", ch, output); 485 } 486 pr_debug("Unknown/broken addr2line style\n"); 487 return BROKEN; |
467 } | 488 } |
468 do { | 489 while (lines) { |
469 ch = io__get_char(&io); | 490 ch = io__get_char(&io); |
470 } while (ch > 0 && ch != '\n'); 471 if (style == GNU_BINUTILS) { 472 do { 473 ch = io__get_char(&io); 474 } while (ch > 0 && ch != '\n'); | 491 if (ch <= 0) 492 break; 493 if (ch == '\n') 494 lines--; |
475 } 476 /* Ignore SIGPIPE in the event addr2line exits. */ 477 signal(SIGPIPE, SIG_IGN); 478 } 479 return style; 480} 481 482static int read_addr2line_record(struct io *io, 483 enum a2l_style style, | 495 } 496 /* Ignore SIGPIPE in the event addr2line exits. */ 497 signal(SIGPIPE, SIG_IGN); 498 } 499 return style; 500} 501 502static int read_addr2line_record(struct io *io, 503 enum a2l_style style, |
504 const char *dso_name, 505 u64 addr, 506 bool first, |
|
484 char **function, 485 char **filename, 486 unsigned int *line_nr) 487{ 488 /* 489 * Returns: 490 * -1 ==> error 491 * 0 ==> sentinel (or other ill-formed) record read --- 8 unchanged lines hidden (view full) --- 500 zfree(function); 501 502 if (filename != NULL) 503 zfree(filename); 504 505 if (line_nr != NULL) 506 *line_nr = 0; 507 | 507 char **function, 508 char **filename, 509 unsigned int *line_nr) 510{ 511 /* 512 * Returns: 513 * -1 ==> error 514 * 0 ==> sentinel (or other ill-formed) record read --- 8 unchanged lines hidden (view full) --- 523 zfree(function); 524 525 if (filename != NULL) 526 zfree(filename); 527 528 if (line_nr != NULL) 529 *line_nr = 0; 530 |
531 /* 532 * Read the first line. Without an error this will be: 533 * - for the first line an address like 0x1234, 534 * - the binutils sentinel 0x0000000000000000, 535 * - the llvm-addr2line the sentinel ',' character, 536 * - the function name line for an inlined function. 537 */ |
|
508 if (io__getline(io, &line, &line_len) < 0 || !line_len) 509 goto error; 510 | 538 if (io__getline(io, &line, &line_len) < 0 || !line_len) 539 goto error; 540 |
541 pr_debug("%s %s: addr2line read address for sentinel: %s", __func__, dso_name, line); |
|
511 if (style == LLVM && line_len == 2 && line[0] == ',') { | 542 if (style == LLVM && line_len == 2 && line[0] == ',') { |
543 /* Found the llvm-addr2line sentinel character. */ |
|
512 zfree(&line); 513 return 0; | 544 zfree(&line); 545 return 0; |
546 } else if (style == GNU_BINUTILS && (!first || addr != 0)) { 547 int zero_count = 0, non_zero_count = 0; 548 /* 549 * Check for binutils sentinel ignoring it for the case the 550 * requested address is 0. 551 */ 552 553 /* A given address should always start 0x. */ 554 if (line_len >= 2 || line[0] != '0' || line[1] != 'x') { 555 for (size_t i = 2; i < line_len; i++) { 556 if (line[i] == '0') 557 zero_count++; 558 else if (line[i] != '\n') 559 non_zero_count++; 560 } 561 if (!non_zero_count) { 562 int ch; 563 564 if (first && !zero_count) { 565 /* Line was erroneous just '0x'. */ 566 goto error; 567 } 568 /* 569 * Line was 0x0..0, the sentinel for binutils. Remove 570 * the function and filename lines. 571 */ 572 zfree(&line); 573 do { 574 ch = io__get_char(io); 575 } while (ch > 0 && ch != '\n'); 576 do { 577 ch = io__get_char(io); 578 } while (ch > 0 && ch != '\n'); 579 return 0; 580 } 581 } |
|
514 } | 582 } |
583 /* Read the second function name line (if inline data then this is the first line). */ 584 if (first && (io__getline(io, &line, &line_len) < 0 || !line_len)) 585 goto error; |
|
515 | 586 |
587 pr_debug("%s %s: addr2line read line: %s", __func__, dso_name, line); |
|
516 if (function != NULL) 517 *function = strdup(strim(line)); 518 519 zfree(&line); 520 line_len = 0; 521 | 588 if (function != NULL) 589 *function = strdup(strim(line)); 590 591 zfree(&line); 592 line_len = 0; 593 |
594 /* Read the third filename and line number line. */ |
|
522 if (io__getline(io, &line, &line_len) < 0 || !line_len) 523 goto error; 524 | 595 if (io__getline(io, &line, &line_len) < 0 || !line_len) 596 goto error; 597 |
598 pr_debug("%s %s: addr2line filename:number : %s", __func__, dso_name, line); |
|
525 if (filename_split(line, line_nr == NULL ? &dummy_line_nr : line_nr) == 0 && 526 style == GNU_BINUTILS) { 527 ret = 0; 528 goto error; 529 } 530 531 if (filename != NULL) 532 *filename = strdup(line); --- 36 unchanged lines hidden (view full) --- 569 char *record_filename = NULL; 570 unsigned int record_line_nr = 0; 571 int record_status = -1; 572 int ret = 0; 573 size_t inline_count = 0; 574 int len; 575 char buf[128]; 576 ssize_t written; | 599 if (filename_split(line, line_nr == NULL ? &dummy_line_nr : line_nr) == 0 && 600 style == GNU_BINUTILS) { 601 ret = 0; 602 goto error; 603 } 604 605 if (filename != NULL) 606 *filename = strdup(line); --- 36 unchanged lines hidden (view full) --- 643 char *record_filename = NULL; 644 unsigned int record_line_nr = 0; 645 int record_status = -1; 646 int ret = 0; 647 size_t inline_count = 0; 648 int len; 649 char buf[128]; 650 ssize_t written; |
577 struct io io; | 651 struct io io = { .eof = false }; |
578 enum a2l_style a2l_style; 579 580 if (!a2l) { 581 if (!filename__has_section(dso_name, ".debug_line")) 582 goto out; 583 | 652 enum a2l_style a2l_style; 653 654 if (!a2l) { 655 if (!filename__has_section(dso_name, ".debug_line")) 656 goto out; 657 |
584 dso->a2l = addr2line_subprocess_init(symbol_conf.addr2line_path, 585 dso_name); | 658 dso->a2l = addr2line_subprocess_init(symbol_conf.addr2line_path, dso_name); |
586 a2l = dso->a2l; 587 } 588 589 if (a2l == NULL) { 590 if (!symbol_conf.disable_add2line_warn) 591 pr_warning("%s %s: addr2line_subprocess_init failed\n", __func__, dso_name); 592 goto out; 593 } | 659 a2l = dso->a2l; 660 } 661 662 if (a2l == NULL) { 663 if (!symbol_conf.disable_add2line_warn) 664 pr_warning("%s %s: addr2line_subprocess_init failed\n", __func__, dso_name); 665 goto out; 666 } |
594 a2l_style = addr2line_configure(a2l); 595 if (a2l_style == BROKEN) { 596 if (!symbol_conf.disable_add2line_warn) 597 pr_warning("%s: addr2line configuration failed\n", __func__); | 667 a2l_style = addr2line_configure(a2l, dso_name); 668 if (a2l_style == BROKEN) |
598 goto out; | 669 goto out; |
599 } | |
600 601 /* | 670 671 /* |
602 * Send our request and then *deliberately* send something that can't be interpreted as 603 * a valid address to ask addr2line about (namely, ","). This causes addr2line to first 604 * write out the answer to our request, in an unbounded/unknown number of records, and 605 * then to write out the lines "??" and "??:0", for GNU binutils, or "," for 606 * llvm-addr2line, so that we can detect when it has finished giving us anything 607 * useful. With GNU binutils, we have to be careful about the first record, though, 608 * because it may be genuinely unknown, in which case we'll get two sets of "??"/"??:0" 609 * lines. | 672 * Send our request and then *deliberately* send something that can't be 673 * interpreted as a valid address to ask addr2line about (namely, 674 * ","). This causes addr2line to first write out the answer to our 675 * request, in an unbounded/unknown number of records, and then to write 676 * out the lines "0x0...0", "??" and "??:0", for GNU binutils, or "," 677 * for llvm-addr2line, so that we can detect when it has finished giving 678 * us anything useful. |
610 */ 611 len = snprintf(buf, sizeof(buf), "%016"PRIx64"\n,\n", addr); 612 written = len > 0 ? write(a2l->in, buf, len) : -1; 613 if (written != len) { 614 if (!symbol_conf.disable_add2line_warn) 615 pr_warning("%s %s: could not send request\n", __func__, dso_name); 616 goto out; 617 } 618 io__init(&io, a2l->out, buf, sizeof(buf)); | 679 */ 680 len = snprintf(buf, sizeof(buf), "%016"PRIx64"\n,\n", addr); 681 written = len > 0 ? write(a2l->in, buf, len) : -1; 682 if (written != len) { 683 if (!symbol_conf.disable_add2line_warn) 684 pr_warning("%s %s: could not send request\n", __func__, dso_name); 685 goto out; 686 } 687 io__init(&io, a2l->out, buf, sizeof(buf)); |
619 620 switch (read_addr2line_record(&io, a2l_style, | 688 io.timeout_ms = addr2line_timeout_ms; 689 switch (read_addr2line_record(&io, a2l_style, dso_name, addr, /*first=*/true, |
621 &record_function, &record_filename, &record_line_nr)) { 622 case -1: 623 if (!symbol_conf.disable_add2line_warn) 624 pr_warning("%s %s: could not read first record\n", __func__, dso_name); 625 goto out; 626 case 0: 627 /* | 690 &record_function, &record_filename, &record_line_nr)) { 691 case -1: 692 if (!symbol_conf.disable_add2line_warn) 693 pr_warning("%s %s: could not read first record\n", __func__, dso_name); 694 goto out; 695 case 0: 696 /* |
628 * The first record was invalid, so return failure, but first read another 629 * record, since we asked a junk question and have to clear the answer out. | 697 * The first record was invalid, so return failure, but first 698 * read another record, since we sent a sentinel ',' for the 699 * sake of detected the last inlined function. Treat this as the 700 * first of a record as the ',' generates a new start with GNU 701 * binutils, also force a non-zero address as we're no longer 702 * reading that record. |
630 */ | 703 */ |
631 switch (read_addr2line_record(&io, a2l_style, NULL, NULL, NULL)) { | 704 switch (read_addr2line_record(&io, a2l_style, dso_name, 705 /*addr=*/1, /*first=*/true, 706 NULL, NULL, NULL)) { |
632 case -1: 633 if (!symbol_conf.disable_add2line_warn) | 707 case -1: 708 if (!symbol_conf.disable_add2line_warn) |
634 pr_warning("%s %s: could not read delimiter record\n", | 709 pr_warning("%s %s: could not read sentinel record\n", |
635 __func__, dso_name); 636 break; 637 case 0: | 710 __func__, dso_name); 711 break; 712 case 0: |
638 /* As expected. */ | 713 /* The sentinel as expected. */ |
639 break; 640 default: 641 if (!symbol_conf.disable_add2line_warn) 642 pr_warning("%s %s: unexpected record instead of sentinel", 643 __func__, dso_name); 644 break; 645 } 646 goto out; 647 default: | 714 break; 715 default: 716 if (!symbol_conf.disable_add2line_warn) 717 pr_warning("%s %s: unexpected record instead of sentinel", 718 __func__, dso_name); 719 break; 720 } 721 goto out; 722 default: |
723 /* First record as expected. */ |
|
648 break; 649 } 650 651 if (file) { 652 *file = strdup(record_filename); 653 ret = 1; 654 } 655 if (line_nr) --- 4 unchanged lines hidden (view full) --- 660 record_function, 661 record_filename, 662 record_line_nr)) { 663 ret = 0; 664 goto out; 665 } 666 } 667 | 724 break; 725 } 726 727 if (file) { 728 *file = strdup(record_filename); 729 ret = 1; 730 } 731 if (line_nr) --- 4 unchanged lines hidden (view full) --- 736 record_function, 737 record_filename, 738 record_line_nr)) { 739 ret = 0; 740 goto out; 741 } 742 } 743 |
668 /* We have to read the records even if we don't care about the inline info. */ | 744 /* 745 * We have to read the records even if we don't care about the inline 746 * info. This isn't the first record and force the address to non-zero 747 * as we're reading records beyond the first. 748 */ |
669 while ((record_status = read_addr2line_record(&io, 670 a2l_style, | 749 while ((record_status = read_addr2line_record(&io, 750 a2l_style, |
751 dso_name, 752 /*addr=*/1, 753 /*first=*/false, |
|
671 &record_function, 672 &record_filename, 673 &record_line_nr)) == 1) { 674 if (unwind_inlines && node && inline_count++ < MAX_INLINE_NEST) { 675 if (inline_list__append_record(dso, node, sym, 676 record_function, 677 record_filename, 678 record_line_nr)) { 679 ret = 0; 680 goto out; 681 } 682 ret = 1; /* found at least one inline frame */ 683 } 684 } 685 686out: 687 free(record_function); 688 free(record_filename); | 754 &record_function, 755 &record_filename, 756 &record_line_nr)) == 1) { 757 if (unwind_inlines && node && inline_count++ < MAX_INLINE_NEST) { 758 if (inline_list__append_record(dso, node, sym, 759 record_function, 760 record_filename, 761 record_line_nr)) { 762 ret = 0; 763 goto out; 764 } 765 ret = 1; /* found at least one inline frame */ 766 } 767 } 768 769out: 770 free(record_function); 771 free(record_filename); |
772 if (io.eof) { 773 dso->a2l = NULL; 774 addr2line_subprocess_cleanup(a2l); 775 } |
|
689 return ret; 690} 691 692void dso__free_a2l(struct dso *dso) 693{ 694 struct child_process *a2l = dso->a2l; 695 696 if (!a2l) --- 102 unchanged lines hidden (view full) --- 799 if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { 800 dso->has_srcline = 0; 801 dso__free_a2l(dso); 802 } 803 804 return NULL; 805} 806 | 776 return ret; 777} 778 779void dso__free_a2l(struct dso *dso) 780{ 781 struct child_process *a2l = dso->a2l; 782 783 if (!a2l) --- 102 unchanged lines hidden (view full) --- 886 if (dso->a2l_fails && ++dso->a2l_fails > A2L_FAIL_LIMIT) { 887 dso->has_srcline = 0; 888 dso__free_a2l(dso); 889 } 890 891 return NULL; 892} 893 |
807void free_srcline(char *srcline) | 894void zfree_srcline(char **srcline) |
808{ | 895{ |
809 if (srcline && strcmp(srcline, SRCLINE_UNKNOWN) != 0) 810 free(srcline); | 896 if (*srcline == NULL) 897 return; 898 899 if (*srcline != SRCLINE_UNKNOWN) 900 free(*srcline); 901 902 *srcline = NULL; |
811} 812 813char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 814 bool show_sym, bool show_addr, u64 ip) 815{ 816 return __get_srcline(dso, addr, sym, show_sym, show_addr, false, ip); 817} 818 --- 56 unchanged lines hidden (view full) --- 875{ 876 struct srcline_node *pos; 877 struct rb_node *next = rb_first_cached(tree); 878 879 while (next) { 880 pos = rb_entry(next, struct srcline_node, rb_node); 881 next = rb_next(&pos->rb_node); 882 rb_erase_cached(&pos->rb_node, tree); | 903} 904 905char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym, 906 bool show_sym, bool show_addr, u64 ip) 907{ 908 return __get_srcline(dso, addr, sym, show_sym, show_addr, false, ip); 909} 910 --- 56 unchanged lines hidden (view full) --- 967{ 968 struct srcline_node *pos; 969 struct rb_node *next = rb_first_cached(tree); 970 971 while (next) { 972 pos = rb_entry(next, struct srcline_node, rb_node); 973 next = rb_next(&pos->rb_node); 974 rb_erase_cached(&pos->rb_node, tree); |
883 free_srcline(pos->srcline); | 975 zfree_srcline(&pos->srcline); |
884 zfree(&pos); 885 } 886} 887 888struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr, 889 struct symbol *sym) 890{ 891 const char *dso_name; --- 6 unchanged lines hidden (view full) --- 898} 899 900void inline_node__delete(struct inline_node *node) 901{ 902 struct inline_list *ilist, *tmp; 903 904 list_for_each_entry_safe(ilist, tmp, &node->val, list) { 905 list_del_init(&ilist->list); | 976 zfree(&pos); 977 } 978} 979 980struct inline_node *dso__parse_addr_inlines(struct dso *dso, u64 addr, 981 struct symbol *sym) 982{ 983 const char *dso_name; --- 6 unchanged lines hidden (view full) --- 990} 991 992void inline_node__delete(struct inline_node *node) 993{ 994 struct inline_list *ilist, *tmp; 995 996 list_for_each_entry_safe(ilist, tmp, &node->val, list) { 997 list_del_init(&ilist->list); |
906 free_srcline(ilist->srcline); | 998 zfree_srcline(&ilist->srcline); |
907 /* only the inlined symbols are owned by the list */ 908 if (ilist->symbol && ilist->symbol->inlined) 909 symbol__delete(ilist->symbol); 910 free(ilist); 911 } 912 913 free(node); 914} --- 55 unchanged lines hidden --- | 999 /* only the inlined symbols are owned by the list */ 1000 if (ilist->symbol && ilist->symbol->inlined) 1001 symbol__delete(ilist->symbol); 1002 free(ilist); 1003 } 1004 1005 free(node); 1006} --- 55 unchanged lines hidden --- |