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

Pull perf tooling fixes from Thomas Gleixner:
"Another round of fixes for the perf tooling side:

- Prevent a NULL pointer dereference in tracepoint error handling

- Fix a thread handling bug in the intel_pt error handling code

- Search both .eh_frame and .debug_frame sections as toolchains seem
to have random choices of storing the CFI information

- Fix the perf state interval output values, which got broken when
fixing the overall output"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf stat: Fix interval output values
perf probe: Search both .eh_frame and .debug_frame sections for probe location
perf tools: Fix thread lifetime related segfaut in intel_pt
perf tools: tracepoint_error() can receive e=NULL, robustify it

Changed files
+63 -26
tools
+9
tools/perf/util/intel-pt.c
··· 2068 2068 err = -ENOMEM; 2069 2069 goto err_free_queues; 2070 2070 } 2071 + 2072 + /* 2073 + * Since this thread will not be kept in any rbtree not in a 2074 + * list, initialize its list node so that at thread__put() the 2075 + * current thread lifetime assuption is kept and we don't segfault 2076 + * at list_del_init(). 2077 + */ 2078 + INIT_LIST_HEAD(&pt->unknown_thread->node); 2079 + 2071 2080 err = thread__set_comm(pt->unknown_thread, "unknown", 0); 2072 2081 if (err) 2073 2082 goto err_delete_thread;
+3
tools/perf/util/parse-events.c
··· 399 399 { 400 400 char help[BUFSIZ]; 401 401 402 + if (!e) 403 + return; 404 + 402 405 /* 403 406 * We get error directly from syscall errno ( > 0), 404 407 * or from encoded pointer's error ( < 0).
+37 -25
tools/perf/util/probe-finder.c
··· 686 686 pf->fb_ops = NULL; 687 687 #if _ELFUTILS_PREREQ(0, 142) 688 688 } else if (nops == 1 && pf->fb_ops[0].atom == DW_OP_call_frame_cfa && 689 - pf->cfi != NULL) { 690 - if (dwarf_cfi_addrframe(pf->cfi, pf->addr, &frame) != 0 || 689 + (pf->cfi_eh != NULL || pf->cfi_dbg != NULL)) { 690 + if ((dwarf_cfi_addrframe(pf->cfi_eh, pf->addr, &frame) != 0 && 691 + (dwarf_cfi_addrframe(pf->cfi_dbg, pf->addr, &frame) != 0)) || 691 692 dwarf_frame_cfa(frame, &pf->fb_ops, &nops) != 0) { 692 693 pr_warning("Failed to get call frame on 0x%jx\n", 693 694 (uintmax_t)pf->addr); ··· 1016 1015 return DWARF_CB_OK; 1017 1016 } 1018 1017 1019 - /* Find probe points from debuginfo */ 1020 - static int debuginfo__find_probes(struct debuginfo *dbg, 1018 + static int debuginfo__find_probe_location(struct debuginfo *dbg, 1021 1019 struct probe_finder *pf) 1022 1020 { 1023 1021 struct perf_probe_point *pp = &pf->pev->point; ··· 1024 1024 size_t cuhl; 1025 1025 Dwarf_Die *diep; 1026 1026 int ret = 0; 1027 - 1028 - #if _ELFUTILS_PREREQ(0, 142) 1029 - Elf *elf; 1030 - GElf_Ehdr ehdr; 1031 - GElf_Shdr shdr; 1032 - 1033 - /* Get the call frame information from this dwarf */ 1034 - elf = dwarf_getelf(dbg->dbg); 1035 - if (elf == NULL) 1036 - return -EINVAL; 1037 - 1038 - if (gelf_getehdr(elf, &ehdr) == NULL) 1039 - return -EINVAL; 1040 - 1041 - if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) && 1042 - shdr.sh_type == SHT_PROGBITS) { 1043 - pf->cfi = dwarf_getcfi_elf(elf); 1044 - } else { 1045 - pf->cfi = dwarf_getcfi(dbg->dbg); 1046 - } 1047 - #endif 1048 1027 1049 1028 off = 0; 1050 1029 pf->lcache = intlist__new(NULL); ··· 1084 1105 intlist__delete(pf->lcache); 1085 1106 pf->lcache = NULL; 1086 1107 1108 + return ret; 1109 + } 1110 + 1111 + /* Find probe points from debuginfo */ 1112 + static int debuginfo__find_probes(struct debuginfo *dbg, 1113 + struct probe_finder *pf) 1114 + { 1115 + int ret = 0; 1116 + 1117 + #if _ELFUTILS_PREREQ(0, 142) 1118 + Elf *elf; 1119 + GElf_Ehdr ehdr; 1120 + GElf_Shdr shdr; 1121 + 1122 + if (pf->cfi_eh || pf->cfi_dbg) 1123 + return debuginfo__find_probe_location(dbg, pf); 1124 + 1125 + /* Get the call frame information from this dwarf */ 1126 + elf = dwarf_getelf(dbg->dbg); 1127 + if (elf == NULL) 1128 + return -EINVAL; 1129 + 1130 + if (gelf_getehdr(elf, &ehdr) == NULL) 1131 + return -EINVAL; 1132 + 1133 + if (elf_section_by_name(elf, &ehdr, &shdr, ".eh_frame", NULL) && 1134 + shdr.sh_type == SHT_PROGBITS) 1135 + pf->cfi_eh = dwarf_getcfi_elf(elf); 1136 + 1137 + pf->cfi_dbg = dwarf_getcfi(dbg->dbg); 1138 + #endif 1139 + 1140 + ret = debuginfo__find_probe_location(dbg, pf); 1087 1141 return ret; 1088 1142 } 1089 1143
+4 -1
tools/perf/util/probe-finder.h
··· 76 76 77 77 /* For variable searching */ 78 78 #if _ELFUTILS_PREREQ(0, 142) 79 - Dwarf_CFI *cfi; /* Call Frame Information */ 79 + /* Call Frame Information from .eh_frame */ 80 + Dwarf_CFI *cfi_eh; 81 + /* Call Frame Information from .debug_frame */ 82 + Dwarf_CFI *cfi_dbg; 80 83 #endif 81 84 Dwarf_Op *fb_ops; /* Frame base attribute */ 82 85 struct perf_probe_arg *pvar; /* Current target variable */
+10
tools/perf/util/stat.c
··· 311 311 312 312 aggr->val = aggr->ena = aggr->run = 0; 313 313 314 + /* 315 + * We calculate counter's data every interval, 316 + * and the display code shows ps->res_stats 317 + * avg value. We need to zero the stats for 318 + * interval mode, otherwise overall avg running 319 + * averages will be shown for each interval. 320 + */ 321 + if (config->interval) 322 + init_stats(ps->res_stats); 323 + 314 324 if (counter->per_pkg) 315 325 zero_per_pkg(counter); 316 326