Hi,
Here is a series of patches for 4.4.y to build perf-tools on newer toolchain. This also includes a perf-probe fix.
Thank you,
---
Arnaldo Carvalho de Melo (1): perf annotate: Use asprintf when formatting objdump command line
Changbin Du (1): perf: Make perf able to build with latest libbfd
Jiri Olsa (1): perf tools: Fix snprint warnings for gcc 8
Masami Hiramatsu (1): perf probe: Fix to check blacklist address correctly
Sergey Senozhatsky (1): tools/lib/subcmd/pager.c: do not alias select() params
tools/perf/builtin-script.c | 24 ++++++++++++------------ tools/perf/tests/attr.c | 4 ++-- tools/perf/tests/pmu.c | 2 +- tools/perf/util/annotate.c | 14 +++++++++++--- tools/perf/util/cgroup.c | 2 +- tools/perf/util/pager.c | 5 ++++- tools/perf/util/parse-events.c | 4 ++-- tools/perf/util/pmu.c | 2 +- tools/perf/util/probe-event.c | 21 +++++++++++++++------ tools/perf/util/srcline.c | 16 +++++++++++++++- 10 files changed, 64 insertions(+), 30 deletions(-)
-- Masami Hiramatsu (Linaro) mhiramat@kernel.org
commit 80526491c2ca6abc028c0f0dbb0707a1f35fb18a upstream.
Fix to check kprobe blacklist address correctly with relocated address by adjusting debuginfo address.
Since the address in the debuginfo is same as objdump, it is different from relocated kernel address with KASLR. Thus, 'perf probe' always misses to catch the blacklisted addresses.
Without this patch, 'perf probe' can not detect the blacklist addresses on a KASLR enabled kernel.
# perf probe kprobe_dispatcher Failed to write event: Invalid argument Error: Failed to add events. #
With this patch, it correctly shows the error message.
# perf probe kprobe_dispatcher kprobe_dispatcher is blacklisted function, skip it. Probe point 'kprobe_dispatcher' not found. Error: Failed to add events. #
Fixes: 9aaf5a5f479b ("perf probe: Check kprobes blacklist when adding new events") Signed-off-by: Masami Hiramatsu mhiramat@kernel.org Tested-by: Arnaldo Carvalho de Melo acme@redhat.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: stable@vger.kernel.org Link: http://lore.kernel.org/lkml/158763966411.30755.5882376357738273695.stgit@dev... Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com --- tools/perf/util/probe-event.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 0195b7e8c54a..4f05424096b6 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c @@ -122,7 +122,7 @@ static struct symbol *__find_kernel_function(u64 addr, struct map **mapp) return machine__find_kernel_function(host_machine, addr, mapp, NULL); }
-static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void) +static struct ref_reloc_sym *kernel_get_ref_reloc_sym(struct map **pmap) { /* kmap->ref_reloc_sym should be set if host_machine is initialized */ struct kmap *kmap; @@ -134,6 +134,10 @@ static struct ref_reloc_sym *kernel_get_ref_reloc_sym(void) kmap = map__kmap(map); if (!kmap) return NULL; + + if (pmap) + *pmap = map; + return kmap->ref_reloc_sym; }
@@ -145,7 +149,7 @@ static int kernel_get_symbol_address_by_name(const char *name, u64 *addr, struct map *map;
/* ref_reloc_sym is just a label. Need a special fix*/ - reloc_sym = kernel_get_ref_reloc_sym(); + reloc_sym = kernel_get_ref_reloc_sym(NULL); if (reloc_sym && strcmp(name, reloc_sym->name) == 0) *addr = (reloc) ? reloc_sym->addr : reloc_sym->unrelocated_addr; else { @@ -618,6 +622,7 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs, bool uprobe) { struct ref_reloc_sym *reloc_sym; + struct map *map; char *tmp; int i, skipped = 0;
@@ -628,7 +633,7 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs, if (module) return add_module_to_probe_trace_events(tevs, ntevs, module);
- reloc_sym = kernel_get_ref_reloc_sym(); + reloc_sym = kernel_get_ref_reloc_sym(&map); if (!reloc_sym) { pr_warning("Relocated base symbol is not found!\n"); return -EINVAL; @@ -637,9 +642,13 @@ static int post_process_probe_trace_events(struct probe_trace_event *tevs, for (i = 0; i < ntevs; i++) { if (!tevs[i].point.address || tevs[i].point.retprobe) continue; - /* If we found a wrong one, mark it by NULL symbol */ + /* + * If we found a wrong one, mark it by NULL symbol. + * Since addresses in debuginfo is same as objdump, we need + * to convert it to addresses on memory. + */ if (kprobe_warn_out_range(tevs[i].point.symbol, - tevs[i].point.address)) { + map__objdump_2mem(map, tevs[i].point.address))) { tmp = NULL; skipped++; } else { @@ -2553,7 +2562,7 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev,
/* Note that the symbols in the kmodule are not relocated */ if (!pev->uprobes && !pp->retprobe && !pev->target) { - reloc_sym = kernel_get_ref_reloc_sym(); + reloc_sym = kernel_get_ref_reloc_sym(NULL); if (!reloc_sym) { pr_warning("Relocated base symbol is not found!\n"); ret = -EINVAL;
From: Arnaldo Carvalho de Melo acme@redhat.com
commit 6810158d526e483868e519befff407b91e76b3db upstream.
We were using a local buffer with an arbitrary size, that would have to get increased to avoid truncation as warned by gcc 8:
util/annotate.c: In function 'symbol__disassemble': util/annotate.c:1488:4: error: '%s' directive output may be truncated writing up to 4095 bytes into a region of size between 3966 and 8086 [-Werror=format-truncation=] "%s %s%s --start-address=0x%016" PRIx64 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ util/annotate.c:1498:20: symfs_filename, symfs_filename); ~~~~~~~~~~~~~~ util/annotate.c:1490:50: note: format string is defined here " -l -d %s %s -C "%s" 2>/dev/null|grep -v "%s:"|expand", ^~ In file included from /usr/include/stdio.h:861, from util/color.h:5, from util/sort.h:8, from util/annotate.c:14: /usr/include/bits/stdio2.h:67:10: note: '__builtin___snprintf_chk' output 116 or more bytes (assuming 8331) into a destination of size 8192 return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ __bos (__s), __fmt, __va_arg_pack ()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
So switch to asprintf, that will make sure enough space is available.
Cc: Adrian Hunter adrian.hunter@intel.com Cc: David Ahern dsahern@gmail.com Cc: Jin Yao yao.jin@linux.intel.com Cc: Jiri Olsa jolsa@kernel.org Cc: Namhyung Kim namhyung@kernel.org Cc: Wang Nan wangnan0@huawei.com Link: https://lkml.kernel.org/n/tip-qagoy2dmbjpc9gdnaj0r3mml@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com --- tools/perf/util/annotate.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index 1dd1949b0e79..1e1c37a17355 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c @@ -1077,7 +1077,7 @@ int symbol__annotate(struct symbol *sym, struct map *map, size_t privsize) struct dso *dso = map->dso; char *filename = dso__build_id_filename(dso, NULL, 0); bool free_filename = true; - char command[PATH_MAX * 2]; + char *command; FILE *file; int err = 0; char symfs_filename[PATH_MAX]; @@ -1192,7 +1192,7 @@ fallback: strcpy(symfs_filename, tmp); }
- snprintf(command, sizeof(command), + err = asprintf(&command, "%s %s%s --start-address=0x%016" PRIx64 " --stop-address=0x%016" PRIx64 " -l -d %s %s -C %s 2>/dev/null|grep -v %s|expand", @@ -1205,6 +1205,11 @@ fallback: symbol_conf.annotate_src ? "-S" : "", symfs_filename, filename);
+ if (err < 0) { + pr_err("Failure allocating memory for the command to run\n"); + goto out_remove_tmp; + } + pr_debug("Executing: %s\n", command);
file = popen(command, "r"); @@ -1214,7 +1219,7 @@ fallback: * If we were using debug info should retry with * original binary. */ - goto out_remove_tmp; + goto out_free_command; }
nline = 0; @@ -1237,6 +1242,9 @@ fallback:
pclose(file);
+out_free_command: + free(command); + out_remove_tmp: if (dso__needs_decompress(dso)) unlink(symfs_filename);
From: Jiri Olsa jolsa@kernel.org
commit 77f18153c080855e1c3fb520ca31a4e61530121d upstream.
[Add an additional sprintf replacement in tools/perf/builtin-script.c]
With gcc 8 we get new set of snprintf() warnings that breaks the compilation, one example:
tests/mem.c: In function ‘check’: tests/mem.c:19:48: error: ‘%s’ directive output may be truncated writing \ up to 99 bytes into a region of size 89 [-Werror=format-truncation=] snprintf(failure, sizeof failure, "unexpected %s", out);
The gcc docs says:
To avoid the warning either use a bigger buffer or handle the function's return value which indicates whether or not its output has been truncated.
Given that all these warnings are harmless, because the code either properly fails due to uncomplete file path or we don't care for truncated output at all, I'm changing all those snprintf() calls to scnprintf(), which actually 'checks' for the snprint return value so the gcc stays silent.
Signed-off-by: Jiri Olsa jolsa@kernel.org Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: David Ahern dsahern@gmail.com Cc: Josh Poimboeuf jpoimboe@redhat.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Sergey Senozhatsky sergey.senozhatsky.work@gmail.com Link: http://lkml.kernel.org/r/20180319082902.4518-1-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com --- tools/perf/builtin-script.c | 24 ++++++++++++------------ tools/perf/tests/attr.c | 4 ++-- tools/perf/tests/pmu.c | 2 +- tools/perf/util/cgroup.c | 2 +- tools/perf/util/parse-events.c | 4 ++-- tools/perf/util/pmu.c | 2 +- 6 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 20f0e27918dd..acd460303d1a 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1245,7 +1245,7 @@ static int is_directory(const char *base_path, const struct dirent *dent) char path[PATH_MAX]; struct stat st;
- sprintf(path, "%s/%s", base_path, dent->d_name); + scnprintf(path, PATH_MAX, "%s/%s", base_path, dent->d_name); if (stat(path, &st)) return 0;
@@ -1426,8 +1426,8 @@ static int list_available_scripts(const struct option *opt __maybe_unused, return -1;
for_each_lang(scripts_path, scripts_dir, lang_dirent) { - snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, - lang_dirent->d_name); + scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, + lang_dirent->d_name); lang_dir = opendir(lang_path); if (!lang_dir) continue; @@ -1436,8 +1436,8 @@ static int list_available_scripts(const struct option *opt __maybe_unused, script_root = get_script_root(script_dirent, REPORT_SUFFIX); if (script_root) { desc = script_desc__findnew(script_root); - snprintf(script_path, MAXPATHLEN, "%s/%s", - lang_path, script_dirent->d_name); + scnprintf(script_path, MAXPATHLEN, "%s/%s", + lang_path, script_dirent->d_name); read_script_info(desc, script_path); free(script_root); } @@ -1473,7 +1473,7 @@ static int check_ev_match(char *dir_name, char *scriptname, int match, len; FILE *fp;
- sprintf(filename, "%s/bin/%s-record", dir_name, scriptname); + scnprintf(filename, MAXPATHLEN, "%s/bin/%s-record", dir_name, scriptname);
fp = fopen(filename, "r"); if (!fp) @@ -1549,8 +1549,8 @@ int find_scripts(char **scripts_array, char **scripts_path_array) }
for_each_lang(scripts_path, scripts_dir, lang_dirent) { - snprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, - lang_dirent->d_name); + scnprintf(lang_path, MAXPATHLEN, "%s/%s", scripts_path, + lang_dirent->d_name); #ifdef NO_LIBPERL if (strstr(lang_path, "perl")) continue; @@ -1605,8 +1605,8 @@ static char *get_script_path(const char *script_root, const char *suffix) return NULL;
for_each_lang(scripts_path, scripts_dir, lang_dirent) { - snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, - lang_dirent->d_name); + scnprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path, + lang_dirent->d_name); lang_dir = opendir(lang_path); if (!lang_dir) continue; @@ -1617,8 +1617,8 @@ static char *get_script_path(const char *script_root, const char *suffix) free(__script_root); closedir(lang_dir); closedir(scripts_dir); - snprintf(script_path, MAXPATHLEN, "%s/%s", - lang_path, script_dirent->d_name); + scnprintf(script_path, MAXPATHLEN, "%s/%s", + lang_path, script_dirent->d_name); return strdup(script_path); } free(__script_root); diff --git a/tools/perf/tests/attr.c b/tools/perf/tests/attr.c index 79547c225c14..9c81fbfb16d2 100644 --- a/tools/perf/tests/attr.c +++ b/tools/perf/tests/attr.c @@ -147,8 +147,8 @@ static int run_dir(const char *d, const char *perf) if (verbose) vcnt++;
- snprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s", - d, d, perf, vcnt, v); + scnprintf(cmd, 3*PATH_MAX, PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s", + d, d, perf, vcnt, v);
return system(cmd) ? TEST_FAIL : TEST_OK; } diff --git a/tools/perf/tests/pmu.c b/tools/perf/tests/pmu.c index faa04e9d5d5f..b776831ceeea 100644 --- a/tools/perf/tests/pmu.c +++ b/tools/perf/tests/pmu.c @@ -95,7 +95,7 @@ static char *test_format_dir_get(void) struct test_format *format = &test_formats[i]; FILE *file;
- snprintf(name, PATH_MAX, "%s/%s", dir, format->name); + scnprintf(name, PATH_MAX, "%s/%s", dir, format->name);
file = fopen(name, "w"); if (!file) diff --git a/tools/perf/util/cgroup.c b/tools/perf/util/cgroup.c index 32e12ecfe9c5..a32f0b34e3ed 100644 --- a/tools/perf/util/cgroup.c +++ b/tools/perf/util/cgroup.c @@ -64,7 +64,7 @@ static int open_cgroup(char *name) if (cgroupfs_find_mountpoint(mnt, PATH_MAX + 1)) return -1;
- snprintf(path, PATH_MAX, "%s/%s", mnt, name); + scnprintf(path, PATH_MAX, "%s/%s", mnt, name);
fd = open(path, O_RDONLY); if (fd == -1) diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 9351738df703..849ad278dd5d 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -194,8 +194,8 @@ struct tracepoint_path *tracepoint_id_to_path(u64 config)
for_each_event(sys_dirent, evt_dir, evt_dirent) {
- snprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, - evt_dirent->d_name); + scnprintf(evt_path, MAXPATHLEN, "%s/%s/id", dir_path, + evt_dirent->d_name); fd = open(evt_path, O_RDONLY); if (fd < 0) continue; diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 4f650ebd564a..5245fbd09106 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c @@ -302,7 +302,7 @@ static int pmu_aliases_parse(char *dir, struct list_head *head) if (pmu_alias_info_file(name)) continue;
- snprintf(path, PATH_MAX, "%s/%s", dir, name); + scnprintf(path, PATH_MAX, "%s/%s", dir, name);
file = fopen(path, "r"); if (!file) {
From: Changbin Du changbin.du@gmail.com
commit 0ada120c883d4f1f6aafd01cf0fbb10d8bbba015 upstream.
libbfd has changed the bfd_section_* macros to inline functions bfd_section_<field> since 2019-09-18. See below two commits: o http://www.sourceware.org/ml/gdb-cvs/2019-09/msg00064.html o https://www.sourceware.org/ml/gdb-cvs/2019-09/msg00072.html
This fix make perf able to build with both old and new libbfd.
Signed-off-by: Changbin Du changbin.du@gmail.com Acked-by: Jiri Olsa jolsa@redhat.com Cc: Peter Zijlstra peterz@infradead.org Link: http://lore.kernel.org/lkml/20200128152938.31413-1-changbin.du@gmail.com Signed-off-by: Arnaldo Carvalho de Melo acme@redhat.com --- tools/perf/util/srcline.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c index b4db3f48e3b0..2853d4728ab9 100644 --- a/tools/perf/util/srcline.c +++ b/tools/perf/util/srcline.c @@ -86,16 +86,30 @@ static void find_address_in_section(bfd *abfd, asection *section, void *data) bfd_vma pc, vma; bfd_size_type size; struct a2l_data *a2l = data; + flagword flags;
if (a2l->found) return;
- if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0) +#ifdef bfd_get_section_flags + flags = bfd_get_section_flags(abfd, section); +#else + flags = bfd_section_flags(section); +#endif + if ((flags & SEC_ALLOC) == 0) return;
pc = a2l->addr; +#ifdef bfd_get_section_vma vma = bfd_get_section_vma(abfd, section); +#else + vma = bfd_section_vma(section); +#endif +#ifdef bfd_get_section_size size = bfd_get_section_size(section); +#else + size = bfd_section_size(section); +#endif
if (pc < vma || pc >= vma + size) return;
From: Sergey Senozhatsky sergey.senozhatsky@gmail.com
commit dfbc3c6cb747c074aa2ba0a10bbeea588d6dfda6 upstream.
[ Change applied file from tools/lib/subcmd/pager.c to tools/perf/util/pager.c ]
Use a separate fd set for select()-s exception fds param to fix the following gcc warning:
pager.c:36:12: error: passing argument 2 to restrict-qualified parameter aliases with argument 4 [-Werror=restrict] select(1, &in, NULL, &in, NULL); ^~~ ~~~
Link: http://lkml.kernel.org/r/20180101105626.7168-1-sergey.senozhatsky@gmail.com Signed-off-by: Sergey Senozhatsky sergey.senozhatsky@gmail.com Cc: Arnaldo Carvalho de Melo acme@redhat.com Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org --- tools/perf/util/pager.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/pager.c b/tools/perf/util/pager.c index 53ef006a951c..b301d779c4af 100644 --- a/tools/perf/util/pager.c +++ b/tools/perf/util/pager.c @@ -16,10 +16,13 @@ static void pager_preexec(void) * have real input */ fd_set in; + fd_set exception;
FD_ZERO(&in); + FD_ZERO(&exception); FD_SET(0, &in); - select(1, &in, NULL, &in, NULL); + FD_SET(0, &exception); + select(1, &in, NULL, &exception, NULL);
setenv("LESS", "FRSX", 0); }
linux-stable-mirror@lists.linaro.org