Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf annotate: fix a crash when annotate the same symbol with 's' and 'T'

When perf report with annotation for a symbol, press 's' and 'T', then exit
the annotate browser. Once annotate the same symbol, the annotate browser
will crash.

The browser.arch was required to be correctly updated when data type
feature was enabled by 'T'. Usually it was initialized by symbol__annotate2
function. If a symbol has already been correctly annotated at the first
time, it should not call the symbol__annotate2 function again, thus the
browser.arch will not get initialized. Then at the second time to show the
annotate browser, the data type needs to be displayed but the browser.arch
is empty.

Stack trace as below:

Perf: Segmentation fault
-------- backtrace --------
#0 0x55d365 in ui__signal_backtrace setup.c:0
#1 0x7f5ff1a3e930 in __restore_rt libc.so.6[3e930]
#2 0x570f08 in arch__is perf[570f08]
#3 0x562186 in annotate_get_insn_location perf[562186]
#4 0x562626 in __hist_entry__get_data_type annotate.c:0
#5 0x56476d in annotation_line__write perf[56476d]
#6 0x54e2db in annotate_browser__write annotate.c:0
#7 0x54d061 in ui_browser__list_head_refresh perf[54d061]
#8 0x54dc9e in annotate_browser__refresh annotate.c:0
#9 0x54c03d in __ui_browser__refresh browser.c:0
#10 0x54ccf8 in ui_browser__run perf[54ccf8]
#11 0x54eb92 in __hist_entry__tui_annotate perf[54eb92]
#12 0x552293 in do_annotate hists.c:0
#13 0x55941c in evsel__hists_browse hists.c:0
#14 0x55b00f in evlist__tui_browse_hists perf[55b00f]
#15 0x42ff02 in cmd_report perf[42ff02]
#16 0x494008 in run_builtin perf.c:0
#17 0x494305 in handle_internal_command perf.c:0
#18 0x410547 in main perf[410547]
#19 0x7f5ff1a295d0 in __libc_start_call_main libc.so.6[295d0]
#20 0x7f5ff1a29680 in __libc_start_main@@GLIBC_2.34 libc.so.6[29680]
#21 0x410b75 in _start perf[410b75]

Fixes: 1d4374afd000 ("perf annotate: Add 'T' hot key to toggle data type display")
Reviewed-by: James Clark <james.clark@linaro.org>
Tested-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Tianyou Li <tianyou.li@intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>

authored by

Tianyou Li and committed by
Namhyung Kim
262c6143 0e6c07a3

+22 -5
+19 -4
tools/perf/ui/browsers/annotate.c
··· 862 862 return al ? al->offset : 0; 863 863 } 864 864 865 + static void annotate_browser__symbol_annotate_error(struct annotate_browser *browser, int err) 866 + { 867 + struct map_symbol *ms = browser->b.priv; 868 + struct symbol *sym = ms->sym; 869 + struct dso *dso = map__dso(ms->map); 870 + char msg[BUFSIZ]; 871 + 872 + dso__set_annotate_warned(dso); 873 + symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); 874 + ui__error("Couldn't annotate %s:\n%s", sym->name, msg); 875 + } 876 + 865 877 static int annotate_browser__run(struct annotate_browser *browser, 866 878 struct evsel *evsel, 867 879 struct hist_browser_timer *hbt) ··· 1187 1175 if (not_annotated || !sym->annotate2) { 1188 1176 err = symbol__annotate2(ms, evsel, &browser.arch); 1189 1177 if (err) { 1190 - char msg[BUFSIZ]; 1191 - dso__set_annotate_warned(dso); 1192 - symbol__strerror_disassemble(ms, err, msg, sizeof(msg)); 1193 - ui__error("Couldn't annotate %s:\n%s", sym->name, msg); 1178 + annotate_browser__symbol_annotate_error(&browser, err); 1194 1179 return -1; 1195 1180 } 1196 1181 ··· 1195 1186 notes->src->tried_source = true; 1196 1187 if (!annotation__has_source(notes)) 1197 1188 ui__warning("Annotation has no source code."); 1189 + } 1190 + } else { 1191 + err = evsel__get_arch(evsel, &browser.arch); 1192 + if (err) { 1193 + annotate_browser__symbol_annotate_error(&browser, err); 1194 + return -1; 1198 1195 } 1199 1196 } 1200 1197
+1 -1
tools/perf/util/annotate.c
··· 980 980 annotation__calc_percent(notes, evsel, symbol__size(sym)); 981 981 } 982 982 983 - static int evsel__get_arch(struct evsel *evsel, struct arch **parch) 983 + int evsel__get_arch(struct evsel *evsel, struct arch **parch) 984 984 { 985 985 struct perf_env *env = evsel__env(evsel); 986 986 const char *arch_name = perf_env__arch(env);
+2
tools/perf/util/annotate.h
··· 585 585 int annotation_br_cntr_entry(char **str, int br_cntr_nr, u64 *br_cntr, 586 586 int num_aggr, struct evsel *evsel); 587 587 int annotation_br_cntr_abbr_list(char **str, struct evsel *evsel, bool header); 588 + 589 + int evsel__get_arch(struct evsel *evsel, struct arch **parch); 588 590 #endif /* __PERF_ANNOTATE_H */