aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2014-01-16 04:39:47 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-01-16 14:29:02 -0500
commite53b00d382f4d8f55bcae301f49863c469fdff65 (patch)
tree7dab9ad69098d2c33aba7f065fc6f540e4fa7b1c /tools
parent981d05adf2e2acc328abb929a6ed3536c0d41c5f (diff)
perf probe: Release all dynamically allocated parameters
To fix a memory leak, release all dynamically allocated options/parameters in params data structure. This also introduces/exports some init/clear routines. Reported-by: David Ahern <dsahern@gmail.com> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: "David A. Long" <dave.long@linaro.org> Cc: "Steven Rostedt (Red Hat)" <rostedt@goodmis.org> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Oleg Nesterov <oleg@redhat.com> Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com> Cc: yrl.pp-manager.tt@hitachi.com Link: http://lkml.kernel.org/r/20140116093947.24403.80118.stgit@kbuild-fedora.novalocal Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/builtin-probe.c48
-rw-r--r--tools/perf/util/probe-event.c22
-rw-r--r--tools/perf/util/probe-event.h6
3 files changed, 71 insertions, 5 deletions
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c
index 43ff33d0007b..78948882e3de 100644
--- a/tools/perf/builtin-probe.c
+++ b/tools/perf/builtin-probe.c
@@ -59,7 +59,7 @@ static struct {
59 struct perf_probe_event events[MAX_PROBES]; 59 struct perf_probe_event events[MAX_PROBES];
60 struct strlist *dellist; 60 struct strlist *dellist;
61 struct line_range line_range; 61 struct line_range line_range;
62 const char *target; 62 char *target;
63 int max_probe_points; 63 int max_probe_points;
64 struct strfilter *filter; 64 struct strfilter *filter;
65} params; 65} params;
@@ -98,7 +98,10 @@ static int set_target(const char *ptr)
98 * short module name. 98 * short module name.
99 */ 99 */
100 if (!params.target && ptr && *ptr == '/') { 100 if (!params.target && ptr && *ptr == '/') {
101 params.target = ptr; 101 params.target = strdup(ptr);
102 if (!params.target)
103 return -ENOMEM;
104
102 found = 1; 105 found = 1;
103 buf = ptr + (strlen(ptr) - 3); 106 buf = ptr + (strlen(ptr) - 3);
104 107
@@ -116,6 +119,9 @@ static int parse_probe_event_argv(int argc, const char **argv)
116 char *buf; 119 char *buf;
117 120
118 found_target = set_target(argv[0]); 121 found_target = set_target(argv[0]);
122 if (found_target < 0)
123 return found_target;
124
119 if (found_target && argc == 1) 125 if (found_target && argc == 1)
120 return 0; 126 return 0;
121 127
@@ -217,7 +223,6 @@ static int opt_show_lines(const struct option *opt __maybe_unused,
217 223
218 params.show_lines = true; 224 params.show_lines = true;
219 ret = parse_line_range_desc(str, &params.line_range); 225 ret = parse_line_range_desc(str, &params.line_range);
220 INIT_LIST_HEAD(&params.line_range.line_list);
221 226
222 return ret; 227 return ret;
223} 228}
@@ -263,7 +268,28 @@ static int opt_set_filter(const struct option *opt __maybe_unused,
263 return 0; 268 return 0;
264} 269}
265 270
266int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused) 271static void init_params(void)
272{
273 line_range__init(&params.line_range);
274}
275
276static void cleanup_params(void)
277{
278 int i;
279
280 for (i = 0; i < params.nevents; i++)
281 clear_perf_probe_event(params.events + i);
282 if (params.dellist)
283 strlist__delete(params.dellist);
284 line_range__clear(&params.line_range);
285 free(params.target);
286 if (params.filter)
287 strfilter__delete(params.filter);
288 memset(&params, 0, sizeof(params));
289}
290
291static int
292__cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
267{ 293{
268 const char * const probe_usage[] = { 294 const char * const probe_usage[] = {
269 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]", 295 "perf probe [<options>] 'PROBEDEF' ['PROBEDEF' ...]",
@@ -417,6 +443,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
417 ret = show_available_funcs(params.target, params.filter, 443 ret = show_available_funcs(params.target, params.filter,
418 params.uprobes); 444 params.uprobes);
419 strfilter__delete(params.filter); 445 strfilter__delete(params.filter);
446 params.filter = NULL;
420 if (ret < 0) 447 if (ret < 0)
421 pr_err(" Error: Failed to show functions." 448 pr_err(" Error: Failed to show functions."
422 " (%d)\n", ret); 449 " (%d)\n", ret);
@@ -456,6 +483,7 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
456 params.filter, 483 params.filter,
457 params.show_ext_vars); 484 params.show_ext_vars);
458 strfilter__delete(params.filter); 485 strfilter__delete(params.filter);
486 params.filter = NULL;
459 if (ret < 0) 487 if (ret < 0)
460 pr_err(" Error: Failed to show vars. (%d)\n", ret); 488 pr_err(" Error: Failed to show vars. (%d)\n", ret);
461 return ret; 489 return ret;
@@ -464,7 +492,6 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
464 492
465 if (params.dellist) { 493 if (params.dellist) {
466 ret = del_perf_probe_events(params.dellist); 494 ret = del_perf_probe_events(params.dellist);
467 strlist__delete(params.dellist);
468 if (ret < 0) { 495 if (ret < 0) {
469 pr_err(" Error: Failed to delete events. (%d)\n", ret); 496 pr_err(" Error: Failed to delete events. (%d)\n", ret);
470 return ret; 497 return ret;
@@ -483,3 +510,14 @@ int cmd_probe(int argc, const char **argv, const char *prefix __maybe_unused)
483 } 510 }
484 return 0; 511 return 0;
485} 512}
513
514int cmd_probe(int argc, const char **argv, const char *prefix)
515{
516 int ret;
517
518 init_params();
519 ret = __cmd_probe(argc, argv, prefix);
520 cleanup_params();
521
522 return ret;
523}
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 579b655c0f93..c68711c50f47 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -794,6 +794,28 @@ int show_available_vars(struct perf_probe_event *pevs __maybe_unused,
794} 794}
795#endif 795#endif
796 796
797void line_range__clear(struct line_range *lr)
798{
799 struct line_node *ln;
800
801 free(lr->function);
802 free(lr->file);
803 free(lr->path);
804 free(lr->comp_dir);
805 while (!list_empty(&lr->line_list)) {
806 ln = list_first_entry(&lr->line_list, struct line_node, list);
807 list_del(&ln->list);
808 free(ln);
809 }
810 memset(lr, 0, sizeof(*lr));
811}
812
813void line_range__init(struct line_range *lr)
814{
815 memset(lr, 0, sizeof(*lr));
816 INIT_LIST_HEAD(&lr->line_list);
817}
818
797static int parse_line_num(char **ptr, int *val, const char *what) 819static int parse_line_num(char **ptr, int *val, const char *what)
798{ 820{
799 const char *start = *ptr; 821 const char *start = *ptr;
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index d481c46e0796..fcaf7273e85a 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -120,6 +120,12 @@ extern void clear_perf_probe_event(struct perf_probe_event *pev);
120/* Command string to line-range */ 120/* Command string to line-range */
121extern int parse_line_range_desc(const char *cmd, struct line_range *lr); 121extern int parse_line_range_desc(const char *cmd, struct line_range *lr);
122 122
123/* Release line range members */
124extern void line_range__clear(struct line_range *lr);
125
126/* Initialize line range */
127extern void line_range__init(struct line_range *lr);
128
123/* Internal use: Return kernel/module path */ 129/* Internal use: Return kernel/module path */
124extern const char *kernel_get_module_path(const char *module); 130extern const char *kernel_get_module_path(const char *module);
125 131