Merge branch 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'perf-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
perf probe: Filter out redundant inline-instances
perf probe: Search concrete out-of-line instances
perf probe: Avoid searching variables in intermediate scopes
perf probe: Fix to search local variables in appropriate scope
perf probe: Warn when more than one line are given
perf probe: Fix to walk all inline instances
perf probe: Fix to search nested inlined functions in CU
perf probe: Fix line walker to check CU correctly
perf probe: Fix a memory leak for scopes array
perf: fix temporary file ownership check
perf report: Use properly build_id kernel binaries
perf top browser: Remove spurious helpline update

+11 -3
tools/perf/builtin-probe.c
··· 134 134 { 135 135 int ret = 0; 136 136 137 - if (str) 138 - ret = parse_line_range_desc(str, &params.line_range); 139 - INIT_LIST_HEAD(&params.line_range.line_list); 137 + if (!str) 138 + return 0; 139 + 140 + if (params.show_lines) { 141 + pr_warning("Warning: more than one --line options are" 142 + " detected. Only the first one is valid.\n"); 143 + return 0; 144 + } 145 + 140 146 params.show_lines = true; 147 + ret = parse_line_range_desc(str, &params.line_range); 148 + INIT_LIST_HEAD(&params.line_range.line_list); 141 149 142 150 return ret; 143 151 }
+195 -15
tools/perf/util/dwarf-aux.c
··· 96 96 return *lineno ?: -ENOENT; 97 97 } 98 98 99 + static int __die_find_inline_cb(Dwarf_Die *die_mem, void *data); 100 + 101 + /** 102 + * cu_walk_functions_at - Walk on function DIEs at given address 103 + * @cu_die: A CU DIE 104 + * @addr: An address 105 + * @callback: A callback which called with found DIEs 106 + * @data: A user data 107 + * 108 + * Walk on function DIEs at given @addr in @cu_die. Passed DIEs 109 + * should be subprogram or inlined-subroutines. 110 + */ 111 + int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, 112 + int (*callback)(Dwarf_Die *, void *), void *data) 113 + { 114 + Dwarf_Die die_mem; 115 + Dwarf_Die *sc_die; 116 + int ret = -ENOENT; 117 + 118 + /* Inlined function could be recursive. Trace it until fail */ 119 + for (sc_die = die_find_realfunc(cu_die, addr, &die_mem); 120 + sc_die != NULL; 121 + sc_die = die_find_child(sc_die, __die_find_inline_cb, &addr, 122 + &die_mem)) { 123 + ret = callback(sc_die, data); 124 + if (ret) 125 + break; 126 + } 127 + 128 + return ret; 129 + 130 + } 131 + 99 132 /** 100 133 * die_compare_name - Compare diename and tname 101 134 * @dw_die: a DIE ··· 231 198 return 0; 232 199 } 233 200 201 + /* Get attribute and translate it as a sdata */ 202 + static int die_get_attr_sdata(Dwarf_Die *tp_die, unsigned int attr_name, 203 + Dwarf_Sword *result) 204 + { 205 + Dwarf_Attribute attr; 206 + 207 + if (dwarf_attr(tp_die, attr_name, &attr) == NULL || 208 + dwarf_formsdata(&attr, result) != 0) 209 + return -ENOENT; 210 + 211 + return 0; 212 + } 213 + 234 214 /** 235 215 * die_is_signed_type - Check whether a type DIE is signed or not 236 216 * @tp_die: a DIE of a type ··· 295 249 } 296 250 return 0; 297 251 } 252 + 253 + /* Get the call file index number in CU DIE */ 254 + static int die_get_call_fileno(Dwarf_Die *in_die) 255 + { 256 + Dwarf_Sword idx; 257 + 258 + if (die_get_attr_sdata(in_die, DW_AT_call_file, &idx) == 0) 259 + return (int)idx; 260 + else 261 + return -ENOENT; 262 + } 263 + 264 + /* Get the declared file index number in CU DIE */ 265 + static int die_get_decl_fileno(Dwarf_Die *pdie) 266 + { 267 + Dwarf_Sword idx; 268 + 269 + if (die_get_attr_sdata(pdie, DW_AT_decl_file, &idx) == 0) 270 + return (int)idx; 271 + else 272 + return -ENOENT; 273 + } 274 + 275 + /** 276 + * die_get_call_file - Get callsite file name of inlined function instance 277 + * @in_die: a DIE of an inlined function instance 278 + * 279 + * Get call-site file name of @in_die. This means from which file the inline 280 + * function is called. 281 + */ 282 + const char *die_get_call_file(Dwarf_Die *in_die) 283 + { 284 + Dwarf_Die cu_die; 285 + Dwarf_Files *files; 286 + int idx; 287 + 288 + idx = die_get_call_fileno(in_die); 289 + if (idx < 0 || !dwarf_diecu(in_die, &cu_die, NULL, NULL) || 290 + dwarf_getsrcfiles(&cu_die, &files, NULL) != 0) 291 + return NULL; 292 + 293 + return dwarf_filesrc(files, idx, NULL, NULL); 294 + } 295 + 298 296 299 297 /** 300 298 * die_find_child - Generic DIE search function in DIE tree ··· 464 374 return die_mem; 465 375 } 466 376 377 + struct __instance_walk_param { 378 + void *addr; 379 + int (*callback)(Dwarf_Die *, void *); 380 + void *data; 381 + int retval; 382 + }; 383 + 384 + static int __die_walk_instances_cb(Dwarf_Die *inst, void *data) 385 + { 386 + struct __instance_walk_param *iwp = data; 387 + Dwarf_Attribute attr_mem; 388 + Dwarf_Die origin_mem; 389 + Dwarf_Attribute *attr; 390 + Dwarf_Die *origin; 391 + int tmp; 392 + 393 + attr = dwarf_attr(inst, DW_AT_abstract_origin, &attr_mem); 394 + if (attr == NULL) 395 + return DIE_FIND_CB_CONTINUE; 396 + 397 + origin = dwarf_formref_die(attr, &origin_mem); 398 + if (origin == NULL || origin->addr != iwp->addr) 399 + return DIE_FIND_CB_CONTINUE; 400 + 401 + /* Ignore redundant instances */ 402 + if (dwarf_tag(inst) == DW_TAG_inlined_subroutine) { 403 + dwarf_decl_line(origin, &tmp); 404 + if (die_get_call_lineno(inst) == tmp) { 405 + tmp = die_get_decl_fileno(origin); 406 + if (die_get_call_fileno(inst) == tmp) 407 + return DIE_FIND_CB_CONTINUE; 408 + } 409 + } 410 + 411 + iwp->retval = iwp->callback(inst, iwp->data); 412 + 413 + return (iwp->retval) ? DIE_FIND_CB_END : DIE_FIND_CB_CONTINUE; 414 + } 415 + 416 + /** 417 + * die_walk_instances - Walk on instances of given DIE 418 + * @or_die: an abstract original DIE 419 + * @callback: a callback function which is called with instance DIE 420 + * @data: user data 421 + * 422 + * Walk on the instances of give @in_die. @in_die must be an inlined function 423 + * declartion. This returns the return value of @callback if it returns 424 + * non-zero value, or -ENOENT if there is no instance. 425 + */ 426 + int die_walk_instances(Dwarf_Die *or_die, int (*callback)(Dwarf_Die *, void *), 427 + void *data) 428 + { 429 + Dwarf_Die cu_die; 430 + Dwarf_Die die_mem; 431 + struct __instance_walk_param iwp = { 432 + .addr = or_die->addr, 433 + .callback = callback, 434 + .data = data, 435 + .retval = -ENOENT, 436 + }; 437 + 438 + if (dwarf_diecu(or_die, &cu_die, NULL, NULL) == NULL) 439 + return -ENOENT; 440 + 441 + die_find_child(&cu_die, __die_walk_instances_cb, &iwp, &die_mem); 442 + 443 + return iwp.retval; 444 + } 445 + 467 446 /* Line walker internal parameters */ 468 447 struct __line_walk_param { 469 - const char *fname; 448 + bool recursive; 470 449 line_walk_callback_t callback; 471 450 void *data; 472 451 int retval; ··· 544 385 static int __die_walk_funclines_cb(Dwarf_Die *in_die, void *data) 545 386 { 546 387 struct __line_walk_param *lw = data; 547 - Dwarf_Addr addr; 388 + Dwarf_Addr addr = 0; 389 + const char *fname; 548 390 int lineno; 549 391 550 392 if (dwarf_tag(in_die) == DW_TAG_inlined_subroutine) { 393 + fname = die_get_call_file(in_die); 551 394 lineno = die_get_call_lineno(in_die); 552 - if (lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) { 553 - lw->retval = lw->callback(lw->fname, lineno, addr, 554 - lw->data); 395 + if (fname && lineno > 0 && dwarf_entrypc(in_die, &addr) == 0) { 396 + lw->retval = lw->callback(fname, lineno, addr, lw->data); 555 397 if (lw->retval != 0) 556 398 return DIE_FIND_CB_END; 557 399 } 558 400 } 559 - return DIE_FIND_CB_SIBLING; 401 + if (!lw->recursive) 402 + /* Don't need to search recursively */ 403 + return DIE_FIND_CB_SIBLING; 404 + 405 + if (addr) { 406 + fname = dwarf_decl_file(in_die); 407 + if (fname && dwarf_decl_line(in_die, &lineno) == 0) { 408 + lw->retval = lw->callback(fname, lineno, addr, lw->data); 409 + if (lw->retval != 0) 410 + return DIE_FIND_CB_END; 411 + } 412 + } 413 + 414 + /* Continue to search nested inlined function call-sites */ 415 + return DIE_FIND_CB_CONTINUE; 560 416 } 561 417 562 418 /* Walk on lines of blocks included in given DIE */ 563 - static int __die_walk_funclines(Dwarf_Die *sp_die, 419 + static int __die_walk_funclines(Dwarf_Die *sp_die, bool recursive, 564 420 line_walk_callback_t callback, void *data) 565 421 { 566 422 struct __line_walk_param lw = { 423 + .recursive = recursive, 567 424 .callback = callback, 568 425 .data = data, 569 426 .retval = 0, 570 427 }; 571 428 Dwarf_Die die_mem; 572 429 Dwarf_Addr addr; 430 + const char *fname; 573 431 int lineno; 574 432 575 433 /* Handle function declaration line */ 576 - lw.fname = dwarf_decl_file(sp_die); 577 - if (lw.fname && dwarf_decl_line(sp_die, &lineno) == 0 && 434 + fname = dwarf_decl_file(sp_die); 435 + if (fname && dwarf_decl_line(sp_die, &lineno) == 0 && 578 436 dwarf_entrypc(sp_die, &addr) == 0) { 579 - lw.retval = callback(lw.fname, lineno, addr, data); 437 + lw.retval = callback(fname, lineno, addr, data); 580 438 if (lw.retval != 0) 581 439 goto done; 582 440 } ··· 606 430 { 607 431 struct __line_walk_param *lw = data; 608 432 609 - lw->retval = __die_walk_funclines(sp_die, lw->callback, lw->data); 433 + lw->retval = __die_walk_funclines(sp_die, true, lw->callback, lw->data); 610 434 if (lw->retval != 0) 611 435 return DWARF_CB_ABORT; 612 436 ··· 615 439 616 440 /** 617 441 * die_walk_lines - Walk on lines inside given DIE 618 - * @rt_die: a root DIE (CU or subprogram) 442 + * @rt_die: a root DIE (CU, subprogram or inlined_subroutine) 619 443 * @callback: callback routine 620 444 * @data: user data 621 445 * ··· 636 460 size_t nlines, i; 637 461 638 462 /* Get the CU die */ 639 - if (dwarf_tag(rt_die) == DW_TAG_subprogram) 463 + if (dwarf_tag(rt_die) != DW_TAG_compile_unit) 640 464 cu_die = dwarf_diecu(rt_die, &die_mem, NULL, NULL); 641 465 else 642 466 cu_die = rt_die; 643 467 if (!cu_die) { 644 - pr_debug2("Failed to get CU from subprogram\n"); 468 + pr_debug2("Failed to get CU from given DIE.\n"); 645 469 return -EINVAL; 646 470 } 647 471 ··· 685 509 * subroutines. We have to check functions list or given function. 686 510 */ 687 511 if (rt_die != cu_die) 688 - ret = __die_walk_funclines(rt_die, callback, data); 512 + /* 513 + * Don't need walk functions recursively, because nested 514 + * inlined functions don't have lines of the specified DIE. 515 + */ 516 + ret = __die_walk_funclines(rt_die, false, callback, data); 689 517 else { 690 518 struct __line_walk_param param = { 691 519 .callback = callback,
+11
tools/perf/util/dwarf-aux.h
··· 34 34 extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr, 35 35 const char **fname, int *lineno); 36 36 37 + /* Walk on funcitons at given address */ 38 + extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, 39 + int (*callback)(Dwarf_Die *, void *), void *data); 40 + 37 41 /* Compare diename and tname */ 38 42 extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); 39 43 40 44 /* Get callsite line number of inline-function instance */ 41 45 extern int die_get_call_lineno(Dwarf_Die *in_die); 46 + 47 + /* Get callsite file name of inlined function instance */ 48 + extern const char *die_get_call_file(Dwarf_Die *in_die); 42 49 43 50 /* Get type die */ 44 51 extern Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); ··· 79 72 /* Search an inlined function including given address */ 80 73 extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 81 74 Dwarf_Die *die_mem); 75 + 76 + /* Walk on the instances of given DIE */ 77 + extern int die_walk_instances(Dwarf_Die *in_die, 78 + int (*callback)(Dwarf_Die *, void *), void *data); 82 79 83 80 /* Walker on lines (Note: line number will not be sorted) */ 84 81 typedef int (* line_walk_callback_t) (const char *fname, int lineno,
+10 -1
tools/perf/util/header.c
··· 726 726 return -1; 727 727 728 728 bev.header = old_bev.header; 729 - bev.pid = 0; 729 + 730 + /* 731 + * As the pid is the missing value, we need to fill 732 + * it properly. The header.misc value give us nice hint. 733 + */ 734 + bev.pid = HOST_KERNEL_ID; 735 + if (bev.header.misc == PERF_RECORD_MISC_GUEST_USER || 736 + bev.header.misc == PERF_RECORD_MISC_GUEST_KERNEL) 737 + bev.pid = DEFAULT_GUEST_KERNEL_ID; 738 + 730 739 memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id)); 731 740 __event_process_build_id(&bev, filename, session); 732 741
+142 -89
tools/perf/util/probe-finder.c
··· 612 612 return ret; 613 613 } 614 614 615 - /* Find a variable in a subprogram die */ 616 - static int find_variable(Dwarf_Die *sp_die, struct probe_finder *pf) 615 + /* Find a variable in a scope DIE */ 616 + static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf) 617 617 { 618 - Dwarf_Die vr_die, *scopes; 618 + Dwarf_Die vr_die; 619 619 char buf[32], *ptr; 620 - int ret, nscopes; 620 + int ret = 0; 621 621 622 622 if (!is_c_varname(pf->pvar->var)) { 623 623 /* Copy raw parameters */ ··· 652 652 if (pf->tvar->name == NULL) 653 653 return -ENOMEM; 654 654 655 - pr_debug("Searching '%s' variable in context.\n", 656 - pf->pvar->var); 655 + pr_debug("Searching '%s' variable in context.\n", pf->pvar->var); 657 656 /* Search child die for local variables and parameters. */ 658 - if (die_find_variable_at(sp_die, pf->pvar->var, pf->addr, &vr_die)) 659 - ret = convert_variable(&vr_die, pf); 660 - else { 661 - /* Search upper class */ 662 - nscopes = dwarf_getscopes_die(sp_die, &scopes); 663 - while (nscopes-- > 1) { 664 - pr_debug("Searching variables in %s\n", 665 - dwarf_diename(&scopes[nscopes])); 666 - /* We should check this scope, so give dummy address */ 667 - if (die_find_variable_at(&scopes[nscopes], 668 - pf->pvar->var, 0, 669 - &vr_die)) { 670 - ret = convert_variable(&vr_die, pf); 671 - goto found; 672 - } 673 - } 674 - if (scopes) 675 - free(scopes); 676 - ret = -ENOENT; 657 + if (!die_find_variable_at(sc_die, pf->pvar->var, pf->addr, &vr_die)) { 658 + /* Search again in global variables */ 659 + if (!die_find_variable_at(&pf->cu_die, pf->pvar->var, 0, &vr_die)) 660 + ret = -ENOENT; 677 661 } 678 - found: 662 + if (ret == 0) 663 + ret = convert_variable(&vr_die, pf); 664 + 679 665 if (ret < 0) 680 666 pr_warning("Failed to find '%s' in this function.\n", 681 667 pf->pvar->var); ··· 704 718 return 0; 705 719 } 706 720 707 - /* Call probe_finder callback with real subprogram DIE */ 708 - static int call_probe_finder(Dwarf_Die *sp_die, struct probe_finder *pf) 721 + /* Call probe_finder callback with scope DIE */ 722 + static int call_probe_finder(Dwarf_Die *sc_die, struct probe_finder *pf) 709 723 { 710 - Dwarf_Die die_mem; 711 724 Dwarf_Attribute fb_attr; 712 725 size_t nops; 713 726 int ret; 714 727 715 - /* If no real subprogram, find a real one */ 716 - if (!sp_die || dwarf_tag(sp_die) != DW_TAG_subprogram) { 717 - sp_die = die_find_realfunc(&pf->cu_die, pf->addr, &die_mem); 718 - if (!sp_die) { 728 + if (!sc_die) { 729 + pr_err("Caller must pass a scope DIE. Program error.\n"); 730 + return -EINVAL; 731 + } 732 + 733 + /* If not a real subprogram, find a real one */ 734 + if (dwarf_tag(sc_die) != DW_TAG_subprogram) { 735 + if (!die_find_realfunc(&pf->cu_die, pf->addr, &pf->sp_die)) { 719 736 pr_warning("Failed to find probe point in any " 720 737 "functions.\n"); 721 738 return -ENOENT; 722 739 } 723 - } 740 + } else 741 + memcpy(&pf->sp_die, sc_die, sizeof(Dwarf_Die)); 724 742 725 - /* Get the frame base attribute/ops */ 726 - dwarf_attr(sp_die, DW_AT_frame_base, &fb_attr); 743 + /* Get the frame base attribute/ops from subprogram */ 744 + dwarf_attr(&pf->sp_die, DW_AT_frame_base, &fb_attr); 727 745 ret = dwarf_getlocation_addr(&fb_attr, pf->addr, &pf->fb_ops, &nops, 1); 728 746 if (ret <= 0 || nops == 0) { 729 747 pf->fb_ops = NULL; ··· 745 755 } 746 756 747 757 /* Call finder's callback handler */ 748 - ret = pf->callback(sp_die, pf); 758 + ret = pf->callback(sc_die, pf); 749 759 750 760 /* *pf->fb_ops will be cached in libdw. Don't free it. */ 751 761 pf->fb_ops = NULL; ··· 753 763 return ret; 754 764 } 755 765 766 + struct find_scope_param { 767 + const char *function; 768 + const char *file; 769 + int line; 770 + int diff; 771 + Dwarf_Die *die_mem; 772 + bool found; 773 + }; 774 + 775 + static int find_best_scope_cb(Dwarf_Die *fn_die, void *data) 776 + { 777 + struct find_scope_param *fsp = data; 778 + const char *file; 779 + int lno; 780 + 781 + /* Skip if declared file name does not match */ 782 + if (fsp->file) { 783 + file = dwarf_decl_file(fn_die); 784 + if (!file || strcmp(fsp->file, file) != 0) 785 + return 0; 786 + } 787 + /* If the function name is given, that's what user expects */ 788 + if (fsp->function) { 789 + if (die_compare_name(fn_die, fsp->function)) { 790 + memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die)); 791 + fsp->found = true; 792 + return 1; 793 + } 794 + } else { 795 + /* With the line number, find the nearest declared DIE */ 796 + dwarf_decl_line(fn_die, &lno); 797 + if (lno < fsp->line && fsp->diff > fsp->line - lno) { 798 + /* Keep a candidate and continue */ 799 + fsp->diff = fsp->line - lno; 800 + memcpy(fsp->die_mem, fn_die, sizeof(Dwarf_Die)); 801 + fsp->found = true; 802 + } 803 + } 804 + return 0; 805 + } 806 + 807 + /* Find an appropriate scope fits to given conditions */ 808 + static Dwarf_Die *find_best_scope(struct probe_finder *pf, Dwarf_Die *die_mem) 809 + { 810 + struct find_scope_param fsp = { 811 + .function = pf->pev->point.function, 812 + .file = pf->fname, 813 + .line = pf->lno, 814 + .diff = INT_MAX, 815 + .die_mem = die_mem, 816 + .found = false, 817 + }; 818 + 819 + cu_walk_functions_at(&pf->cu_die, pf->addr, find_best_scope_cb, &fsp); 820 + 821 + return fsp.found ? die_mem : NULL; 822 + } 823 + 756 824 static int probe_point_line_walker(const char *fname, int lineno, 757 825 Dwarf_Addr addr, void *data) 758 826 { 759 827 struct probe_finder *pf = data; 828 + Dwarf_Die *sc_die, die_mem; 760 829 int ret; 761 830 762 831 if (lineno != pf->lno || strtailcmp(fname, pf->fname) != 0) 763 832 return 0; 764 833 765 834 pf->addr = addr; 766 - ret = call_probe_finder(NULL, pf); 835 + sc_die = find_best_scope(pf, &die_mem); 836 + if (!sc_die) { 837 + pr_warning("Failed to find scope of probe point.\n"); 838 + return -ENOENT; 839 + } 840 + 841 + ret = call_probe_finder(sc_die, pf); 767 842 768 843 /* Continue if no error, because the line will be in inline function */ 769 844 return ret < 0 ? ret : 0; ··· 882 827 Dwarf_Addr addr, void *data) 883 828 { 884 829 struct probe_finder *pf = data; 830 + Dwarf_Die *sc_die, die_mem; 885 831 int ret; 886 832 887 833 if (!line_list__has_line(&pf->lcache, lineno) || ··· 892 836 pr_debug("Probe line found: line:%d addr:0x%llx\n", 893 837 lineno, (unsigned long long)addr); 894 838 pf->addr = addr; 895 - ret = call_probe_finder(NULL, pf); 839 + pf->lno = lineno; 840 + sc_die = find_best_scope(pf, &die_mem); 841 + if (!sc_die) { 842 + pr_warning("Failed to find scope of probe point.\n"); 843 + return -ENOENT; 844 + } 845 + 846 + ret = call_probe_finder(sc_die, pf); 896 847 897 848 /* 898 849 * Continue if no error, because the lazy pattern will match ··· 924 861 return die_walk_lines(sp_die, probe_point_lazy_walker, pf); 925 862 } 926 863 927 - /* Callback parameter with return value */ 928 - struct dwarf_callback_param { 929 - void *data; 930 - int retval; 931 - }; 932 - 933 864 static int probe_point_inline_cb(Dwarf_Die *in_die, void *data) 934 865 { 935 - struct dwarf_callback_param *param = data; 936 - struct probe_finder *pf = param->data; 866 + struct probe_finder *pf = data; 937 867 struct perf_probe_point *pp = &pf->pev->point; 938 868 Dwarf_Addr addr; 869 + int ret; 939 870 940 871 if (pp->lazy_line) 941 - param->retval = find_probe_point_lazy(in_die, pf); 872 + ret = find_probe_point_lazy(in_die, pf); 942 873 else { 943 874 /* Get probe address */ 944 875 if (dwarf_entrypc(in_die, &addr) != 0) { 945 876 pr_warning("Failed to get entry address of %s.\n", 946 877 dwarf_diename(in_die)); 947 - param->retval = -ENOENT; 948 - return DWARF_CB_ABORT; 878 + return -ENOENT; 949 879 } 950 880 pf->addr = addr; 951 881 pf->addr += pp->offset; 952 882 pr_debug("found inline addr: 0x%jx\n", 953 883 (uintmax_t)pf->addr); 954 884 955 - param->retval = call_probe_finder(in_die, pf); 956 - if (param->retval < 0) 957 - return DWARF_CB_ABORT; 885 + ret = call_probe_finder(in_die, pf); 958 886 } 959 887 960 - return DWARF_CB_OK; 888 + return ret; 961 889 } 890 + 891 + /* Callback parameter with return value for libdw */ 892 + struct dwarf_callback_param { 893 + void *data; 894 + int retval; 895 + }; 962 896 963 897 /* Search function from function name */ 964 898 static int probe_point_search_cb(Dwarf_Die *sp_die, void *data) ··· 993 933 /* TODO: Check the address in this function */ 994 934 param->retval = call_probe_finder(sp_die, pf); 995 935 } 996 - } else { 997 - struct dwarf_callback_param _param = {.data = (void *)pf, 998 - .retval = 0}; 936 + } else 999 937 /* Inlined function: search instances */ 1000 - dwarf_func_inline_instances(sp_die, probe_point_inline_cb, 1001 - &_param); 1002 - param->retval = _param.retval; 1003 - } 938 + param->retval = die_walk_instances(sp_die, 939 + probe_point_inline_cb, (void *)pf); 1004 940 1005 941 return DWARF_CB_ABORT; /* Exit; no same symbol in this CU. */ 1006 942 } ··· 1116 1060 } 1117 1061 1118 1062 /* Add a found probe point into trace event list */ 1119 - static int add_probe_trace_event(Dwarf_Die *sp_die, struct probe_finder *pf) 1063 + static int add_probe_trace_event(Dwarf_Die *sc_die, struct probe_finder *pf) 1120 1064 { 1121 1065 struct trace_event_finder *tf = 1122 1066 container_of(pf, struct trace_event_finder, pf); ··· 1131 1075 } 1132 1076 tev = &tf->tevs[tf->ntevs++]; 1133 1077 1134 - ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe, 1135 - &tev->point); 1078 + /* Trace point should be converted from subprogram DIE */ 1079 + ret = convert_to_trace_point(&pf->sp_die, pf->addr, 1080 + pf->pev->point.retprobe, &tev->point); 1136 1081 if (ret < 0) 1137 1082 return ret; 1138 1083 ··· 1148 1091 for (i = 0; i < pf->pev->nargs; i++) { 1149 1092 pf->pvar = &pf->pev->args[i]; 1150 1093 pf->tvar = &tev->args[i]; 1151 - ret = find_variable(sp_die, pf); 1094 + /* Variable should be found from scope DIE */ 1095 + ret = find_variable(sc_die, pf); 1152 1096 if (ret != 0) 1153 1097 return ret; 1154 1098 } ··· 1217 1159 } 1218 1160 1219 1161 /* Add a found vars into available variables list */ 1220 - static int add_available_vars(Dwarf_Die *sp_die, struct probe_finder *pf) 1162 + static int add_available_vars(Dwarf_Die *sc_die, struct probe_finder *pf) 1221 1163 { 1222 1164 struct available_var_finder *af = 1223 1165 container_of(pf, struct available_var_finder, pf); 1224 1166 struct variable_list *vl; 1225 - Dwarf_Die die_mem, *scopes = NULL; 1226 - int ret, nscopes; 1167 + Dwarf_Die die_mem; 1168 + int ret; 1227 1169 1228 1170 /* Check number of tevs */ 1229 1171 if (af->nvls == af->max_vls) { ··· 1232 1174 } 1233 1175 vl = &af->vls[af->nvls++]; 1234 1176 1235 - ret = convert_to_trace_point(sp_die, pf->addr, pf->pev->point.retprobe, 1236 - &vl->point); 1177 + /* Trace point should be converted from subprogram DIE */ 1178 + ret = convert_to_trace_point(&pf->sp_die, pf->addr, 1179 + pf->pev->point.retprobe, &vl->point); 1237 1180 if (ret < 0) 1238 1181 return ret; 1239 1182 ··· 1246 1187 if (vl->vars == NULL) 1247 1188 return -ENOMEM; 1248 1189 af->child = true; 1249 - die_find_child(sp_die, collect_variables_cb, (void *)af, &die_mem); 1190 + die_find_child(sc_die, collect_variables_cb, (void *)af, &die_mem); 1250 1191 1251 1192 /* Find external variables */ 1252 1193 if (!af->externs) 1253 1194 goto out; 1254 1195 /* Don't need to search child DIE for externs. */ 1255 1196 af->child = false; 1256 - nscopes = dwarf_getscopes_die(sp_die, &scopes); 1257 - while (nscopes-- > 1) 1258 - die_find_child(&scopes[nscopes], collect_variables_cb, 1259 - (void *)af, &die_mem); 1260 - if (scopes) 1261 - free(scopes); 1197 + die_find_child(&pf->cu_die, collect_variables_cb, (void *)af, &die_mem); 1262 1198 1263 1199 out: 1264 1200 if (strlist__empty(vl->vars)) { ··· 1445 1391 1446 1392 static int line_range_inline_cb(Dwarf_Die *in_die, void *data) 1447 1393 { 1448 - struct dwarf_callback_param *param = data; 1394 + find_line_range_by_line(in_die, data); 1449 1395 1450 - param->retval = find_line_range_by_line(in_die, param->data); 1451 - return DWARF_CB_ABORT; /* No need to find other instances */ 1396 + /* 1397 + * We have to check all instances of inlined function, because 1398 + * some execution paths can be optimized out depends on the 1399 + * function argument of instances 1400 + */ 1401 + return 0; 1452 1402 } 1453 1403 1454 1404 /* Search function from function name */ ··· 1480 1422 pr_debug("New line range: %d to %d\n", lf->lno_s, lf->lno_e); 1481 1423 lr->start = lf->lno_s; 1482 1424 lr->end = lf->lno_e; 1483 - if (dwarf_func_inline(sp_die)) { 1484 - struct dwarf_callback_param _param; 1485 - _param.data = (void *)lf; 1486 - _param.retval = 0; 1487 - dwarf_func_inline_instances(sp_die, 1488 - line_range_inline_cb, 1489 - &_param); 1490 - param->retval = _param.retval; 1491 - } else 1425 + if (dwarf_func_inline(sp_die)) 1426 + param->retval = die_walk_instances(sp_die, 1427 + line_range_inline_cb, lf); 1428 + else 1492 1429 param->retval = find_line_range_by_line(sp_die, lf); 1493 1430 return DWARF_CB_ABORT; 1494 1431 }
+1 -1
tools/perf/util/probe-finder.h
··· 57 57 struct perf_probe_event *pev; /* Target probe event */ 58 58 59 59 /* Callback when a probe point is found */ 60 - int (*callback)(Dwarf_Die *sp_die, struct probe_finder *pf); 60 + int (*callback)(Dwarf_Die *sc_die, struct probe_finder *pf); 61 61 62 62 /* For function searching */ 63 63 int lno; /* Line number */
+33 -26
tools/perf/util/symbol.c
··· 1506 1506 if (strncmp(dso->name, "/tmp/perf-", 10) == 0) { 1507 1507 struct stat st; 1508 1508 1509 - if (stat(dso->name, &st) < 0) 1509 + if (lstat(dso->name, &st) < 0) 1510 1510 return -1; 1511 1511 1512 1512 if (st.st_uid && (st.st_uid != geteuid())) { ··· 2181 2181 return ret; 2182 2182 } 2183 2183 2184 - struct dso *dso__new_kernel(const char *name) 2184 + static struct dso* 2185 + dso__kernel_findnew(struct machine *machine, const char *name, 2186 + const char *short_name, int dso_type) 2185 2187 { 2186 - struct dso *dso = dso__new(name ?: "[kernel.kallsyms]"); 2188 + /* 2189 + * The kernel dso could be created by build_id processing. 2190 + */ 2191 + struct dso *dso = __dsos__findnew(&machine->kernel_dsos, name); 2187 2192 2193 + /* 2194 + * We need to run this in all cases, since during the build_id 2195 + * processing we had no idea this was the kernel dso. 2196 + */ 2188 2197 if (dso != NULL) { 2189 - dso__set_short_name(dso, "[kernel]"); 2190 - dso->kernel = DSO_TYPE_KERNEL; 2191 - } 2192 - 2193 - return dso; 2194 - } 2195 - 2196 - static struct dso *dso__new_guest_kernel(struct machine *machine, 2197 - const char *name) 2198 - { 2199 - char bf[PATH_MAX]; 2200 - struct dso *dso = dso__new(name ?: machine__mmap_name(machine, bf, 2201 - sizeof(bf))); 2202 - if (dso != NULL) { 2203 - dso__set_short_name(dso, "[guest.kernel]"); 2204 - dso->kernel = DSO_TYPE_GUEST_KERNEL; 2198 + dso__set_short_name(dso, short_name); 2199 + dso->kernel = dso_type; 2205 2200 } 2206 2201 2207 2202 return dso; ··· 2214 2219 dso->has_build_id = true; 2215 2220 } 2216 2221 2217 - static struct dso *machine__create_kernel(struct machine *machine) 2222 + static struct dso *machine__get_kernel(struct machine *machine) 2218 2223 { 2219 2224 const char *vmlinux_name = NULL; 2220 2225 struct dso *kernel; 2221 2226 2222 2227 if (machine__is_host(machine)) { 2223 2228 vmlinux_name = symbol_conf.vmlinux_name; 2224 - kernel = dso__new_kernel(vmlinux_name); 2229 + if (!vmlinux_name) 2230 + vmlinux_name = "[kernel.kallsyms]"; 2231 + 2232 + kernel = dso__kernel_findnew(machine, vmlinux_name, 2233 + "[kernel]", 2234 + DSO_TYPE_KERNEL); 2225 2235 } else { 2236 + char bf[PATH_MAX]; 2237 + 2226 2238 if (machine__is_default_guest(machine)) 2227 2239 vmlinux_name = symbol_conf.default_guest_vmlinux_name; 2228 - kernel = dso__new_guest_kernel(machine, vmlinux_name); 2240 + if (!vmlinux_name) 2241 + vmlinux_name = machine__mmap_name(machine, bf, 2242 + sizeof(bf)); 2243 + 2244 + kernel = dso__kernel_findnew(machine, vmlinux_name, 2245 + "[guest.kernel]", 2246 + DSO_TYPE_GUEST_KERNEL); 2229 2247 } 2230 2248 2231 - if (kernel != NULL) { 2249 + if (kernel != NULL && (!kernel->has_build_id)) 2232 2250 dso__read_running_kernel_build_id(kernel, machine); 2233 - dsos__add(&machine->kernel_dsos, kernel); 2234 - } 2251 + 2235 2252 return kernel; 2236 2253 } 2237 2254 ··· 2347 2340 2348 2341 int machine__create_kernel_maps(struct machine *machine) 2349 2342 { 2350 - struct dso *kernel = machine__create_kernel(machine); 2343 + struct dso *kernel = machine__get_kernel(machine); 2351 2344 2352 2345 if (kernel == NULL || 2353 2346 __machine__create_kernel_maps(machine, kernel) < 0)
-1
tools/perf/util/symbol.h
··· 155 155 }; 156 156 157 157 struct dso *dso__new(const char *name); 158 - struct dso *dso__new_kernel(const char *name); 159 158 void dso__delete(struct dso *dso); 160 159 161 160 int dso__name_len(const struct dso *dso);
-1
tools/perf/util/ui/browsers/top.c
··· 208 208 }, 209 209 }; 210 210 211 - ui_helpline__push("Press <- or ESC to exit"); 212 211 return perf_top_browser__run(&browser); 213 212 }