diff options
Diffstat (limited to 'tools/perf/util/session.c')
| -rw-r--r-- | tools/perf/util/session.c | 73 |
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 | ||
| 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; |
| @@ -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 | ||
| 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 | |||
| 126 | void perf_session__delete(struct perf_session *self) | 156 | void 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 | ||
| 167 | void 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 | |||
| 134 | static bool symbol__match_parent_regex(struct symbol *sym) | 178 | static 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; | ||
| 827 | out_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); |
| 846 | out_err: | 873 | |
| 847 | return err; | 874 | return err; |
| 848 | } | 875 | } |
| 849 | 876 | ||
