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

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>

authored by

Namhyung Kim and committed by
Arnaldo Carvalho de Melo
003824e8 96695d44

+21 -16
+21 -16
tools/perf/builtin-trace.c
··· 1766 1766 return err; 1767 1767 } 1768 1768 1769 - static bool 1770 - perf_session__has_tp(struct perf_session *session, const char *name) 1771 - { 1772 - struct perf_evsel *evsel; 1773 - 1774 - evsel = perf_evlist__find_tracepoint_by_name(session->evlist, name); 1775 - 1776 - return evsel != NULL; 1777 - } 1778 - 1779 1769 static int parse_target_str(struct trace *trace) 1780 1770 { 1781 1771 if (trace->opts.target.pid) { ··· 2002 2012 static int trace__replay(struct trace *trace) 2003 2013 { 2004 2014 const struct perf_evsel_str_handler handlers[] = { 2005 - { "raw_syscalls:sys_enter", trace__sys_enter, }, 2006 - { "raw_syscalls:sys_exit", trace__sys_exit, }, 2007 2015 { "probe:vfs_getname", trace__vfs_getname, }, 2008 2016 }; 2009 2017 struct perf_data_file file = { ··· 2009 2021 .mode = PERF_DATA_MODE_READ, 2010 2022 }; 2011 2023 struct perf_session *session; 2024 + struct perf_evsel *evsel; 2012 2025 int err = -1; 2013 2026 2014 2027 trace->tool.sample = trace__process_sample; ··· 2041 2052 if (err) 2042 2053 goto out; 2043 2054 2044 - if (!perf_session__has_tp(session, "raw_syscalls:sys_enter")) { 2045 - pr_err("Data file does not have raw_syscalls:sys_enter events\n"); 2055 + evsel = perf_evlist__find_tracepoint_by_name(session->evlist, 2056 + "raw_syscalls:sys_enter"); 2057 + if (evsel == NULL) { 2058 + pr_err("Data file does not have raw_syscalls:sys_enter event\n"); 2046 2059 goto out; 2047 2060 } 2048 2061 2049 - if (!perf_session__has_tp(session, "raw_syscalls:sys_exit")) { 2050 - pr_err("Data file does not have raw_syscalls:sys_exit events\n"); 2062 + if (perf_evsel__init_syscall_tp(evsel, trace__sys_enter) < 0 || 2063 + perf_evsel__init_sc_tp_ptr_field(evsel, args)) { 2064 + pr_err("Error during initialize raw_syscalls:sys_enter event\n"); 2065 + goto out; 2066 + } 2067 + 2068 + evsel = perf_evlist__find_tracepoint_by_name(session->evlist, 2069 + "raw_syscalls:sys_exit"); 2070 + if (evsel == NULL) { 2071 + pr_err("Data file does not have raw_syscalls:sys_exit event\n"); 2072 + goto out; 2073 + } 2074 + 2075 + if (perf_evsel__init_syscall_tp(evsel, trace__sys_exit) < 0 || 2076 + perf_evsel__init_sc_tp_uint_field(evsel, ret)) { 2077 + pr_err("Error during initialize raw_syscalls:sys_exit event\n"); 2051 2078 goto out; 2052 2079 } 2053 2080