diff options
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r-- | tools/perf/util/session.c | 62 |
1 files changed, 39 insertions, 23 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index c422cd676313..fa9d652c2dc3 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -27,8 +27,10 @@ static int perf_session__open(struct perf_session *self, bool force) | |||
27 | 27 | ||
28 | self->fd = open(self->filename, O_RDONLY); | 28 | self->fd = open(self->filename, O_RDONLY); |
29 | if (self->fd < 0) { | 29 | if (self->fd < 0) { |
30 | pr_err("failed to open file: %s", self->filename); | 30 | int err = errno; |
31 | if (!strcmp(self->filename, "perf.data")) | 31 | |
32 | pr_err("failed to open %s: %s", self->filename, strerror(err)); | ||
33 | if (err == ENOENT && !strcmp(self->filename, "perf.data")) | ||
32 | pr_err(" (try 'perf record' first)"); | 34 | pr_err(" (try 'perf record' first)"); |
33 | pr_err("\n"); | 35 | pr_err("\n"); |
34 | return -errno; | 36 | return -errno; |
@@ -77,6 +79,12 @@ int perf_session__create_kernel_maps(struct perf_session *self) | |||
77 | return ret; | 79 | return ret; |
78 | } | 80 | } |
79 | 81 | ||
82 | static void perf_session__destroy_kernel_maps(struct perf_session *self) | ||
83 | { | ||
84 | machine__destroy_kernel_maps(&self->host_machine); | ||
85 | machines__destroy_guest_kernel_maps(&self->machines); | ||
86 | } | ||
87 | |||
80 | struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) | 88 | struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) |
81 | { | 89 | { |
82 | size_t len = filename ? strlen(filename) + 1 : 0; | 90 | size_t len = filename ? strlen(filename) + 1 : 0; |
@@ -94,8 +102,6 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc | |||
94 | self->hists_tree = RB_ROOT; | 102 | self->hists_tree = RB_ROOT; |
95 | self->last_match = NULL; | 103 | self->last_match = NULL; |
96 | self->mmap_window = 32; | 104 | self->mmap_window = 32; |
97 | self->cwd = NULL; | ||
98 | self->cwdlen = 0; | ||
99 | self->machines = RB_ROOT; | 105 | self->machines = RB_ROOT; |
100 | self->repipe = repipe; | 106 | self->repipe = repipe; |
101 | INIT_LIST_HEAD(&self->ordered_samples.samples_head); | 107 | INIT_LIST_HEAD(&self->ordered_samples.samples_head); |
@@ -124,16 +130,43 @@ out_delete: | |||
124 | return NULL; | 130 | return NULL; |
125 | } | 131 | } |
126 | 132 | ||
133 | static void perf_session__delete_dead_threads(struct perf_session *self) | ||
134 | { | ||
135 | struct thread *n, *t; | ||
136 | |||
137 | list_for_each_entry_safe(t, n, &self->dead_threads, node) { | ||
138 | list_del(&t->node); | ||
139 | thread__delete(t); | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static void perf_session__delete_threads(struct perf_session *self) | ||
144 | { | ||
145 | struct rb_node *nd = rb_first(&self->threads); | ||
146 | |||
147 | while (nd) { | ||
148 | struct thread *t = rb_entry(nd, struct thread, rb_node); | ||
149 | |||
150 | rb_erase(&t->rb_node, &self->threads); | ||
151 | nd = rb_next(nd); | ||
152 | thread__delete(t); | ||
153 | } | ||
154 | } | ||
155 | |||
127 | void perf_session__delete(struct perf_session *self) | 156 | void perf_session__delete(struct perf_session *self) |
128 | { | 157 | { |
129 | perf_header__exit(&self->header); | 158 | perf_header__exit(&self->header); |
159 | perf_session__destroy_kernel_maps(self); | ||
160 | perf_session__delete_dead_threads(self); | ||
161 | perf_session__delete_threads(self); | ||
162 | machine__exit(&self->host_machine); | ||
130 | close(self->fd); | 163 | close(self->fd); |
131 | free(self->cwd); | ||
132 | free(self); | 164 | free(self); |
133 | } | 165 | } |
134 | 166 | ||
135 | void perf_session__remove_thread(struct perf_session *self, struct thread *th) | 167 | void perf_session__remove_thread(struct perf_session *self, struct thread *th) |
136 | { | 168 | { |
169 | self->last_match = NULL; | ||
137 | rb_erase(&th->rb_node, &self->threads); | 170 | rb_erase(&th->rb_node, &self->threads); |
138 | /* | 171 | /* |
139 | * We may have references to this thread, for instance in some hist_entry | 172 | * We may have references to this thread, for instance in some hist_entry |
@@ -830,23 +863,6 @@ int perf_session__process_events(struct perf_session *self, | |||
830 | if (perf_session__register_idle_thread(self) == NULL) | 863 | if (perf_session__register_idle_thread(self) == NULL) |
831 | return -ENOMEM; | 864 | return -ENOMEM; |
832 | 865 | ||
833 | if (!symbol_conf.full_paths) { | ||
834 | char bf[PATH_MAX]; | ||
835 | |||
836 | if (getcwd(bf, sizeof(bf)) == NULL) { | ||
837 | err = -errno; | ||
838 | out_getcwd_err: | ||
839 | pr_err("failed to get the current directory\n"); | ||
840 | goto out_err; | ||
841 | } | ||
842 | self->cwd = strdup(bf); | ||
843 | if (self->cwd == NULL) { | ||
844 | err = -ENOMEM; | ||
845 | goto out_getcwd_err; | ||
846 | } | ||
847 | self->cwdlen = strlen(self->cwd); | ||
848 | } | ||
849 | |||
850 | if (!self->fd_pipe) | 866 | if (!self->fd_pipe) |
851 | err = __perf_session__process_events(self, | 867 | err = __perf_session__process_events(self, |
852 | self->header.data_offset, | 868 | self->header.data_offset, |
@@ -854,7 +870,7 @@ out_getcwd_err: | |||
854 | self->size, ops); | 870 | self->size, ops); |
855 | else | 871 | else |
856 | err = __perf_session__process_pipe_events(self, ops); | 872 | err = __perf_session__process_pipe_events(self, ops); |
857 | out_err: | 873 | |
858 | return err; | 874 | return err; |
859 | } | 875 | } |
860 | 876 | ||