From 9a2936878a198553a17d21d1e843aa574ad9fa38 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 7 Sep 2012 10:55:53 +0900 Subject: [PATCH 01/13] perf tools: Ignore compiled python binaries It prevents mindless git add from adding those files. Signed-off-by: Namhyung Kim Cc: Ingo Molnar Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1346982953-30824-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/perf/.gitignore b/tools/perf/.gitignore index 26b823b61aa1..8f8fbc227a46 100644 --- a/tools/perf/.gitignore +++ b/tools/perf/.gitignore @@ -21,3 +21,5 @@ config.mak config.mak.autogen *-bison.* *-flex.* +*.pyc +*.pyo From 245c5a18433090da0e1a799bdb0faa78552b5992 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 7 Sep 2012 11:49:45 +0900 Subject: [PATCH 02/13] tools lib traceevent: Get rid of die() from pretty_print() There are three cases that call die() in the pretty_print. 1. insufficient number of argument: cannot proceed anymore. 2. too long format conversion specifier: truncate and proceed. 3. bad size specifier in format string: skip and proceed. For all cases, convert die to do_warning, mark the event as EVENT_FL_FAILED and print error message at the last. Signed-off-by: Namhyung Kim Acked-by: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1346986187-5170-1-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 43 ++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index b5b4d806ffa2..6d5e75987a3d 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -3889,8 +3889,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event goto cont_process; case '*': /* The argument is the length. */ - if (!arg) - die("no argument match"); + if (!arg) { + do_warning("no argument match"); + event->flags |= EVENT_FL_FAILED; + goto out_failed; + } len_arg = eval_num_arg(data, size, event, arg); len_as_arg = 1; arg = arg->next; @@ -3923,15 +3926,21 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event case 'x': case 'X': case 'u': - if (!arg) - die("no argument match"); + if (!arg) { + do_warning("no argument match"); + event->flags |= EVENT_FL_FAILED; + goto out_failed; + } len = ((unsigned long)ptr + 1) - (unsigned long)saveptr; /* should never happen */ - if (len > 31) - die("bad format!"); + if (len > 31) { + do_warning("bad format!"); + event->flags |= EVENT_FL_FAILED; + len = 31; + } memcpy(format, saveptr, len); format[len] = 0; @@ -3995,19 +4004,26 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event trace_seq_printf(s, format, (long long)val); break; default: - die("bad count (%d)", ls); + do_warning("bad count (%d)", ls); + event->flags |= EVENT_FL_FAILED; } break; case 's': - if (!arg) - die("no matching argument"); + if (!arg) { + do_warning("no matching argument"); + event->flags |= EVENT_FL_FAILED; + goto out_failed; + } len = ((unsigned long)ptr + 1) - (unsigned long)saveptr; /* should never happen */ - if (len > 31) - die("bad format!"); + if (len > 31) { + do_warning("bad format!"); + event->flags |= EVENT_FL_FAILED; + len = 31; + } memcpy(format, saveptr, len); format[len] = 0; @@ -4025,6 +4041,11 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event trace_seq_putc(s, *ptr); } + if (event->flags & EVENT_FL_FAILED) { +out_failed: + trace_seq_printf(s, "[FAILED TO PARSE]"); + } + if (args) { free_args(args); free(bprint_fmt); From 0ca8da00ad170c12c12350c3a2500591a7bec535 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 7 Sep 2012 11:49:46 +0900 Subject: [PATCH 03/13] tools lib traceevent: Get rid of die() from pevent_register_event_handler If memory allocation for handler fails, return gracefully instead of calling die(). Note that casts to void * are needed because gcc complained about discarding 'const' qualifier during implicit argument cast. Signed-off-by: Namhyung Kim Acked-by: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1346986187-5170-2-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 6d5e75987a3d..17fd01d46e60 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -5183,7 +5183,12 @@ int pevent_register_event_handler(struct pevent *pevent, not_found: /* Save for later use. */ - handle = malloc_or_die(sizeof(*handle)); + handle = malloc(sizeof(*handle)); + if (!handle) { + do_warning("Failed to allocate event handler"); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } + memset(handle, 0, sizeof(*handle)); handle->id = id; if (event_name) @@ -5193,7 +5198,11 @@ int pevent_register_event_handler(struct pevent *pevent, if ((event_name && !handle->event_name) || (sys_name && !handle->sys_name)) { - die("Failed to allocate event/sys name"); + do_warning("Failed to allocate event/sys name"); + free((void *)handle->event_name); + free((void *)handle->sys_name); + free(handle); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; } handle->func = func; From 67ed939c9eb029c28057eb75de456a9d0e899fd4 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 7 Sep 2012 11:49:47 +0900 Subject: [PATCH 04/13] tools lib traceevent: Get rid of die() from pevent_register_print_function If memory allocation for handler fails or argument type is not match, return gracefully instead of calling die(). Also add an new error code for the later case. Signed-off-by: Namhyung Kim Acked-by: Steven Rostedt Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1346986187-5170-3-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 26 ++++++++++++++++++++------ tools/lib/traceevent/event-parse.h | 3 ++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 17fd01d46e60..4595aeb3c432 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -5080,6 +5080,7 @@ int pevent_register_print_function(struct pevent *pevent, struct pevent_func_params *param; enum pevent_func_arg_type type; va_list ap; + int ret; func_handle = find_func_handler(pevent, name); if (func_handle) { @@ -5092,14 +5093,21 @@ int pevent_register_print_function(struct pevent *pevent, remove_func_handler(pevent, name); } - func_handle = malloc_or_die(sizeof(*func_handle)); + func_handle = malloc(sizeof(*func_handle)); + if (!func_handle) { + do_warning("Failed to allocate function handler"); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } memset(func_handle, 0, sizeof(*func_handle)); func_handle->ret_type = ret_type; func_handle->name = strdup(name); func_handle->func = func; - if (!func_handle->name) - die("Failed to allocate function name"); + if (!func_handle->name) { + do_warning("Failed to allocate function name"); + free(func_handle); + return PEVENT_ERRNO__MEM_ALLOC_FAILED; + } next_param = &(func_handle->params); va_start(ap, name); @@ -5109,11 +5117,17 @@ int pevent_register_print_function(struct pevent *pevent, break; if (type < 0 || type >= PEVENT_FUNC_ARG_MAX_TYPES) { - warning("Invalid argument type %d", type); + do_warning("Invalid argument type %d", type); + ret = PEVENT_ERRNO__INVALID_ARG_TYPE; goto out_free; } - param = malloc_or_die(sizeof(*param)); + param = malloc(sizeof(*param)); + if (!param) { + do_warning("Failed to allocate function param"); + ret = PEVENT_ERRNO__MEM_ALLOC_FAILED; + goto out_free; + } param->type = type; param->next = NULL; @@ -5131,7 +5145,7 @@ int pevent_register_print_function(struct pevent *pevent, out_free: va_end(ap); free_func_handle(func_handle); - return -1; + return ret; } /** diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h index 863a0bbda7f1..3318963f1c98 100644 --- a/tools/lib/traceevent/event-parse.h +++ b/tools/lib/traceevent/event-parse.h @@ -351,7 +351,8 @@ enum pevent_flag { _PE(READ_ID_FAILED, "failed to read event id"), \ _PE(READ_FORMAT_FAILED, "failed to read event format"), \ _PE(READ_PRINT_FAILED, "failed to read event print fmt"), \ - _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace") + _PE(OLD_FTRACE_ARG_FAILED,"failed to allocate field name for ftrace"),\ + _PE(INVALID_ARG_TYPE, "invalid argument type") #undef _PE #define _PE(__code, __str) PEVENT_ERRNO__ ## __code From 863e451f69ddf255e877567e325298edd3b21519 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 6 Sep 2012 17:46:55 +0200 Subject: [PATCH 05/13] perf diff: Make diff command work with evsel hists Putting 'perf diff' command back on track with the 'latest' evsel hists changes. Each evsel has its own 'hists' object gathering stats for the particular event. While currently counts are accumulated for the whole session regardless of the events diversification within compared sessions. The 'perf diff' command now outputs all matching events within compared sessions (with event name specified). The per event diff output stays the same. $ ./perf diff # Event 'cycles' # # Baseline Delta Shared Object Symbol # ........ .......... ................. .............................. # 0.00% +15.14% [kernel.kallsyms] [k] __wake_up 0.00% +13.38% [kernel.kallsyms] [k] ext4fs_dirhash ... SNIP 0.00% +0.42% [kernel.kallsyms] [k] local_clock 0.17% -0.05% [kernel.kallsyms] [k] native_write_msr_safe # Event 'faults' # # Baseline Delta Shared Object Symbol # ........ .......... ................. .............................. # 0.00% +79.12% ld-2.15.so [.] _dl_relocate_object 0.00% +11.62% ld-2.15.so [.] openaux Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul E. McKenney Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1346946426-13496-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Documentation/perf-diff.txt | 3 + tools/perf/builtin-diff.c | 93 +++++++++++++++++--------- tools/perf/util/evsel.h | 7 ++ tools/perf/util/session.h | 4 +- 4 files changed, 72 insertions(+), 35 deletions(-) diff --git a/tools/perf/Documentation/perf-diff.txt b/tools/perf/Documentation/perf-diff.txt index 74d7481ed7a6..ab7f667de1b1 100644 --- a/tools/perf/Documentation/perf-diff.txt +++ b/tools/perf/Documentation/perf-diff.txt @@ -17,6 +17,9 @@ captured via perf record. If no parameters are passed it will assume perf.data.old and perf.data. +The differential profile is displayed only for events matching both +specified perf.data files. + OPTIONS ------- -M:: diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index d29d350fb2b7..e9933fdd256e 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c @@ -10,6 +10,7 @@ #include "util/event.h" #include "util/hist.h" #include "util/evsel.h" +#include "util/evlist.h" #include "util/session.h" #include "util/tool.h" #include "util/sort.h" @@ -24,11 +25,6 @@ static char diff__default_sort_order[] = "dso,symbol"; static bool force; static bool show_displacement; -struct perf_diff { - struct perf_tool tool; - struct perf_session *session; -}; - static int hists__add_entry(struct hists *self, struct addr_location *al, u64 period) { @@ -37,14 +33,12 @@ static int hists__add_entry(struct hists *self, return -ENOMEM; } -static int diff__process_sample_event(struct perf_tool *tool, +static int diff__process_sample_event(struct perf_tool *tool __used, union perf_event *event, struct perf_sample *sample, - struct perf_evsel *evsel __used, + struct perf_evsel *evsel, struct machine *machine) { - struct perf_diff *_diff = container_of(tool, struct perf_diff, tool); - struct perf_session *session = _diff->session; struct addr_location al; if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) { @@ -56,26 +50,24 @@ static int diff__process_sample_event(struct perf_tool *tool, if (al.filtered || al.sym == NULL) return 0; - if (hists__add_entry(&session->hists, &al, sample->period)) { + if (hists__add_entry(&evsel->hists, &al, sample->period)) { pr_warning("problem incrementing symbol period, skipping event\n"); return -1; } - session->hists.stats.total_period += sample->period; + evsel->hists.stats.total_period += sample->period; return 0; } -static struct perf_diff diff = { - .tool = { - .sample = diff__process_sample_event, - .mmap = perf_event__process_mmap, - .comm = perf_event__process_comm, - .exit = perf_event__process_task, - .fork = perf_event__process_task, - .lost = perf_event__process_lost, - .ordered_samples = true, - .ordering_requires_timestamps = true, - }, +static struct perf_tool tool = { + .sample = diff__process_sample_event, + .mmap = perf_event__process_mmap, + .comm = perf_event__process_comm, + .exit = perf_event__process_task, + .fork = perf_event__process_task, + .lost = perf_event__process_lost, + .ordered_samples = true, + .ordering_requires_timestamps = true, }; static void perf_session__insert_hist_entry_by_name(struct rb_root *root, @@ -146,34 +138,71 @@ static void hists__match(struct hists *older, struct hists *newer) } } +static struct perf_evsel *evsel_match(struct perf_evsel *evsel, + struct perf_evlist *evlist) +{ + struct perf_evsel *e; + + list_for_each_entry(e, &evlist->entries, node) + if (perf_evsel__match2(evsel, e)) + return e; + + return NULL; +} + static int __cmd_diff(void) { int ret, i; #define older (session[0]) #define newer (session[1]) struct perf_session *session[2]; + struct perf_evlist *evlist_new, *evlist_old; + struct perf_evsel *evsel; + bool first = true; older = perf_session__new(input_old, O_RDONLY, force, false, - &diff.tool); + &tool); newer = perf_session__new(input_new, O_RDONLY, force, false, - &diff.tool); + &tool); if (session[0] == NULL || session[1] == NULL) return -ENOMEM; for (i = 0; i < 2; ++i) { - diff.session = session[i]; - ret = perf_session__process_events(session[i], &diff.tool); + ret = perf_session__process_events(session[i], &tool); if (ret) goto out_delete; - hists__output_resort(&session[i]->hists); } - if (show_displacement) - hists__resort_entries(&older->hists); + evlist_old = older->evlist; + evlist_new = newer->evlist; + + list_for_each_entry(evsel, &evlist_new->entries, node) + hists__output_resort(&evsel->hists); + + list_for_each_entry(evsel, &evlist_old->entries, node) { + hists__output_resort(&evsel->hists); + + if (show_displacement) + hists__resort_entries(&evsel->hists); + } + + list_for_each_entry(evsel, &evlist_new->entries, node) { + struct perf_evsel *evsel_old; + + evsel_old = evsel_match(evsel, evlist_old); + if (!evsel_old) + continue; + + fprintf(stdout, "%s# Event '%s'\n#\n", first ? "" : "\n", + perf_evsel__name(evsel)); + + first = false; + + hists__match(&evsel_old->hists, &evsel->hists); + hists__fprintf(&evsel->hists, &evsel_old->hists, + show_displacement, true, 0, 0, stdout); + } - hists__match(&older->hists, &newer->hists); - hists__fprintf(&newer->hists, &older->hists, - show_displacement, true, 0, 0, stdout); out_delete: for (i = 0; i < 2; ++i) perf_session__delete(session[i]); diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index a3f562cec433..390690eb8781 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h @@ -124,6 +124,13 @@ void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads); (evsel->attr.type == PERF_TYPE_##t && \ evsel->attr.config == PERF_COUNT_##c) +static inline bool perf_evsel__match2(struct perf_evsel *e1, + struct perf_evsel *e2) +{ + return (e1->attr.type == e2->attr.type) && + (e1->attr.config == e2->attr.config); +} + int __perf_evsel__read_on_cpu(struct perf_evsel *evsel, int cpu, int thread, bool scale); diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 176a60902f56..aab414fbb64b 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -36,9 +36,7 @@ struct perf_session { struct pevent *pevent; /* * FIXME: Need to split this up further, we need global - * stats + per event stats. 'perf diff' also needs - * to properly support multiple events in a single - * perf.data file. + * stats + per event stats. */ struct hists hists; int fd; From 0ca0c130419a4aa05d28fbecc5d360f051944251 Mon Sep 17 00:00:00 2001 From: Jiri Olsa Date: Thu, 6 Sep 2012 17:46:56 +0200 Subject: [PATCH 06/13] perf tools: Replace sort's standalone field_sep with symbol_conf.field_sep The repsep_snprintf function was still using standalone field_sep, which not even set anymore. Replacing it with 'symbol_conf.field_sep'. Signed-off-by: Jiri Olsa Cc: Andi Kleen Cc: Corey Ashford Cc: David Ahern Cc: Frederic Weisbecker Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul E. McKenney Cc: Paul Mackerras Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/1346946426-13496-3-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/sort.c | 6 ++---- tools/perf/util/sort.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index 0f5a0a496bc4..7a2fbd8855b7 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c @@ -12,8 +12,6 @@ int sort__branch_mode = -1; /* -1 = means not set */ enum sort_type sort__first_dimension; -char * field_sep; - LIST_HEAD(hist_entry__sort_list); static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) @@ -23,11 +21,11 @@ static int repsep_snprintf(char *bf, size_t size, const char *fmt, ...) va_start(ap, fmt); n = vsnprintf(bf, size, fmt, ap); - if (field_sep && n > 0) { + if (symbol_conf.field_sep && n > 0) { char *sep = bf; while (1) { - sep = strchr(sep, *field_sep); + sep = strchr(sep, *symbol_conf.field_sep); if (sep == NULL) break; *sep = '.'; diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h index e724b26acd51..e459c981b039 100644 --- a/tools/perf/util/sort.h +++ b/tools/perf/util/sort.h @@ -32,7 +32,6 @@ extern const char default_sort_order[]; extern int sort__need_collapse; extern int sort__has_parent; extern int sort__branch_mode; -extern char *field_sep; extern struct sort_entry sort_comm; extern struct sort_entry sort_dso; extern struct sort_entry sort_sym; From b771a8306205f0261496e93574a71bc7106844dc Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Sat, 8 Sep 2012 03:43:17 +0300 Subject: [PATCH 07/13] perf tools: include basename for non-glibc systems perf uses the glibc version of basename(), by defining _GNU_SOURCE, including string.h and not including libgen.h. The glibc version of basename is better than the POSIX version since it does not modify its argument. Android has only one version of basename which is defined in libgen.h. This version is the same as the glibc version. Error on Android: util/annotate.c: In function 'symbol__annotate_printf': util/annotate.c:503:3: error: implicit declaration of function 'basename' [-Werror=implicit-function-declaration] util/annotate.c:503:3: error: nested extern declaration of 'basename' [-Werror=nested-externs] util/annotate.c:503:14: error: assignment makes pointer from integer without a cast [-Werror] On Android libgen.h should be included to define basename. Signed-off-by: Irina Tirdea Cc: David Ahern Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1347065004-15306-6-git-send-email-irina.tirdea@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/symbol.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index fc4b1e630fd9..d3b330cbc3e0 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -10,6 +10,9 @@ #include #include #include +#if defined(__BIONIC__) +#include +#endif #ifndef NO_LIBELF_SUPPORT #include From 57ec0a942d6855cd7a5711fcf4adb57c51259659 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Sat, 8 Sep 2012 03:43:18 +0300 Subject: [PATCH 08/13] perf tools: fix missing winsize definition In Android, struct winsize is not defined in the headers already included in help.c. This leads to a compile error. Including termios.h fixes the compilation error since it defines struct winsize. Signed-off-by: Irina Tirdea Cc: David Ahern Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1347065004-15306-7-git-send-email-irina.tirdea@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/help.c | 1 + tools/perf/util/top.h | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c index 6f2975a00358..4fa764d8f7d7 100644 --- a/tools/perf/util/help.c +++ b/tools/perf/util/help.c @@ -3,6 +3,7 @@ #include "exec_cmd.h" #include "levenshtein.h" #include "help.h" +#include void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) { diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index 33347ca89ee4..86ff1b15059b 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h @@ -5,6 +5,7 @@ #include "types.h" #include #include +#include struct perf_evlist; struct perf_evsel; From 27683dc5cc9286ace82b6c900ab794428ed5e487 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Sat, 8 Sep 2012 03:43:19 +0300 Subject: [PATCH 09/13] perf tools: include missing pthread.h header pthread variables are used in some files without explicitely including pthread.h. This leads to compile errors on Android. e.g.: in annotate.h, error: unknown type name 'pthread_mutex_t' Including pthread.h explicitely in files that use it to have all definitions included. Signed-off-by: Irina Tirdea Cc: David Ahern Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1347065004-15306-8-git-send-email-irina.tirdea@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/perf.c | 1 + tools/perf/util/annotate.h | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/perf/perf.c b/tools/perf/perf.c index e7840e500715..fb8578cfa03c 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -14,6 +14,7 @@ #include "util/run-command.h" #include "util/parse-events.h" #include "util/debugfs.h" +#include const char perf_usage_string[] = "perf [--version] [--help] COMMAND [ARGS]"; diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h index a6d6bc5d7164..62a6e7a7365d 100644 --- a/tools/perf/util/annotate.h +++ b/tools/perf/util/annotate.h @@ -7,6 +7,7 @@ #include "symbol.h" #include #include +#include struct ins; From 7b45f21c2e42f265f6fd469e43857e98e2fdf01c Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Sat, 8 Sep 2012 03:43:21 +0300 Subject: [PATCH 10/13] perf tools: replace mkostemp with mkstemp The mkostemp function is only available in glibc. This leads to compile error in Android, since bionic is derived from BSD. Replacing mkostemp with mkstemp. mkstemp is available on both glibc and bionic. Signed-off-by: Irina Tirdea Cc: David Ahern Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1347065004-15306-10-git-send-email-irina.tirdea@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/dso-test-data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/perf/util/dso-test-data.c b/tools/perf/util/dso-test-data.c index 541cdc72c7df..c6caedeb1d6b 100644 --- a/tools/perf/util/dso-test-data.c +++ b/tools/perf/util/dso-test-data.c @@ -23,7 +23,7 @@ static char *test_file(int size) int fd, i; unsigned char *buf; - fd = mkostemp(templ, O_CREAT|O_WRONLY|O_TRUNC); + fd = mkstemp(templ); buf = malloc(size); if (!buf) { From 9612ef6716efc20fac0f57d59452cda4e6846bda Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Sat, 8 Sep 2012 03:43:22 +0300 Subject: [PATCH 11/13] tools lib traceevent: replace mempcpy with memcpy The mempcpy function is not supported by bionic in Android and will lead to compilation errors. Replacing mempcpy with memcpy so it will work in Android. Signed-off-by: Irina Tirdea Cc: David Ahern Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1347065004-15306-11-git-send-email-irina.tirdea@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/lib/traceevent/event-parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c index 4595aeb3c432..f4190b5764de 100644 --- a/tools/lib/traceevent/event-parse.c +++ b/tools/lib/traceevent/event-parse.c @@ -4833,8 +4833,8 @@ int pevent_strerror(struct pevent *pevent, enum pevent_errno errnum, msg = strerror_r(errnum, buf, buflen); if (msg != buf) { size_t len = strlen(msg); - char *c = mempcpy(buf, msg, min(buflen-1, len)); - *c = '\0'; + memcpy(buf, msg, min(buflen - 1, len)); + *(buf + min(buflen - 1, len)) = '\0'; } return 0; } From c9f08bee50c71b06685ccff8110e56a7c05662b7 Mon Sep 17 00:00:00 2001 From: Irina Tirdea Date: Sat, 8 Sep 2012 03:43:23 +0300 Subject: [PATCH 12/13] perf tools: add NO_BACKTRACE for application self-debugging perf has support for self-debugging by defining dump_stack function. This function uses backtrace and backtrace_symbols functions defined as GNU extensions. In Android, bionic does not offer support for these functions and compilation will fail with the following error: target C: libperf <= tools/perf/util/util.c tools/perf/util/util.c:4:22: fatal error: execinfo.h: No such file or directory compilation terminated. Add a compile-time option (NO_BACKTRACE) to enable or disable self-debugging functionality in perf. This can also help in debugging since it offers the possibility to turn on/off printing the backtrace. Signed-off-by: Irina Tirdea Cc: David Ahern Cc: Ingo Molnar Cc: Namhyung Kim Cc: Paul Mackerras Cc: Peter Zijlstra Cc: Steven Rostedt Link: http://lkml.kernel.org/r/1347065004-15306-12-git-send-email-irina.tirdea@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/Makefile | 8 ++++++++ tools/perf/config/feature-tests.mak | 14 ++++++++++++++ tools/perf/util/util.c | 6 ++++++ 3 files changed, 28 insertions(+) diff --git a/tools/perf/Makefile b/tools/perf/Makefile index afd507574902..3eda49215730 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -755,6 +755,14 @@ else endif endif +ifdef NO_BACKTRACE + BASIC_CFLAGS += -DNO_BACKTRACE +else + ifneq ($(call try-cc,$(SOURCE_BACKTRACE),),y) + BASIC_CFLAGS += -DNO_BACKTRACE + endif +endif + ifdef ASCIIDOC8 export ASCIIDOC8 endif diff --git a/tools/perf/config/feature-tests.mak b/tools/perf/config/feature-tests.mak index 2f1156a62ab7..116690a669d2 100644 --- a/tools/perf/config/feature-tests.mak +++ b/tools/perf/config/feature-tests.mak @@ -179,3 +179,17 @@ int main(void) } endef endif + +ifndef NO_BACKTRACE +define SOURCE_BACKTRACE +#include +#include + +int main(void) +{ + backtrace(NULL, 0); + backtrace_symbols(NULL, 0); + return 0; +} +endef +endif diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 1b8775c3707d..2055cf38041c 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c @@ -1,7 +1,9 @@ #include "../perf.h" #include "util.h" #include +#ifndef NO_BACKTRACE #include +#endif #include #include @@ -163,6 +165,7 @@ size_t hex_width(u64 v) } /* Obtain a backtrace and print it to stdout. */ +#ifndef NO_BACKTRACE void dump_stack(void) { void *array[16]; @@ -177,3 +180,6 @@ void dump_stack(void) free(strings); } +#else +void dump_stack(void) {} +#endif From b155a09015135cf59ada8d48109ccbd9891c1b42 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Fri, 31 Aug 2012 10:49:27 +0300 Subject: [PATCH 13/13] perf tools: Fix build for another rbtree.c change Fixes: ../../lib/rbtree.c: In function 'rb_insert_color': ../../lib/rbtree.c:95:9: error: 'true' undeclared (first use in this function) ../../lib/rbtree.c:95:9: note: each undeclared identifier is reported only once for each function it appears in ../../lib/rbtree.c: In function '__rb_erase_color': ../../lib/rbtree.c:216:9: error: 'true' undeclared (first use in this function) ../../lib/rbtree.c: In function 'rb_erase': ../../lib/rbtree.c:368:2: error: unknown type name 'bool' make: *** [util/rbtree.o] Error 1 Signed-off-by: Adrian Hunter Cc: Michel Lespinasse Cc: Andrew Morton Cc: linux-mm@kvack.org Link: http://lkml.kernel.org/r/50406F60.5040707@intel.com Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/include/linux/rbtree.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/perf/util/include/linux/rbtree.h b/tools/perf/util/include/linux/rbtree.h index 7a243a143037..2a030c5af3aa 100644 --- a/tools/perf/util/include/linux/rbtree.h +++ b/tools/perf/util/include/linux/rbtree.h @@ -1 +1,2 @@ +#include #include "../../../../include/linux/rbtree.h"