aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2016-07-19 02:44:38 -0400
committerIngo Molnar <mingo@kernel.org>2016-07-19 02:44:38 -0400
commit5048c2af078d5976895d521262a8802ea791f3b0 (patch)
treeff17370ff5f36680ca7f71df0b9444747699348c /tools/perf
parent09211e2530ab4905ec16edecc27022d6b247419d (diff)
parent988dd774dcbd9151c2a643fc7284c5c3c4d0adb7 (diff)
Merge tag 'perf-core-for-mingo-20160718' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Properly report when a function wildcard produces no matches in 'perf probe' (Masami Hiramatsu) - Balance opening and reading events in 'perf stat', which could cause it to get stuck trying to close invalid file descriptors (Mark Rutland) Infrastructure changes: - Copy more headers from the kernel, this time for headers that were just including the contents of its kernel counterparts, should help resolving the problems with linux-next, where some uapi related patches seem to be breaking tools/object/ build. (Arnaldo Carvalho de Melo) Some more combing will be done, but at least it is possible to build perf out of tree, via a detached tarball (make help | grep perf), without including kernel files in its MANIFEST (Arnaldo Carvalho de Melo) - Fix smatch found errors that were not causing problems, but are mistakes nonetheless (Dan Carpenter) - Fix string vs. byte array resolving in the python script code (Jiri Olsa) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/MANIFEST13
-rw-r--r--tools/perf/Makefile.perf18
-rw-r--r--tools/perf/builtin-stat.c8
-rw-r--r--tools/perf/jvmti/jvmti_agent.c10
-rw-r--r--tools/perf/perf-sys.h1
-rw-r--r--tools/perf/tests/Build1
-rw-r--r--tools/perf/tests/builtin-test.c4
-rw-r--r--tools/perf/tests/is_printable_array.c36
-rw-r--r--tools/perf/tests/tests.h1
-rw-r--r--tools/perf/util/cpumap.c14
-rw-r--r--tools/perf/util/cpumap.h2
-rw-r--r--tools/perf/util/include/asm/byteorder.h2
-rw-r--r--tools/perf/util/include/linux/const.h1
-rw-r--r--tools/perf/util/map.c3
-rw-r--r--tools/perf/util/probe-event.c12
-rw-r--r--tools/perf/util/python.c12
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c25
-rw-r--r--tools/perf/util/util.c16
-rw-r--r--tools/perf/util/util.h1
19 files changed, 132 insertions, 48 deletions
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 923eda2e7d52..ad2534df4ba6 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -77,17 +77,4 @@ tools/include/linux/stringify.h
77tools/include/linux/types.h 77tools/include/linux/types.h
78tools/include/linux/err.h 78tools/include/linux/err.h
79tools/include/linux/bitmap.h 79tools/include/linux/bitmap.h
80include/asm-generic/bitops/arch_hweight.h
81include/asm-generic/bitops/const_hweight.h
82include/asm-generic/bitops/fls64.h
83include/asm-generic/bitops/__fls.h
84include/asm-generic/bitops/fls.h
85include/linux/list.h
86include/linux/hash.h
87include/linux/swab.h
88arch/*/include/asm/unistd*.h
89arch/*/include/uapi/asm/unistd*.h
90tools/arch/*/include/uapi/asm/perf_regs.h 80tools/arch/*/include/uapi/asm/perf_regs.h
91include/linux/poison.h
92include/uapi/linux/const.h
93include/uapi/linux/swab.h
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index a129fbc1ed37..6641abb97f0a 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -351,6 +351,9 @@ $(PERF_IN): prepare FORCE
351 @(test -f ../../include/uapi/linux/perf_event.h && ( \ 351 @(test -f ../../include/uapi/linux/perf_event.h && ( \
352 (diff -B ../include/uapi/linux/perf_event.h ../../include/uapi/linux/perf_event.h >/dev/null) \ 352 (diff -B ../include/uapi/linux/perf_event.h ../../include/uapi/linux/perf_event.h >/dev/null) \
353 || echo "Warning: tools/include/uapi/linux/perf_event.h differs from kernel" >&2 )) || true 353 || echo "Warning: tools/include/uapi/linux/perf_event.h differs from kernel" >&2 )) || true
354 @(test -f ../../include/linux/hash.h && ( \
355 (diff -B ../include/linux/hash.h ../../include/linux/hash.h >/dev/null) \
356 || echo "Warning: tools/include/linux/hash.h differs from kernel" >&2 )) || true
354 @(test -f ../../include/uapi/linux/hw_breakpoint.h && ( \ 357 @(test -f ../../include/uapi/linux/hw_breakpoint.h && ( \
355 (diff -B ../include/uapi/linux/hw_breakpoint.h ../../include/uapi/linux/hw_breakpoint.h >/dev/null) \ 358 (diff -B ../include/uapi/linux/hw_breakpoint.h ../../include/uapi/linux/hw_breakpoint.h >/dev/null) \
356 || echo "Warning: tools/include/uapi/linux/hw_breakpoint.h differs from kernel" >&2 )) || true 359 || echo "Warning: tools/include/uapi/linux/hw_breakpoint.h differs from kernel" >&2 )) || true
@@ -411,6 +414,21 @@ $(PERF_IN): prepare FORCE
411 @(test -f ../../arch/arm64/include/uapi/asm/kvm.h && ( \ 414 @(test -f ../../arch/arm64/include/uapi/asm/kvm.h && ( \
412 (diff -B ../arch/arm64/include/uapi/asm/kvm.h ../../arch/arm64/include/uapi/asm/kvm.h >/dev/null) \ 415 (diff -B ../arch/arm64/include/uapi/asm/kvm.h ../../arch/arm64/include/uapi/asm/kvm.h >/dev/null) \
413 || echo "Warning: tools/arch/arm64/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true 416 || echo "Warning: tools/arch/arm64/include/uapi/asm/kvm.h differs from kernel" >&2 )) || true
417 @(test -f ../../include/asm-generic/bitops/arch_hweight.h && ( \
418 (diff -B ../include/asm-generic/bitops/arch_hweight.h ../../include/asm-generic/bitops/arch_hweight.h >/dev/null) \
419 || echo "Warning: tools/include/asm-generic/bitops/arch_hweight.h differs from kernel" >&2 )) || true
420 @(test -f ../../include/asm-generic/bitops/const_hweight.h && ( \
421 (diff -B ../include/asm-generic/bitops/const_hweight.h ../../include/asm-generic/bitops/const_hweight.h >/dev/null) \
422 || echo "Warning: tools/include/asm-generic/bitops/const_hweight.h differs from kernel" >&2 )) || true
423 @(test -f ../../include/asm-generic/bitops/__fls.h && ( \
424 (diff -B ../include/asm-generic/bitops/__fls.h ../../include/asm-generic/bitops/__fls.h >/dev/null) \
425 || echo "Warning: tools/include/asm-generic/bitops/__fls.h differs from kernel" >&2 )) || true
426 @(test -f ../../include/asm-generic/bitops/fls.h && ( \
427 (diff -B ../include/asm-generic/bitops/fls.h ../../include/asm-generic/bitops/fls.h >/dev/null) \
428 || echo "Warning: tools/include/asm-generic/bitops/fls.h differs from kernel" >&2 )) || true
429 @(test -f ../../include/asm-generic/bitops/fls64.h && ( \
430 (diff -B ../include/asm-generic/bitops/fls64.h ../../include/asm-generic/bitops/fls64.h >/dev/null) \
431 || echo "Warning: tools/include/asm-generic/bitops/fls64.h differs from kernel" >&2 )) || true
414 $(Q)$(MAKE) $(build)=perf 432 $(Q)$(MAKE) $(build)=perf
415 433
416$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST) 434$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8c5a3bfdfdd7..0c16d20d7e32 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -290,8 +290,12 @@ perf_evsel__write_stat_event(struct perf_evsel *counter, u32 cpu, u32 thread,
290static int read_counter(struct perf_evsel *counter) 290static int read_counter(struct perf_evsel *counter)
291{ 291{
292 int nthreads = thread_map__nr(evsel_list->threads); 292 int nthreads = thread_map__nr(evsel_list->threads);
293 int ncpus = perf_evsel__nr_cpus(counter); 293 int ncpus, cpu, thread;
294 int cpu, thread; 294
295 if (target__has_cpu(&target))
296 ncpus = perf_evsel__nr_cpus(counter);
297 else
298 ncpus = 1;
295 299
296 if (!counter->supported) 300 if (!counter->supported)
297 return -ENOENT; 301 return -ENOENT;
diff --git a/tools/perf/jvmti/jvmti_agent.c b/tools/perf/jvmti/jvmti_agent.c
index 3573f315f955..55daefff0d54 100644
--- a/tools/perf/jvmti/jvmti_agent.c
+++ b/tools/perf/jvmti/jvmti_agent.c
@@ -59,7 +59,6 @@ static int get_e_machine(struct jitheader *hdr)
59 ssize_t sret; 59 ssize_t sret;
60 char id[16]; 60 char id[16];
61 int fd, ret = -1; 61 int fd, ret = -1;
62 int m = -1;
63 struct { 62 struct {
64 uint16_t e_type; 63 uint16_t e_type;
65 uint16_t e_machine; 64 uint16_t e_machine;
@@ -81,11 +80,7 @@ static int get_e_machine(struct jitheader *hdr)
81 if (sret != sizeof(info)) 80 if (sret != sizeof(info))
82 goto error; 81 goto error;
83 82
84 m = info.e_machine; 83 hdr->elf_mach = info.e_machine;
85 if (m < 0)
86 m = 0; /* ELF EM_NONE */
87
88 hdr->elf_mach = m;
89 ret = 0; 84 ret = 0;
90error: 85error:
91 close(fd); 86 close(fd);
@@ -491,10 +486,11 @@ jvmti_write_debug_info(void *agent, uint64_t code, const char *file,
491 if (sret != 1) 486 if (sret != 1)
492 goto error; 487 goto error;
493 } 488 }
494 if (padding_count) 489 if (padding_count) {
495 sret = fwrite_unlocked(pad_bytes, padding_count, 1, fp); 490 sret = fwrite_unlocked(pad_bytes, padding_count, 1, fp);
496 if (sret != 1) 491 if (sret != 1)
497 goto error; 492 goto error;
493 }
498 494
499 funlockfile(fp); 495 funlockfile(fp);
500 return 0; 496 return 0;
diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h
index 5cee8a3d0455..7ed72a475c57 100644
--- a/tools/perf/perf-sys.h
+++ b/tools/perf/perf-sys.h
@@ -5,6 +5,7 @@
5#include <sys/types.h> 5#include <sys/types.h>
6#include <sys/syscall.h> 6#include <sys/syscall.h>
7#include <linux/types.h> 7#include <linux/types.h>
8#include <linux/compiler.h>
8#include <linux/perf_event.h> 9#include <linux/perf_event.h>
9#include <asm/barrier.h> 10#include <asm/barrier.h>
10 11
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 4158422cc2a6..cb20ae1c0d35 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -40,6 +40,7 @@ perf-y += event_update.o
40perf-y += event-times.o 40perf-y += event-times.o
41perf-y += backward-ring-buffer.o 41perf-y += backward-ring-buffer.o
42perf-y += sdt.o 42perf-y += sdt.o
43perf-y += is_printable_array.o
43 44
44$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build 45$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
45 $(call rule_mkdir) 46 $(call rule_mkdir)
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 4dd2d050788a..10eb30686c9c 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -222,6 +222,10 @@ static struct test generic_tests[] = {
222 .func = test__sdt_event, 222 .func = test__sdt_event,
223 }, 223 },
224 { 224 {
225 .desc = "Test is_printable_array function",
226 .func = test__is_printable_array,
227 },
228 {
225 .func = NULL, 229 .func = NULL,
226 }, 230 },
227}; 231};
diff --git a/tools/perf/tests/is_printable_array.c b/tools/perf/tests/is_printable_array.c
new file mode 100644
index 000000000000..42e13393e502
--- /dev/null
+++ b/tools/perf/tests/is_printable_array.c
@@ -0,0 +1,36 @@
1#include <linux/compiler.h>
2#include "tests.h"
3#include "debug.h"
4#include "util.h"
5
6int test__is_printable_array(int subtest __maybe_unused)
7{
8 char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 };
9 char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 };
10 struct {
11 char *buf;
12 unsigned int len;
13 int ret;
14 } t[] = {
15 { (char *) "krava", sizeof("krava"), 1 },
16 { (char *) "krava", sizeof("krava") - 1, 0 },
17 { (char *) "", sizeof(""), 1 },
18 { (char *) "", 0, 0 },
19 { NULL, 0, 0 },
20 { buf1, sizeof(buf1), 0 },
21 { buf2, sizeof(buf2), 0 },
22 };
23 unsigned int i;
24
25 for (i = 0; i < ARRAY_SIZE(t); i++) {
26 int ret;
27
28 ret = is_printable_array((char *) t[i].buf, t[i].len);
29 if (ret != t[i].ret) {
30 pr_err("failed: test %u\n", i);
31 return TEST_FAIL;
32 }
33 }
34
35 return TEST_OK;
36}
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index a0288f8092b2..9bfc0e06c61a 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -89,6 +89,7 @@ int test__event_times(int subtest);
89int test__backward_ring_buffer(int subtest); 89int test__backward_ring_buffer(int subtest);
90int test__cpu_map_print(int subtest); 90int test__cpu_map_print(int subtest);
91int test__sdt_event(int subtest); 91int test__sdt_event(int subtest);
92int test__is_printable_array(int subtest);
92 93
93#if defined(__arm__) || defined(__aarch64__) 94#if defined(__arm__) || defined(__aarch64__)
94#ifdef HAVE_DWARF_UNWIND_SUPPORT 95#ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/cpumap.c b/tools/perf/util/cpumap.c
index 15f83acac1b8..2c0b52264a46 100644
--- a/tools/perf/util/cpumap.c
+++ b/tools/perf/util/cpumap.c
@@ -589,14 +589,24 @@ int cpu__setup_cpunode_map(void)
589 589
590bool cpu_map__has(struct cpu_map *cpus, int cpu) 590bool cpu_map__has(struct cpu_map *cpus, int cpu)
591{ 591{
592 return cpu_map__idx(cpus, cpu) != -1;
593}
594
595int cpu_map__idx(struct cpu_map *cpus, int cpu)
596{
592 int i; 597 int i;
593 598
594 for (i = 0; i < cpus->nr; ++i) { 599 for (i = 0; i < cpus->nr; ++i) {
595 if (cpus->map[i] == cpu) 600 if (cpus->map[i] == cpu)
596 return true; 601 return i;
597 } 602 }
598 603
599 return false; 604 return -1;
605}
606
607int cpu_map__cpu(struct cpu_map *cpus, int idx)
608{
609 return cpus->map[idx];
600} 610}
601 611
602size_t cpu_map__snprint(struct cpu_map *map, char *buf, size_t size) 612size_t cpu_map__snprint(struct cpu_map *map, char *buf, size_t size)
diff --git a/tools/perf/util/cpumap.h b/tools/perf/util/cpumap.h
index 206dc550354a..06bd689f5989 100644
--- a/tools/perf/util/cpumap.h
+++ b/tools/perf/util/cpumap.h
@@ -68,5 +68,7 @@ int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,
68 int (*f)(struct cpu_map *map, int cpu, void *data), 68 int (*f)(struct cpu_map *map, int cpu, void *data),
69 void *data); 69 void *data);
70 70
71int cpu_map__cpu(struct cpu_map *cpus, int idx);
71bool cpu_map__has(struct cpu_map *cpus, int cpu); 72bool cpu_map__has(struct cpu_map *cpus, int cpu);
73int cpu_map__idx(struct cpu_map *cpus, int cpu);
72#endif /* __PERF_CPUMAP_H */ 74#endif /* __PERF_CPUMAP_H */
diff --git a/tools/perf/util/include/asm/byteorder.h b/tools/perf/util/include/asm/byteorder.h
deleted file mode 100644
index 2a9bdc066307..000000000000
--- a/tools/perf/util/include/asm/byteorder.h
+++ /dev/null
@@ -1,2 +0,0 @@
1#include <asm/types.h>
2#include "../../../../include/uapi/linux/swab.h"
diff --git a/tools/perf/util/include/linux/const.h b/tools/perf/util/include/linux/const.h
deleted file mode 100644
index c10a35e1afb8..000000000000
--- a/tools/perf/util/include/linux/const.h
+++ /dev/null
@@ -1 +0,0 @@
1#include "../../../../include/uapi/linux/const.h"
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index b39b12a1208d..728129ac653a 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -312,6 +312,9 @@ int map__load(struct map *map, symbol_filter_t filter)
312 pr_warning("%.*s was updated (is prelink enabled?). " 312 pr_warning("%.*s was updated (is prelink enabled?). "
313 "Restart the long running apps that use it!\n", 313 "Restart the long running apps that use it!\n",
314 (int)real_len, name); 314 (int)real_len, name);
315 } else if (filter) {
316 pr_warning("no symbols passed the given filter.\n");
317 return -2; /* Empty but maybe by the filter */
315 } else { 318 } else {
316 pr_warning("no symbols found in %s, maybe install " 319 pr_warning("no symbols found in %s, maybe install "
317 "a debug package?\n", name); 320 "a debug package?\n", name);
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index d4f8835c0a27..953dc1ab2ed7 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -3312,8 +3312,16 @@ int show_available_funcs(const char *target, struct strfilter *_filter,
3312 3312
3313 /* Load symbols with given filter */ 3313 /* Load symbols with given filter */
3314 available_func_filter = _filter; 3314 available_func_filter = _filter;
3315 if (map__load(map, filter_available_functions)) { 3315 ret = map__load(map, filter_available_functions);
3316 pr_err("Failed to load symbols in %s\n", (target) ? : "kernel"); 3316 if (ret) {
3317 if (ret == -2) {
3318 char *str = strfilter__string(_filter);
3319 pr_err("Failed to find symbols matched to \"%s\"\n",
3320 str);
3321 free(str);
3322 } else
3323 pr_err("Failed to load symbols in %s\n",
3324 (target) ? : "kernel");
3317 goto end; 3325 goto end;
3318 } 3326 }
3319 if (!dso__sorted_by_name(map->dso, map->type)) 3327 if (!dso__sorted_by_name(map->dso, map->type))
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index d32f97033718..a5fbc012e3df 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -295,18 +295,6 @@ static bool is_tracepoint(struct pyrf_event *pevent)
295 return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT; 295 return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT;
296} 296}
297 297
298static int is_printable_array(char *p, unsigned int len)
299{
300 unsigned int i;
301
302 for (i = 0; i < len; i++) {
303 if (!isprint(p[i]) && !isspace(p[i]))
304 return 0;
305 }
306
307 return 1;
308}
309
310static PyObject* 298static PyObject*
311tracepoint_field(struct pyrf_event *pe, struct format_field *field) 299tracepoint_field(struct pyrf_event *pe, struct format_field *field)
312{ 300{
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 6ac6b7a33f42..e0203b979474 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -386,7 +386,6 @@ exit:
386 return pylist; 386 return pylist;
387} 387}
388 388
389
390static void python_process_tracepoint(struct perf_sample *sample, 389static void python_process_tracepoint(struct perf_sample *sample,
391 struct perf_evsel *evsel, 390 struct perf_evsel *evsel,
392 struct addr_location *al) 391 struct addr_location *al)
@@ -457,14 +456,26 @@ static void python_process_tracepoint(struct perf_sample *sample,
457 pydict_set_item_string_decref(dict, "common_callchain", callchain); 456 pydict_set_item_string_decref(dict, "common_callchain", callchain);
458 } 457 }
459 for (field = event->format.fields; field; field = field->next) { 458 for (field = event->format.fields; field; field = field->next) {
460 if (field->flags & FIELD_IS_STRING) { 459 unsigned int offset, len;
461 int offset; 460 unsigned long long val;
461
462 if (field->flags & FIELD_IS_ARRAY) {
463 offset = field->offset;
464 len = field->size;
462 if (field->flags & FIELD_IS_DYNAMIC) { 465 if (field->flags & FIELD_IS_DYNAMIC) {
463 offset = *(int *)(data + field->offset); 466 val = pevent_read_number(scripting_context->pevent,
467 data + offset, len);
468 offset = val;
469 len = offset >> 16;
464 offset &= 0xffff; 470 offset &= 0xffff;
465 } else 471 }
466 offset = field->offset; 472 if (field->flags & FIELD_IS_STRING &&
467 obj = PyString_FromString((char *)data + offset); 473 is_printable_array(data + offset, len)) {
474 obj = PyString_FromString((char *) data + offset);
475 } else {
476 obj = PyByteArray_FromStringAndSize((const char *) data + offset, len);
477 field->flags &= ~FIELD_IS_STRING;
478 }
468 } else { /* FIELD_IS_NUMERIC */ 479 } else { /* FIELD_IS_NUMERIC */
469 obj = get_field_numeric_entry(event, field, data); 480 obj = get_field_numeric_entry(event, field, data);
470 } 481 }
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index 5f44a21955cd..cee559d8c9e8 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -746,3 +746,19 @@ void print_binary(unsigned char *data, size_t len,
746 } 746 }
747 printer(BINARY_PRINT_DATA_END, -1, extra); 747 printer(BINARY_PRINT_DATA_END, -1, extra);
748} 748}
749
750int is_printable_array(char *p, unsigned int len)
751{
752 unsigned int i;
753
754 if (!p || !len || p[len - 1] != 0)
755 return 0;
756
757 len--;
758
759 for (i = 0; i < len; i++) {
760 if (!isprint(p[i]) && !isspace(p[i]))
761 return 0;
762 }
763 return 1;
764}
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 843cbba8f9d3..e5f55477491d 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -364,4 +364,5 @@ void print_binary(unsigned char *data, size_t len,
364extern int sched_getcpu(void); 364extern int sched_getcpu(void);
365#endif 365#endif
366 366
367int is_printable_array(char *p, unsigned int len);
367#endif /* GIT_COMPAT_UTIL_H */ 368#endif /* GIT_COMPAT_UTIL_H */