diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-07-30 17:31:28 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2010-07-30 17:31:28 -0400 |
commit | d65a458b348cd458413b3cfec66e43ebd0367646 (patch) | |
tree | 984d730e5a81e4ae7c04b9f664d8a1cacdd0c6e6 /tools | |
parent | 591765fdaf7ea1888157f342b67b0461f2e5ed9b (diff) |
perf tools: Release session and symbol resources on exit
So that we reduce the noise when looking for leaks using tools such as
valgrind.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-record.c | 5 | ||||
-rw-r--r-- | tools/perf/util/event.c | 5 | ||||
-rw-r--r-- | tools/perf/util/map.c | 26 | ||||
-rw-r--r-- | tools/perf/util/map.h | 1 | ||||
-rw-r--r-- | tools/perf/util/session.c | 26 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 9 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 1 |
7 files changed, 70 insertions, 3 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 5ae0d93d8597..ff77b805de71 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -440,6 +440,7 @@ static void atexit_header(void) | |||
440 | process_buildids(); | 440 | process_buildids(); |
441 | perf_header__write(&session->header, output, true); | 441 | perf_header__write(&session->header, output, true); |
442 | perf_session__delete(session); | 442 | perf_session__delete(session); |
443 | symbol__exit(); | ||
443 | } | 444 | } |
444 | } | 445 | } |
445 | 446 | ||
@@ -871,7 +872,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
871 | } else { | 872 | } else { |
872 | all_tids=malloc(sizeof(pid_t)); | 873 | all_tids=malloc(sizeof(pid_t)); |
873 | if (!all_tids) | 874 | if (!all_tids) |
874 | return -ENOMEM; | 875 | goto out_symbol_exit; |
875 | 876 | ||
876 | all_tids[0] = target_tid; | 877 | all_tids[0] = target_tid; |
877 | thread_num = 1; | 878 | thread_num = 1; |
@@ -918,5 +919,7 @@ out_free_fd: | |||
918 | } | 919 | } |
919 | free(all_tids); | 920 | free(all_tids); |
920 | all_tids = NULL; | 921 | all_tids = NULL; |
922 | out_symbol_exit: | ||
923 | symbol__exit(); | ||
921 | return err; | 924 | return err; |
922 | } | 925 | } |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 8151d23664c7..6b0db5577929 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -515,12 +515,13 @@ int event__process_mmap(event_t *self, struct perf_session *session) | |||
515 | if (machine == NULL) | 515 | if (machine == NULL) |
516 | goto out_problem; | 516 | goto out_problem; |
517 | thread = perf_session__findnew(session, self->mmap.pid); | 517 | thread = perf_session__findnew(session, self->mmap.pid); |
518 | if (thread == NULL) | ||
519 | goto out_problem; | ||
518 | map = map__new(&machine->user_dsos, self->mmap.start, | 520 | map = map__new(&machine->user_dsos, self->mmap.start, |
519 | self->mmap.len, self->mmap.pgoff, | 521 | self->mmap.len, self->mmap.pgoff, |
520 | self->mmap.pid, self->mmap.filename, | 522 | self->mmap.pid, self->mmap.filename, |
521 | MAP__FUNCTION); | 523 | MAP__FUNCTION); |
522 | 524 | if (map == NULL) | |
523 | if (thread == NULL || map == NULL) | ||
524 | goto out_problem; | 525 | goto out_problem; |
525 | 526 | ||
526 | thread__insert_map(thread, map); | 527 | thread__insert_map(thread, map); |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 2ddbae319de5..15d6a6dd50c5 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -539,6 +539,32 @@ int machine__init(struct machine *self, const char *root_dir, pid_t pid) | |||
539 | return self->root_dir == NULL ? -ENOMEM : 0; | 539 | return self->root_dir == NULL ? -ENOMEM : 0; |
540 | } | 540 | } |
541 | 541 | ||
542 | static void dsos__delete(struct list_head *self) | ||
543 | { | ||
544 | struct dso *pos, *n; | ||
545 | |||
546 | list_for_each_entry_safe(pos, n, self, node) { | ||
547 | list_del(&pos->node); | ||
548 | dso__delete(pos); | ||
549 | } | ||
550 | } | ||
551 | |||
552 | void machine__exit(struct machine *self) | ||
553 | { | ||
554 | struct kmap *kmap = map__kmap(self->vmlinux_maps[MAP__FUNCTION]); | ||
555 | |||
556 | if (kmap->ref_reloc_sym) { | ||
557 | free((char *)kmap->ref_reloc_sym->name); | ||
558 | free(kmap->ref_reloc_sym); | ||
559 | } | ||
560 | |||
561 | map_groups__exit(&self->kmaps); | ||
562 | dsos__delete(&self->user_dsos); | ||
563 | dsos__delete(&self->kernel_dsos); | ||
564 | free(self->root_dir); | ||
565 | self->root_dir = NULL; | ||
566 | } | ||
567 | |||
542 | struct machine *machines__add(struct rb_root *self, pid_t pid, | 568 | struct machine *machines__add(struct rb_root *self, pid_t pid, |
543 | const char *root_dir) | 569 | const char *root_dir) |
544 | { | 570 | { |
diff --git a/tools/perf/util/map.h b/tools/perf/util/map.h index 20eba420ddae..0e0984e86fce 100644 --- a/tools/perf/util/map.h +++ b/tools/perf/util/map.h | |||
@@ -143,6 +143,7 @@ struct machine *machines__find(struct rb_root *self, pid_t pid); | |||
143 | struct machine *machines__findnew(struct rb_root *self, pid_t pid); | 143 | struct machine *machines__findnew(struct rb_root *self, pid_t pid); |
144 | char *machine__mmap_name(struct machine *self, char *bf, size_t size); | 144 | char *machine__mmap_name(struct machine *self, char *bf, size_t size); |
145 | int machine__init(struct machine *self, const char *root_dir, pid_t pid); | 145 | int machine__init(struct machine *self, const char *root_dir, pid_t pid); |
146 | void machine__exit(struct machine *self); | ||
146 | 147 | ||
147 | /* | 148 | /* |
148 | * Default guest kernel is defined by parameter --guestkallsyms | 149 | * Default guest kernel is defined by parameter --guestkallsyms |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 8cbea122e349..04a3b3db9e90 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -124,9 +124,35 @@ out_delete: | |||
124 | return NULL; | 124 | return NULL; |
125 | } | 125 | } |
126 | 126 | ||
127 | static void perf_session__delete_dead_threads(struct perf_session *self) | ||
128 | { | ||
129 | struct thread *n, *t; | ||
130 | |||
131 | list_for_each_entry_safe(t, n, &self->dead_threads, node) { | ||
132 | list_del(&t->node); | ||
133 | thread__delete(t); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | static void perf_session__delete_threads(struct perf_session *self) | ||
138 | { | ||
139 | struct rb_node *nd = rb_first(&self->threads); | ||
140 | |||
141 | while (nd) { | ||
142 | struct thread *t = rb_entry(nd, struct thread, rb_node); | ||
143 | |||
144 | rb_erase(&t->rb_node, &self->threads); | ||
145 | nd = rb_next(nd); | ||
146 | thread__delete(t); | ||
147 | } | ||
148 | } | ||
149 | |||
127 | void perf_session__delete(struct perf_session *self) | 150 | void perf_session__delete(struct perf_session *self) |
128 | { | 151 | { |
129 | perf_header__exit(&self->header); | 152 | perf_header__exit(&self->header); |
153 | perf_session__delete_dead_threads(self); | ||
154 | perf_session__delete_threads(self); | ||
155 | machine__exit(&self->host_machine); | ||
130 | close(self->fd); | 156 | close(self->fd); |
131 | free(self); | 157 | free(self); |
132 | } | 158 | } |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index d99497ec52aa..94cdf68440cd 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -2245,6 +2245,15 @@ out_free_comm_list: | |||
2245 | return -1; | 2245 | return -1; |
2246 | } | 2246 | } |
2247 | 2247 | ||
2248 | void symbol__exit(void) | ||
2249 | { | ||
2250 | strlist__delete(symbol_conf.sym_list); | ||
2251 | strlist__delete(symbol_conf.dso_list); | ||
2252 | strlist__delete(symbol_conf.comm_list); | ||
2253 | vmlinux_path__exit(); | ||
2254 | symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL; | ||
2255 | } | ||
2256 | |||
2248 | int machines__create_kernel_maps(struct rb_root *self, pid_t pid) | 2257 | int machines__create_kernel_maps(struct rb_root *self, pid_t pid) |
2249 | { | 2258 | { |
2250 | struct machine *machine = machines__findnew(self, pid); | 2259 | struct machine *machine = machines__findnew(self, pid); |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index f29f73c20809..33d53ce28958 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -219,6 +219,7 @@ int machines__create_kernel_maps(struct rb_root *self, pid_t pid); | |||
219 | int machines__create_guest_kernel_maps(struct rb_root *self); | 219 | int machines__create_guest_kernel_maps(struct rb_root *self); |
220 | 220 | ||
221 | int symbol__init(void); | 221 | int symbol__init(void); |
222 | void symbol__exit(void); | ||
222 | bool symbol_type__is_a(char symbol_type, enum map_type map_type); | 223 | bool symbol_type__is_a(char symbol_type, enum map_type map_type); |
223 | 224 | ||
224 | size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp); | 225 | size_t machine__fprintf_vmlinux_path(struct machine *self, FILE *fp); |