From fcf65bf149afa91b875ffde4455967cb63ee0be9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 7 Aug 2012 09:58:03 -0300 Subject: perf evsel: Cache associated event_format We already lookup the associated event_format when reading the perf.data header, so that we can cache the tracepoint name in evsel->name, so do it a little further and save the event_format itself, so that we can avoid relookups in tools that need to access it. Change the tools to take the most obvious advantage, when they were using pevent_find_event directly. More work is needed for further removing the need of a pointer to pevent, such as when asking for event field values ("common_pid" and the other common fields and per event_format fields). This is something that was planned but only got actually done when Andrey Wagin needed to do this lookup at perf_tool->sample() time, when we don't have access to pevent (session->pevent) to use with pevent_find_event(). Cc: Andrey Wagin Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Signed-off-by: Arnaldo Carvalho de Melo Link: http://lkml.kernel.org/n/tip-txkvew2ckko0b594ae8fbnyk@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 29 ++++++----------------------- 1 file changed, 6 insertions(+), 23 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 1e60ab70b2b1..8dba4707b03f 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -262,14 +262,11 @@ static int perf_session__check_output_opt(struct perf_session *session) return 0; } -static void print_sample_start(struct pevent *pevent, - struct perf_sample *sample, +static void print_sample_start(struct perf_sample *sample, struct thread *thread, struct perf_evsel *evsel) { - int type; struct perf_event_attr *attr = &evsel->attr; - struct event_format *event; const char *evname = NULL; unsigned long secs; unsigned long usecs; @@ -307,20 +304,7 @@ static void print_sample_start(struct pevent *pevent, } if (PRINT_FIELD(EVNAME)) { - if (attr->type == PERF_TYPE_TRACEPOINT) { - /* - * XXX Do we really need this here? - * perf_evlist__set_tracepoint_names should have done - * this already - */ - type = trace_parse_common_type(pevent, - sample->raw_data); - event = pevent_find_event(pevent, type); - if (event) - evname = event->name; - } else - evname = perf_evsel__name(evsel); - + evname = perf_evsel__name(evsel); printf("%s: ", evname ? evname : "[unknown]"); } } @@ -416,7 +400,7 @@ static void print_sample_bts(union perf_event *event, } static void process_event(union perf_event *event __unused, - struct pevent *pevent, + struct pevent *pevent __unused, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, @@ -427,7 +411,7 @@ static void process_event(union perf_event *event __unused, if (output[attr->type].fields == 0) return; - print_sample_start(pevent, sample, thread, evsel); + print_sample_start(sample, thread, evsel); if (is_bts_event(attr)) { print_sample_bts(event, sample, evsel, machine, thread); @@ -435,9 +419,8 @@ static void process_event(union perf_event *event __unused, } if (PRINT_FIELD(TRACE)) - print_trace_event(pevent, sample->cpu, sample->raw_data, - sample->raw_size); - + event_format__print(evsel->tp_format, sample->cpu, + sample->raw_data, sample->raw_size); if (PRINT_FIELD(ADDR)) print_sample_addr(event, sample, machine, thread, attr); -- cgit v1.2.3 From 9782243353ec135327a80c76c63464e592949cd1 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Tue, 7 Aug 2012 23:50:21 -0300 Subject: perf script: Stop using pevent directly We can get all that is needed using just event_format, that is available via evsel->tp_format now. Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Mike Galbraith Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Stephane Eranian Link: http://lkml.kernel.org/n/tip-2hsr1686epa9f0vx4yg7z2zj@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 48 ++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 31 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 8dba4707b03f..6425612b4d99 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -28,11 +28,6 @@ static bool system_wide; static const char *cpu_list; static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); -struct perf_script { - struct perf_tool tool; - struct perf_session *session; -}; - enum perf_output_field { PERF_OUTPUT_COMM = 1U << 0, PERF_OUTPUT_TID = 1U << 1, @@ -399,11 +394,8 @@ static void print_sample_bts(union perf_event *event, printf("\n"); } -static void process_event(union perf_event *event __unused, - struct pevent *pevent __unused, - struct perf_sample *sample, - struct perf_evsel *evsel, - struct machine *machine, +static void process_event(union perf_event *event, struct perf_sample *sample, + struct perf_evsel *evsel, struct machine *machine, struct thread *thread) { struct perf_event_attr *attr = &evsel->attr; @@ -488,7 +480,6 @@ static int process_sample_event(struct perf_tool *tool __used, struct machine *machine) { struct addr_location al; - struct perf_script *scr = container_of(tool, struct perf_script, tool); struct thread *thread = machine__findnew_thread(machine, event->ip.tid); if (thread == NULL) { @@ -520,27 +511,24 @@ static int process_sample_event(struct perf_tool *tool __used, if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) return 0; - scripting_ops->process_event(event, scr->session->pevent, - sample, evsel, machine, thread); + scripting_ops->process_event(event, sample, evsel, machine, thread); evsel->hists.stats.total_period += sample->period; return 0; } -static struct perf_script perf_script = { - .tool = { - .sample = process_sample_event, - .mmap = perf_event__process_mmap, - .comm = perf_event__process_comm, - .exit = perf_event__process_task, - .fork = perf_event__process_task, - .attr = perf_event__process_attr, - .event_type = perf_event__process_event_type, - .tracing_data = perf_event__process_tracing_data, - .build_id = perf_event__process_build_id, - .ordered_samples = true, - .ordering_requires_timestamps = true, - }, +static struct perf_tool perf_script = { + .sample = process_sample_event, + .mmap = perf_event__process_mmap, + .comm = perf_event__process_comm, + .exit = perf_event__process_task, + .fork = perf_event__process_task, + .attr = perf_event__process_attr, + .event_type = perf_event__process_event_type, + .tracing_data = perf_event__process_tracing_data, + .build_id = perf_event__process_build_id, + .ordered_samples = true, + .ordering_requires_timestamps = true, }; extern volatile int session_done; @@ -556,7 +544,7 @@ static int __cmd_script(struct perf_session *session) signal(SIGINT, sig_handler); - ret = perf_session__process_events(session, &perf_script.tool); + ret = perf_session__process_events(session, &perf_script); if (debug_mode) pr_err("Misordered timestamps: %" PRIu64 "\n", nr_unordered); @@ -1339,12 +1327,10 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) setup_pager(); session = perf_session__new(input_name, O_RDONLY, 0, false, - &perf_script.tool); + &perf_script); if (session == NULL) return -ENOMEM; - perf_script.session = session; - if (cpu_list) { if (perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap)) return -1; -- cgit v1.2.3 From 73994dc158a24df4af77d0a76c9702f120f7a6ad Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Wed, 8 Aug 2012 17:57:52 +0800 Subject: perf script: Replace "struct thread" with "struct addr_location" as a parameter for "process_event()" Both perl and python script start processing events other than trace points, and it's useful to pass the resolved symbol and the dso info to the event handler in script for better analysis and statistics. Struct thread is already a member of struct addr_location, using addr_location will keep the thread info, while providing additional symbol and dso info if exist, so that the script itself doesn't need to bother to do the symbol resolving and dso searching work. Tested-by: David Ahern Signed-off-by: Feng Tang Acked-by: David Ahern Cc: Andi Kleen Cc: David Ahern Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Robert Richter Cc: Stephane Eranian Link: http://lkml.kernel.org/r/1344419875-21665-3-git-send-email-feng.tang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 6425612b4d99..30a9cb8c9927 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -396,9 +396,10 @@ static void print_sample_bts(union perf_event *event, static void process_event(union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, struct machine *machine, - struct thread *thread) + struct addr_location *al) { struct perf_event_attr *attr = &evsel->attr; + struct thread *thread = al->thread; if (output[attr->type].fields == 0) return; @@ -511,7 +512,7 @@ static int process_sample_event(struct perf_tool *tool __used, if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) return 0; - scripting_ops->process_event(event, sample, evsel, machine, thread); + scripting_ops->process_event(event, sample, evsel, machine, &al); evsel->hists.stats.total_period += sample->period; return 0; -- cgit v1.2.3 From 71ad0f5e4e361c8bca864c7d09d14b64af6bc2fc Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Tue, 7 Aug 2012 15:20:46 +0200 Subject: perf tools: Support for DWARF CFI unwinding on post processing This brings the support for DWARF cfi unwinding on perf post processing. Call frame informations are retrieved and then passed to libunwind that requests memory and register content from the applications. Adding unwind object to handle the user stack backtrace based on the user register values and user stack dump. The unwind object access the libunwind via remote interface and provides to it all the necessary data to unwind the stack. The unwind interface provides following function: unwind__get_entries And callback (specified in above function) to retrieve the backtrace entries: typedef int (*unwind_entry_cb_t)(struct unwind_entry *entry, void *arg); Signed-off-by: Jiri Olsa Original-patch-by: Frederic Weisbecker Cc: "Frank Ch. Eigler" Cc: Arun Sharma Cc: Benjamin Redelings Cc: Corey Ashford Cc: Cyrill Gorcunov Cc: Frank Ch. Eigler Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Masami Hiramatsu Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Robert Richter Cc: Stephane Eranian Cc: Tom Zanussi Cc: Ulrich Drepper Link: http://lkml.kernel.org/r/1344345647-11536-12-git-send-email-jolsa@redhat.com [ Replaced use of perf_session by usage of perf_evsel ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 30a9cb8c9927..2d6e3b226aad 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -380,7 +380,7 @@ static void print_sample_bts(union perf_event *event, printf(" "); else printf("\n"); - perf_event__print_ip(event, sample, machine, + perf_evsel__print_ip(evsel, event, sample, machine, PRINT_FIELD(SYM), PRINT_FIELD(DSO), PRINT_FIELD(SYMOFFSET)); } @@ -422,7 +422,7 @@ static void process_event(union perf_event *event, struct perf_sample *sample, printf(" "); else printf("\n"); - perf_event__print_ip(event, sample, machine, + perf_evsel__print_ip(evsel, event, sample, machine, PRINT_FIELD(SYM), PRINT_FIELD(DSO), PRINT_FIELD(SYMOFFSET)); } -- cgit v1.2.3 From d54b1a9e0eaca92cde678d19bd82b9594ed00450 Mon Sep 17 00:00:00 2001 From: David Ahern Date: Sun, 26 Aug 2012 12:24:46 -0600 Subject: perf script: Remove use of die/exit Allows perf to clean up properly on exit. Only exits left are exec failures which are appropriate and usage callbacks that list available options. Signed-off-by: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1346005487-62961-7-git-send-email-dsahern@gmail.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 60 +++++++++++++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 19 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 2d6e3b226aad..c350cfee3157 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1153,18 +1153,23 @@ static const struct option options[] = { OPT_END() }; -static bool have_cmd(int argc, const char **argv) +static int have_cmd(int argc, const char **argv) { char **__argv = malloc(sizeof(const char *) * argc); - if (!__argv) - die("malloc"); + if (!__argv) { + pr_err("malloc failed\n"); + return -1; + } + memcpy(__argv, argv, sizeof(const char *) * argc); argc = parse_options(argc, (const char **)__argv, record_options, NULL, PARSE_OPT_STOP_AT_NON_OPTION); free(__argv); - return argc != 0; + system_wide = (argc == 0); + + return 0; } int cmd_script(int argc, const char **argv, const char *prefix __used) @@ -1231,13 +1236,13 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) if (pipe(live_pipe) < 0) { perror("failed to create pipe"); - exit(-1); + return -1; } pid = fork(); if (pid < 0) { perror("failed to fork"); - exit(-1); + return -1; } if (!pid) { @@ -1249,13 +1254,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) if (is_top_script(argv[0])) { system_wide = true; } else if (!system_wide) { - system_wide = !have_cmd(argc - rep_args, - &argv[rep_args]); + if (have_cmd(argc - rep_args, &argv[rep_args]) != 0) { + err = -1; + goto out; + } } __argv = malloc((argc + 6) * sizeof(const char *)); - if (!__argv) - die("malloc"); + if (!__argv) { + pr_err("malloc failed\n"); + err = -ENOMEM; + goto out; + } __argv[j++] = "/bin/sh"; __argv[j++] = rec_script_path; @@ -1277,8 +1287,12 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) close(live_pipe[1]); __argv = malloc((argc + 4) * sizeof(const char *)); - if (!__argv) - die("malloc"); + if (!__argv) { + pr_err("malloc failed\n"); + err = -ENOMEM; + goto out; + } + j = 0; __argv[j++] = "/bin/sh"; __argv[j++] = rep_script_path; @@ -1303,12 +1317,20 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) if (!rec_script_path) system_wide = false; - else if (!system_wide) - system_wide = !have_cmd(argc - 1, &argv[1]); + else if (!system_wide) { + if (have_cmd(argc - 1, &argv[1]) != 0) { + err = -1; + goto out; + } + } __argv = malloc((argc + 2) * sizeof(const char *)); - if (!__argv) - die("malloc"); + if (!__argv) { + pr_err("malloc failed\n"); + err = -ENOMEM; + goto out; + } + __argv[j++] = "/bin/sh"; __argv[j++] = script_path; if (system_wide) @@ -1357,18 +1379,18 @@ int cmd_script(int argc, const char **argv, const char *prefix __used) input = open(session->filename, O_RDONLY); /* input_name */ if (input < 0) { perror("failed to open file"); - exit(-1); + return -1; } err = fstat(input, &perf_stat); if (err < 0) { perror("failed to stat file"); - exit(-1); + return -1; } if (!perf_stat.st_size) { fprintf(stderr, "zero-sized file, nothing to do!\n"); - exit(0); + return 0; } scripting_ops = script_spec__lookup(generate_script_lang); -- cgit v1.2.3 From 1d037ca1648b775277fc96401ec2aa233724906c Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Tue, 11 Sep 2012 01:15:03 +0300 Subject: perf tools: Use __maybe_used for unused variables perf defines both __used and __unused variables to use for marking unused variables. The variable __used is defined to __attribute__((__unused__)), which contradicts the kernel definition to __attribute__((__used__)) for new gcc versions. On Android, __used is also defined in system headers and this leads to warnings like: warning: '__used__' attribute ignored __unused is not defined in the kernel and is not a standard definition. If __unused is included everywhere instead of __used, this leads to conflicts with glibc headers, since glibc has a variables with this name in its headers. The best approach is to use __maybe_unused, the definition used in the kernel for __attribute__((unused)). In this way there is only one definition in perf sources (instead of 2 definitions that point to the same thing: __used and __unused) and it works on both Linux and Android. This patch simply replaces all instances of __used and __unused with __maybe_unused. Signed-off-by: Irina Tirdea Acked-by: Pekka Enberg Cc: David Ahern Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1347315303-29906-7-git-send-email-irina.tirdea@intel.com [ committer note: fixed up conflict with a116e05 in builtin-sched.c ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index c350cfee3157..6d98a83d5a60 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -430,9 +430,9 @@ static void process_event(union perf_event *event, struct perf_sample *sample, printf("\n"); } -static int default_start_script(const char *script __unused, - int argc __unused, - const char **argv __unused) +static int default_start_script(const char *script __maybe_unused, + int argc __maybe_unused, + const char **argv __maybe_unused) { return 0; } @@ -442,8 +442,8 @@ static int default_stop_script(void) return 0; } -static int default_generate_script(struct pevent *pevent __unused, - const char *outfile __unused) +static int default_generate_script(struct pevent *pevent __maybe_unused, + const char *outfile __maybe_unused) { return 0; } @@ -474,7 +474,7 @@ static int cleanup_scripting(void) static const char *input_name; -static int process_sample_event(struct perf_tool *tool __used, +static int process_sample_event(struct perf_tool *tool __maybe_unused, union perf_event *event, struct perf_sample *sample, struct perf_evsel *evsel, @@ -534,7 +534,7 @@ static struct perf_tool perf_script = { extern volatile int session_done; -static void sig_handler(int sig __unused) +static void sig_handler(int sig __maybe_unused) { session_done = 1; } @@ -644,8 +644,8 @@ static void list_available_languages(void) fprintf(stderr, "\n"); } -static int parse_scriptname(const struct option *opt __used, - const char *str, int unset __used) +static int parse_scriptname(const struct option *opt __maybe_unused, + const char *str, int unset __maybe_unused) { char spec[PATH_MAX]; const char *script, *ext; @@ -690,8 +690,8 @@ static int parse_scriptname(const struct option *opt __used, return 0; } -static int parse_output_fields(const struct option *opt __used, - const char *arg, int unset __used) +static int parse_output_fields(const struct option *opt __maybe_unused, + const char *arg, int unset __maybe_unused) { char *tok; int i, imax = sizeof(all_output_options) / sizeof(struct output_option); @@ -982,8 +982,9 @@ static char *get_script_root(struct dirent *script_dirent, const char *suffix) return script_root; } -static int list_available_scripts(const struct option *opt __used, - const char *s __used, int unset __used) +static int list_available_scripts(const struct option *opt __maybe_unused, + const char *s __maybe_unused, + int unset __maybe_unused) { struct dirent *script_next, *lang_next, script_dirent, lang_dirent; char scripts_path[MAXPATHLEN]; @@ -1172,7 +1173,7 @@ static int have_cmd(int argc, const char **argv) return 0; } -int cmd_script(int argc, const char **argv, const char *prefix __used) +int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused) { char *rec_script_path = NULL; char *rep_script_path = NULL; -- cgit v1.2.3 From 36385be55da10b3271407c45c3a62d9af3db666e Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Fri, 7 Sep 2012 16:42:24 +0800 Subject: perf scripts: Add --symbols option to handle specific symbols Since perf script no longer only handle the trace points, we can add the symbol filter option so that scripts can handle specified samples. Signed-off-by: Feng Tang Cc: Andi Kleen Cc: David Ahern Cc: Ingo Molnar Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1347007349-3102-3-git-send-email-feng.tang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 6d98a83d5a60..76577e67c3b3 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -14,6 +14,7 @@ #include "util/util.h" #include "util/evlist.h" #include "util/evsel.h" +#include "util/sort.h" #include static char const *script_name; @@ -1143,6 +1144,8 @@ static const struct option options[] = { parse_output_fields), OPT_BOOLEAN('a', "all-cpus", &system_wide, "system-wide collection from all CPUs"), + OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", + "only consider these symbols"), OPT_STRING('C', "cpu", &cpu_list, "cpu", "list of cpus to profile"), OPT_STRING('c', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", "only display events for these comms"), -- cgit v1.2.3 From e5f3705e62b03251797a5173024184bfc223599d Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Fri, 7 Sep 2012 16:42:26 +0800 Subject: perf scripts: Export a find_scripts() function So that other perf commands/browser has a way to dig out the available scripts info in system, this is a preparation for the script browser. Signed-off-by: Feng Tang Cc: Andi Kleen Cc: David Ahern Cc: Ingo Molnar Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1347007349-3102-5-git-send-email-feng.tang@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-script.c | 55 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'tools/perf/builtin-script.c') diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 76577e67c3b3..1be843aa1546 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1032,6 +1032,61 @@ static int list_available_scripts(const struct option *opt __maybe_unused, exit(0); } +/* + * Return -1 if none is found, otherwise the actual scripts number. + * + * Currently the only user of this function is the script browser, which + * will list all statically runnable scripts, select one, execute it and + * show the output in a perf browser. + */ +int find_scripts(char **scripts_array, char **scripts_path_array) +{ + struct dirent *script_next, *lang_next, script_dirent, lang_dirent; + char scripts_path[MAXPATHLEN]; + DIR *scripts_dir, *lang_dir; + char lang_path[MAXPATHLEN]; + char *temp; + int i = 0; + + snprintf(scripts_path, MAXPATHLEN, "%s/scripts", perf_exec_path()); + + scripts_dir = opendir(scripts_path); + if (!scripts_dir) + return -1; + + for_each_lang(scripts_path, scripts_dir, lang_dirent, lang_next) { + snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, + lang_dirent.d_name); +#ifdef NO_LIBPERL + if (strstr(lang_path, "perl")) + continue; +#endif +#ifdef NO_LIBPYTHON + if (strstr(lang_path, "python")) + continue; +#endif + + lang_dir = opendir(lang_path); + if (!lang_dir) + continue; + + for_each_script(lang_path, lang_dir, script_dirent, script_next) { + /* Skip those real time scripts: xxxtop.p[yl] */ + if (strstr(script_dirent.d_name, "top.")) + continue; + sprintf(scripts_path_array[i], "%s/%s", lang_path, + script_dirent.d_name); + temp = strchr(script_dirent.d_name, '.'); + snprintf(scripts_array[i], + (temp - script_dirent.d_name) + 1, + "%s", script_dirent.d_name); + i++; + } + } + + return i; +} + static char *get_script_path(const char *script_root, const char *suffix) { struct dirent *script_next, *lang_next, script_dirent, lang_dirent; -- cgit v1.2.3