mirror of https://gitee.com/openkylin/linux.git
perf trace: Fix segfault on perf trace -i perf.data
When replaying a previous record session, it'll get a segfault since it doesn't initialize raw_syscalls enter/exit tracepoint's evsel->priv for caching the format fields. So fix it by properly initializing sys_enter/exit evsels that comes from reading the perf.data file header. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Pekka Enberg <penberg@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1384237500-22991-2-git-send-email-namhyung@kernel.org [ Split the syscall tp field caching part in the previous patch ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
96695d4402
commit
003824e8c2
|
@ -1766,16 +1766,6 @@ static int trace__process_sample(struct perf_tool *tool,
|
|||
return err;
|
||||
}
|
||||
|
||||
static bool
|
||||
perf_session__has_tp(struct perf_session *session, const char *name)
|
||||
{
|
||||
struct perf_evsel *evsel;
|
||||
|
||||
evsel = perf_evlist__find_tracepoint_by_name(session->evlist, name);
|
||||
|
||||
return evsel != NULL;
|
||||
}
|
||||
|
||||
static int parse_target_str(struct trace *trace)
|
||||
{
|
||||
if (trace->opts.target.pid) {
|
||||
|
@ -2012,8 +2002,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
|
|||
static int trace__replay(struct trace *trace)
|
||||
{
|
||||
const struct perf_evsel_str_handler handlers[] = {
|
||||
{ "raw_syscalls:sys_enter", trace__sys_enter, },
|
||||
{ "raw_syscalls:sys_exit", trace__sys_exit, },
|
||||
{ "probe:vfs_getname", trace__vfs_getname, },
|
||||
};
|
||||
struct perf_data_file file = {
|
||||
|
@ -2021,6 +2009,7 @@ static int trace__replay(struct trace *trace)
|
|||
.mode = PERF_DATA_MODE_READ,
|
||||
};
|
||||
struct perf_session *session;
|
||||
struct perf_evsel *evsel;
|
||||
int err = -1;
|
||||
|
||||
trace->tool.sample = trace__process_sample;
|
||||
|
@ -2052,13 +2041,29 @@ static int trace__replay(struct trace *trace)
|
|||
if (err)
|
||||
goto out;
|
||||
|
||||
if (!perf_session__has_tp(session, "raw_syscalls:sys_enter")) {
|
||||
pr_err("Data file does not have raw_syscalls:sys_enter events\n");
|
||||
evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
|
||||
"raw_syscalls:sys_enter");
|
||||
if (evsel == NULL) {
|
||||
pr_err("Data file does not have raw_syscalls:sys_enter event\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!perf_session__has_tp(session, "raw_syscalls:sys_exit")) {
|
||||
pr_err("Data file does not have raw_syscalls:sys_exit events\n");
|
||||
if (perf_evsel__init_syscall_tp(evsel, trace__sys_enter) < 0 ||
|
||||
perf_evsel__init_sc_tp_ptr_field(evsel, args)) {
|
||||
pr_err("Error during initialize raw_syscalls:sys_enter event\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
|
||||
"raw_syscalls:sys_exit");
|
||||
if (evsel == NULL) {
|
||||
pr_err("Data file does not have raw_syscalls:sys_exit event\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (perf_evsel__init_syscall_tp(evsel, trace__sys_exit) < 0 ||
|
||||
perf_evsel__init_sc_tp_uint_field(evsel, ret)) {
|
||||
pr_err("Error during initialize raw_syscalls:sys_exit event\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue