mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 08:31:55 +00:00
59c24980df
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>
92 lines
2.4 KiB
C
92 lines
2.4 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/* Display a menu with individual samples to browse with perf script */
|
|
#include "util.h"
|
|
#include "hist.h"
|
|
#include "evsel.h"
|
|
#include "hists.h"
|
|
#include "sort.h"
|
|
#include "config.h"
|
|
#include "time-utils.h"
|
|
#include <linux/time64.h>
|
|
|
|
static u64 context_len = 10 * NSEC_PER_MSEC;
|
|
|
|
static int res_sample_config(const char *var, const char *value, void *data __maybe_unused)
|
|
{
|
|
if (!strcmp(var, "samples.context"))
|
|
return perf_config_u64(&context_len, var, value);
|
|
return 0;
|
|
}
|
|
|
|
void res_sample_init(void)
|
|
{
|
|
perf_config(res_sample_config, NULL);
|
|
}
|
|
|
|
int res_sample_browse(struct res_sample *res_samples, int num_res,
|
|
struct perf_evsel *evsel, enum rstype rstype)
|
|
{
|
|
char **names;
|
|
int i, n;
|
|
int choice;
|
|
char *cmd;
|
|
char pbuf[256], tidbuf[32], cpubuf[32];
|
|
const char *perf = perf_exe(pbuf, sizeof pbuf);
|
|
char trange[128], tsample[64];
|
|
struct res_sample *r;
|
|
char extra_format[256];
|
|
|
|
names = calloc(num_res, sizeof(char *));
|
|
if (!names)
|
|
return -1;
|
|
for (i = 0; i < num_res; i++) {
|
|
char tbuf[64];
|
|
|
|
timestamp__scnprintf_nsec(res_samples[i].time, tbuf, sizeof tbuf);
|
|
if (asprintf(&names[i], "%s: CPU %d tid %d", tbuf,
|
|
res_samples[i].cpu, res_samples[i].tid) < 0) {
|
|
while (--i >= 0)
|
|
free(names[i]);
|
|
free(names);
|
|
return -1;
|
|
}
|
|
}
|
|
choice = ui__popup_menu(num_res, names);
|
|
for (i = 0; i < num_res; i++)
|
|
free(names[i]);
|
|
free(names);
|
|
|
|
if (choice < 0 || choice >= num_res)
|
|
return -1;
|
|
r = &res_samples[choice];
|
|
|
|
n = timestamp__scnprintf_nsec(r->time - context_len, trange, sizeof trange);
|
|
trange[n++] = ',';
|
|
timestamp__scnprintf_nsec(r->time + context_len, trange + n, sizeof trange - n);
|
|
|
|
timestamp__scnprintf_nsec(r->time, tsample, sizeof tsample);
|
|
|
|
attr_to_script(extra_format, &evsel->attr);
|
|
|
|
if (asprintf(&cmd, "%s script %s%s --time %s %s%s %s%s --ns %s %s %s %s %s | less +/%s",
|
|
perf,
|
|
input_name ? "-i " : "",
|
|
input_name ? input_name : "",
|
|
trange,
|
|
r->cpu >= 0 ? "--cpu " : "",
|
|
r->cpu >= 0 ? (sprintf(cpubuf, "%d", r->cpu), cpubuf) : "",
|
|
r->tid ? "--tid " : "",
|
|
r->tid ? (sprintf(tidbuf, "%d", r->tid), tidbuf) : "",
|
|
extra_format,
|
|
rstype == A_ASM ? "-F +insn --xed" :
|
|
rstype == A_SOURCE ? "-F +srcline,+srccode" : "",
|
|
symbol_conf.inline_name ? "--inline" : "",
|
|
"--show-lost-events ",
|
|
r->tid ? "--show-switch-events --show-task-events " : "",
|
|
tsample) < 0)
|
|
return -1;
|
|
run_script(cmd);
|
|
free(cmd);
|
|
return 0;
|
|
}
|