aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c73
1 files changed, 50 insertions, 23 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 8f83a1835766..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
82static 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
80struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) 88struct 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;
@@ -90,11 +98,10 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
90 98
91 memcpy(self->filename, filename, len); 99 memcpy(self->filename, filename, len);
92 self->threads = RB_ROOT; 100 self->threads = RB_ROOT;
101 INIT_LIST_HEAD(&self->dead_threads);
93 self->hists_tree = RB_ROOT; 102 self->hists_tree = RB_ROOT;
94 self->last_match = NULL; 103 self->last_match = NULL;
95 self->mmap_window = 32; 104 self->mmap_window = 32;
96 self->cwd = NULL;
97 self->cwdlen = 0;
98 self->machines = RB_ROOT; 105 self->machines = RB_ROOT;
99 self->repipe = repipe; 106 self->repipe = repipe;
100 INIT_LIST_HEAD(&self->ordered_samples.samples_head); 107 INIT_LIST_HEAD(&self->ordered_samples.samples_head);
@@ -123,14 +130,51 @@ out_delete:
123 return NULL; 130 return NULL;
124} 131}
125 132
133static 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
143static 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
126void perf_session__delete(struct perf_session *self) 156void perf_session__delete(struct perf_session *self)
127{ 157{
128 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);
129 close(self->fd); 163 close(self->fd);
130 free(self->cwd);
131 free(self); 164 free(self);
132} 165}
133 166
167void perf_session__remove_thread(struct perf_session *self, struct thread *th)
168{
169 self->last_match = NULL;
170 rb_erase(&th->rb_node, &self->threads);
171 /*
172 * We may have references to this thread, for instance in some hist_entry
173 * instances, so just move them to a separate list.
174 */
175 list_add_tail(&th->node, &self->dead_threads);
176}
177
134static bool symbol__match_parent_regex(struct symbol *sym) 178static bool symbol__match_parent_regex(struct symbol *sym)
135{ 179{
136 if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0)) 180 if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0))
@@ -819,23 +863,6 @@ int perf_session__process_events(struct perf_session *self,
819 if (perf_session__register_idle_thread(self) == NULL) 863 if (perf_session__register_idle_thread(self) == NULL)
820 return -ENOMEM; 864 return -ENOMEM;
821 865
822 if (!symbol_conf.full_paths) {
823 char bf[PATH_MAX];
824
825 if (getcwd(bf, sizeof(bf)) == NULL) {
826 err = -errno;
827out_getcwd_err:
828 pr_err("failed to get the current directory\n");
829 goto out_err;
830 }
831 self->cwd = strdup(bf);
832 if (self->cwd == NULL) {
833 err = -ENOMEM;
834 goto out_getcwd_err;
835 }
836 self->cwdlen = strlen(self->cwd);
837 }
838
839 if (!self->fd_pipe) 866 if (!self->fd_pipe)
840 err = __perf_session__process_events(self, 867 err = __perf_session__process_events(self,
841 self->header.data_offset, 868 self->header.data_offset,
@@ -843,7 +870,7 @@ out_getcwd_err:
843 self->size, ops); 870 self->size, ops);
844 else 871 else
845 err = __perf_session__process_pipe_events(self, ops); 872 err = __perf_session__process_pipe_events(self, ops);
846out_err: 873
847 return err; 874 return err;
848} 875}
849 876