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;
|
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)
|
static int parse_target_str(struct trace *trace)
|
||||||
{
|
{
|
||||||
if (trace->opts.target.pid) {
|
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)
|
static int trace__replay(struct trace *trace)
|
||||||
{
|
{
|
||||||
const struct perf_evsel_str_handler handlers[] = {
|
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, },
|
{ "probe:vfs_getname", trace__vfs_getname, },
|
||||||
};
|
};
|
||||||
struct perf_data_file file = {
|
struct perf_data_file file = {
|
||||||
@ -2021,6 +2009,7 @@ static int trace__replay(struct trace *trace)
|
|||||||
.mode = PERF_DATA_MODE_READ,
|
.mode = PERF_DATA_MODE_READ,
|
||||||
};
|
};
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
|
struct perf_evsel *evsel;
|
||||||
int err = -1;
|
int err = -1;
|
||||||
|
|
||||||
trace->tool.sample = trace__process_sample;
|
trace->tool.sample = trace__process_sample;
|
||||||
@ -2052,13 +2041,29 @@ static int trace__replay(struct trace *trace)
|
|||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!perf_session__has_tp(session, "raw_syscalls:sys_enter")) {
|
evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
|
||||||
pr_err("Data file does not have raw_syscalls:sys_enter events\n");
|
"raw_syscalls:sys_enter");
|
||||||
|
if (evsel == NULL) {
|
||||||
|
pr_err("Data file does not have raw_syscalls:sys_enter event\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!perf_session__has_tp(session, "raw_syscalls:sys_exit")) {
|
if (perf_evsel__init_syscall_tp(evsel, trace__sys_enter) < 0 ||
|
||||||
pr_err("Data file does not have raw_syscalls:sys_exit events\n");
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user