diff options
author | Namhyung Kim <namhyung.kim@lge.com> | 2013-11-12 01:25:00 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-11-12 11:00:37 -0500 |
commit | 003824e8c27eeb8d3eec54cfab5845ec01ab532e (patch) | |
tree | e9a8b32744407d4b87ad0644576c48341a612f07 /tools/perf | |
parent | 96695d440242aca871ef8d797bd98d9cbd7ad8a0 (diff) |
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>
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/builtin-trace.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index 3fa1dce6d43e..8d6ea8fbf476 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -1766,16 +1766,6 @@ static int trace__process_sample(struct perf_tool *tool, | |||
1766 | return err; | 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 | static int parse_target_str(struct trace *trace) | 1769 | static int parse_target_str(struct trace *trace) |
1780 | { | 1770 | { |
1781 | if (trace->opts.target.pid) { | 1771 | if (trace->opts.target.pid) { |
@@ -2012,8 +2002,6 @@ out_error: | |||
2012 | static int trace__replay(struct trace *trace) | 2002 | static int trace__replay(struct trace *trace) |
2013 | { | 2003 | { |
2014 | const struct perf_evsel_str_handler handlers[] = { | 2004 | const struct perf_evsel_str_handler handlers[] = { |
2015 | { "raw_syscalls:sys_enter", trace__sys_enter, }, | ||
2016 | { "raw_syscalls:sys_exit", trace__sys_exit, }, | ||
2017 | { "probe:vfs_getname", trace__vfs_getname, }, | 2005 | { "probe:vfs_getname", trace__vfs_getname, }, |
2018 | }; | 2006 | }; |
2019 | struct perf_data_file file = { | 2007 | struct perf_data_file file = { |
@@ -2021,6 +2009,7 @@ static int trace__replay(struct trace *trace) | |||
2021 | .mode = PERF_DATA_MODE_READ, | 2009 | .mode = PERF_DATA_MODE_READ, |
2022 | }; | 2010 | }; |
2023 | struct perf_session *session; | 2011 | struct perf_session *session; |
2012 | struct perf_evsel *evsel; | ||
2024 | int err = -1; | 2013 | int err = -1; |
2025 | 2014 | ||
2026 | trace->tool.sample = trace__process_sample; | 2015 | trace->tool.sample = trace__process_sample; |
@@ -2052,13 +2041,29 @@ static int trace__replay(struct trace *trace) | |||
2052 | if (err) | 2041 | if (err) |
2053 | goto out; | 2042 | goto out; |
2054 | 2043 | ||
2055 | if (!perf_session__has_tp(session, "raw_syscalls:sys_enter")) { | 2044 | evsel = perf_evlist__find_tracepoint_by_name(session->evlist, |
2056 | pr_err("Data file does not have raw_syscalls:sys_enter events\n"); | 2045 | "raw_syscalls:sys_enter"); |
2046 | if (evsel == NULL) { | ||
2047 | pr_err("Data file does not have raw_syscalls:sys_enter event\n"); | ||
2048 | goto out; | ||
2049 | } | ||
2050 | |||
2051 | if (perf_evsel__init_syscall_tp(evsel, trace__sys_enter) < 0 || | ||
2052 | perf_evsel__init_sc_tp_ptr_field(evsel, args)) { | ||
2053 | pr_err("Error during initialize raw_syscalls:sys_enter event\n"); | ||
2054 | goto out; | ||
2055 | } | ||
2056 | |||
2057 | evsel = perf_evlist__find_tracepoint_by_name(session->evlist, | ||
2058 | "raw_syscalls:sys_exit"); | ||
2059 | if (evsel == NULL) { | ||
2060 | pr_err("Data file does not have raw_syscalls:sys_exit event\n"); | ||
2057 | goto out; | 2061 | goto out; |
2058 | } | 2062 | } |
2059 | 2063 | ||
2060 | if (!perf_session__has_tp(session, "raw_syscalls:sys_exit")) { | 2064 | if (perf_evsel__init_syscall_tp(evsel, trace__sys_exit) < 0 || |
2061 | pr_err("Data file does not have raw_syscalls:sys_exit events\n"); | 2065 | perf_evsel__init_sc_tp_uint_field(evsel, ret)) { |
2066 | pr_err("Error during initialize raw_syscalls:sys_exit event\n"); | ||
2062 | goto out; | 2067 | goto out; |
2063 | } | 2068 | } |
2064 | 2069 | ||