aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/ui/browser.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2019-03-11 10:45:02 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2019-03-11 15:33:20 -0400
commit59c24980dffbea2106fe65e64ea77834d657ee9c (patch)
treeb6e1b75844e8f7b1cf199fd78eecb64df6d92f60 /tools/perf/ui/browser.c
parent905e4aff31382c3f9b2014d1361f4a1be4479ba2 (diff)
perf ui browser: Fix ui popup argv browser for many entries
Fix the argv ui browser code to correctly display more entries than fit on the screen without crashing. The problem was some type confusion with pointer types in the ->seek function. Do the argv arithmetic correctly with char ** pointers. Also add some asserts to find overruns and limit the display function correctly. Then finally remove a workaround for this in the res sample browser. Committer testing: 1) Resize the x terminal to have just some 5 lines 2) Use 'perf report --samples 1' to activate the sample browser options in the menu 3) Press ENTER, this will cause the crash: # perf report --samples 1 perf: Segmentation fault -------- backtrace -------- perf[0x5a514a] /lib64/libc.so.6(+0x385bf)[0x7f27281b55bf] /lib64/libc.so.6(+0x161a67)[0x7f27282dea67] /lib64/libslang.so.2(SLsmg_write_wrapped_string+0x82)[0x7f272874a0b2] perf(ui_browser__argv_refresh+0x77)[0x5939a7] perf[0x5924cc] perf(ui_browser__run+0x39)[0x593449] perf(ui__popup_menu+0x83)[0x5a5263] perf[0x59f421] perf(perf_evlist__tui_browse_hists+0x3a0)[0x5a3780] perf(cmd_report+0x2746)[0x447136] perf[0x4a95fe] perf(main+0x61c)[0x42dc6c] /lib64/libc.so.6(__libc_start_main+0xf2)[0x7f27281a1412] perf(_start+0x2d)[0x42de9d] # After applying this patch no crash takes place in such situation. Signed-off-by: Andi Kleen <ak@linux.intel.com> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: http://lkml.kernel.org/r/20190311144502.15423-12-andi@firstfloor.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/ui/browser.c')
-rw-r--r--tools/perf/ui/browser.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 4f75561424ed..4ad37d8c7d6a 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -611,14 +611,16 @@ void ui_browser__argv_seek(struct ui_browser *browser, off_t offset, int whence)
611 browser->top = browser->entries; 611 browser->top = browser->entries;
612 break; 612 break;
613 case SEEK_CUR: 613 case SEEK_CUR:
614 browser->top = browser->top + browser->top_idx + offset; 614 browser->top = (char **)browser->top + offset;
615 break; 615 break;
616 case SEEK_END: 616 case SEEK_END:
617 browser->top = browser->top + browser->nr_entries - 1 + offset; 617 browser->top = (char **)browser->entries + browser->nr_entries - 1 + offset;
618 break; 618 break;
619 default: 619 default:
620 return; 620 return;
621 } 621 }
622 assert((char **)browser->top < (char **)browser->entries + browser->nr_entries);
623 assert((char **)browser->top >= (char **)browser->entries);
622} 624}
623 625
624unsigned int ui_browser__argv_refresh(struct ui_browser *browser) 626unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
@@ -630,7 +632,9 @@ unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
630 browser->top = browser->entries; 632 browser->top = browser->entries;
631 633
632 pos = (char **)browser->top; 634 pos = (char **)browser->top;
633 while (idx < browser->nr_entries) { 635 while (idx < browser->nr_entries &&
636 row < (unsigned)SLtt_Screen_Rows - 1) {
637 assert(pos < (char **)browser->entries + browser->nr_entries);
634 if (!browser->filter || !browser->filter(browser, *pos)) { 638 if (!browser->filter || !browser->filter(browser, *pos)) {
635 ui_browser__gotorc(browser, row, 0); 639 ui_browser__gotorc(browser, row, 0);
636 browser->write(browser, pos, row); 640 browser->write(browser, pos, row);