Skip to contentSkip to conversation

perf python: Add support to access tracepoint fields

PATCH In review Jiri Olsa 5 participants 12 messages Jul 16, 2016 – Jul 19, 2016 perf events

lore
Share & tools
lore

Jiri Olsa

author reviewer
#0 lore raw

v3 cover perf python: Add support to access tracepoint fields

hi,
adding support to access tracepoint fields in python scripts.

v3 changes:
- once again fixed is_printable_array [Steven]
- patch 3/3 already merged
- added new patch 3/3 with automated test for is_printable_array

v2 changes:
- most of the patches is already pulled in,
this is just leftover
- fixed is_printable_array [Steven]
- making is_printable_array global
- attached unrelated fix 3/3

With this patchset it's possible to access tracepoint fields in event python object like:

print "time %u prev_comm=%s prev_pid=%d prev_prio=%d prev_state=0x%x ==> next_comm=%s next_pid=%d next_prio=%d" % (
event.sample_time,
event.prev_comm,
event.prev_pid,
event.prev_prio,
event.prev_state,
event.next_comm,
event.next_pid,
event.next_prio)

Also available in:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
perf/fixes

thanks,
jirka

---
Jiri Olsa (3):
perf script python: Fix string vs byte array resolving perf tools: Make is_printable_array global perf tests: Add is_printable_array test

 tools/perf/tests/Build                                 |  1 +
 tools/perf/tests/builtin-test.c                        |  4 ++++
 tools/perf/tests/is_printable_array.c                  | 36 ++++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h                               |  1 +
 tools/perf/util/python.c                               | 12 ------------
 tools/perf/util/scripting-engines/trace-event-python.c | 25 ++++++++++++++++++-------
 tools/perf/util/util.c                                 | 16 ++++++++++++++++
 tools/perf/util/util.h                                 |  1 +
 8 files changed, 77 insertions(+), 19 deletions(-)
 create mode 100644 tools/perf/tests/is_printable_array.c
author reviewer
#1 lore raw

PATCH v3 1/3 perf script python: Fix string vs byte array resolving

Jirka reported that python code returns all arrays as strings. This makes impossible to get all items for byte array tracepoint field containing 0x00 value item.

Fixing this by scanning full length of the array and returning it as PyByteArray object in case non printable byte is found.

---
 .../util/scripting-engines/trace-event-python.c    | 39 ++++++++++++++++++----
 1 file changed, 33 insertions(+), 6 deletions(-)
tools/perf/util/scripting-engines/trace-event-python.c +33 -6
index 6ac6b7a33f42..7bd6da80533e 100644
@@ -386,6 +386,21 @@ exit:
 	return pylist;
 }
 
+static int is_printable_array(char *p, unsigned int len)
+{
+	unsigned int i;
+
+	if (!p || !len || p[len - 1] != 0)
+		return 0;
+
+	len--;
+
+	for (i = 0; i < len; i++) {
+		if (!isprint(p[i]) && !isspace(p[i]))
+			return 0;
+	}
+	return 1;
+}
 
 static void python_process_tracepoint(struct perf_sample *sample,
 				      struct perf_evsel *evsel,
@@ -457,14 +472,26 @@ static void python_process_tracepoint(struct perf_sample *sample,
 		pydict_set_item_string_decref(dict, "common_callchain", callchain);
 	}
 	for (field = event->format.fields; field; field = field->next) {
-		if (field->flags & FIELD_IS_STRING) {
-			int offset;
+		unsigned int offset, len;
+		unsigned long long val;
+
+		if (field->flags & FIELD_IS_ARRAY) {
+			offset = field->offset;
+			len    = field->size;
 			if (field->flags & FIELD_IS_DYNAMIC) {
-				offset = *(int *)(data + field->offset);
+				val     = pevent_read_number(scripting_context->pevent,
+							     data + offset, len);
+				offset  = val;
+				len     = offset >> 16;
 				offset &= 0xffff;
-			} else
-				offset = field->offset;
-			obj = PyString_FromString((char *)data + offset);
+			}
+			if (field->flags & FIELD_IS_STRING &&
+			    is_printable_array(data + offset, len)) {
+				obj = PyString_FromString((char *) data + offset);
+			} else {
+				obj = PyByteArray_FromStringAndSize((const char *) data + offset, len);
+				field->flags &= ~FIELD_IS_STRING;
+			}
 		} else { /* FIELD_IS_NUMERIC */
 			obj = get_field_numeric_entry(event, field, data);
 		}
Signature · 1 line
2.4.11
Tested-by on v3 1/3
#2 lore raw

Re: [PATCH 1/3] perf script python: Fix string vs byte array resolving

Quoted 9 lines · Sat, Jul 16, 2016 at 06:11:18PM CEST, [email protected] wrote:

Jirka reported that python code returns all arrays as strings. This makes impossible to get all items for byte array tracepoint field containing 0x00 value item.

Fixing this by scanning full length of the array and returning it as PyByteArray object in case non printable byte is found.

Quoted 66 lines

---
.../util/scripting-engines/trace-event-python.c | 39 ++++++++++++++++++----

1 file changed, 33 insertions(+), 6 deletions(-)
tools/perf/util/scripting-engines/trace-event-python.c +33 -6
index 6ac6b7a33f42..7bd6da80533e 100644
@@ -386,6 +386,21 @@ exit:
 	return pylist;
 }
 
+static int is_printable_array(char *p, unsigned int len)
+{
+	unsigned int i;
+
+	if (!p || !len || p[len - 1] != 0)
+		return 0;
+
+	len--;
+
+	for (i = 0; i < len; i++) {
+		if (!isprint(p[i]) && !isspace(p[i]))
+			return 0;
+	}
+	return 1;
+}
 
 static void python_process_tracepoint(struct perf_sample *sample,
 				      struct perf_evsel *evsel,
@@ -457,14 +472,26 @@ static void python_process_tracepoint(struct perf_sample *sample,
 		pydict_set_item_string_decref(dict, "common_callchain", callchain);
 	}
 	for (field = event->format.fields; field; field = field->next) {
-		if (field->flags & FIELD_IS_STRING) {
-			int offset;
+		unsigned int offset, len;
+		unsigned long long val;
+
+		if (field->flags & FIELD_IS_ARRAY) {
+			offset = field->offset;
+			len    = field->size;
 			if (field->flags & FIELD_IS_DYNAMIC) {
-				offset = *(int *)(data + field->offset);
+				val     = pevent_read_number(scripting_context->pevent,
+							     data + offset, len);
+				offset  = val;
+				len     = offset >> 16;
 				offset &= 0xffff;
-			} else
-				offset = field->offset;
-			obj = PyString_FromString((char *)data + offset);
+			}
+			if (field->flags & FIELD_IS_STRING &&
+			    is_printable_array(data + offset, len)) {
+				obj = PyString_FromString((char *) data + offset);
+			} else {
+				obj = PyByteArray_FromStringAndSize((const char *) data + offset, len);
+				field->flags &= ~FIELD_IS_STRING;
+			}
 		} else { /* FIELD_IS_NUMERIC */
 			obj = get_field_numeric_entry(event, field, data);
 		}
Signature · 1 line
2.4.11
#3 lore raw

[tip:perf/core] perf script python: Fix string vs byte array resolving

In reply to Jiri Olsa
perf script python: Fix string vs byte array resolving
Commit-ID:  249de6e074580988d3ee4902236803098e2cda4c
Gitweb:     http://git.kernel.org/tip/249de6e074580988d3ee4902236803098e2cda4c
Author:     Jiri Olsa <[email protected]>
AuthorDate: Sat, 16 Jul 2016 18:11:18 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 18 Jul 2016 19:48:04 -0300

perf script python: Fix string vs byte array resolving

Jirka reported that python code returns all arrays as strings. This makes impossible to get all items for byte array tracepoint field containing 0x00 value item.

Fixing this by scanning full length of the array and returning it as PyByteArray object in case non printable byte is found.

---
 .../util/scripting-engines/trace-event-python.c    | 39 ++++++++++++++++++----
 1 file changed, 33 insertions(+), 6 deletions(-)
tools/perf/util/scripting-engines/trace-event-python.c +33 -6
index 6ac6b7a..7bd6da8 100644
@@ -386,6 +386,21 @@ exit:
 	return pylist;
 }
 
+static int is_printable_array(char *p, unsigned int len)
+{
+	unsigned int i;
+
+	if (!p || !len || p[len - 1] != 0)
+		return 0;
+
+	len--;
+
+	for (i = 0; i < len; i++) {
+		if (!isprint(p[i]) && !isspace(p[i]))
+			return 0;
+	}
+	return 1;
+}
 
 static void python_process_tracepoint(struct perf_sample *sample,
 				      struct perf_evsel *evsel,
@@ -457,14 +472,26 @@ static void python_process_tracepoint(struct perf_sample *sample,
 		pydict_set_item_string_decref(dict, "common_callchain", callchain);
 	}
 	for (field = event->format.fields; field; field = field->next) {
-		if (field->flags & FIELD_IS_STRING) {
-			int offset;
+		unsigned int offset, len;
+		unsigned long long val;
+
+		if (field->flags & FIELD_IS_ARRAY) {
+			offset = field->offset;
+			len    = field->size;
 			if (field->flags & FIELD_IS_DYNAMIC) {
-				offset = *(int *)(data + field->offset);
+				val     = pevent_read_number(scripting_context->pevent,
+							     data + offset, len);
+				offset  = val;
+				len     = offset >> 16;
 				offset &= 0xffff;
-			} else
-				offset = field->offset;
-			obj = PyString_FromString((char *)data + offset);
+			}
+			if (field->flags & FIELD_IS_STRING &&
+			    is_printable_array(data + offset, len)) {
+				obj = PyString_FromString((char *) data + offset);
+			} else {
+				obj = PyByteArray_FromStringAndSize((const char *) data + offset, len);
+				field->flags &= ~FIELD_IS_STRING;
+			}
 		} else { /* FIELD_IS_NUMERIC */
 			obj = get_field_numeric_entry(event, field, data);
 		}
author reviewer
#4 lore raw

PATCH v3 2/3 perf tools: Make is_printable_array global

In reply to Jiri Olsa

It's used from 2 objects in perf, so it's better
to keep just one copy.

---
 tools/perf/util/python.c                               | 12 ------------
 tools/perf/util/scripting-engines/trace-event-python.c | 16 ----------------
 tools/perf/util/util.c                                 | 16 ++++++++++++++++
 tools/perf/util/util.h                                 |  1 +
 4 files changed, 17 insertions(+), 28 deletions(-)
tools/perf/util/python.c +0 -12
index d32f97033718..a5fbc012e3df 100644
@@ -295,18 +295,6 @@ static bool is_tracepoint(struct pyrf_event *pevent)
 	return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT;
 }
 
-static int is_printable_array(char *p, unsigned int len)
-{
-	unsigned int i;
-
-	for (i = 0; i < len; i++) {
-		if (!isprint(p[i]) && !isspace(p[i]))
-			return 0;
-	}
-
-	return 1;
-}
-
 static PyObject*
 tracepoint_field(struct pyrf_event *pe, struct format_field *field)
 {
tools/perf/util/scripting-engines/trace-event-python.c +0 -16
index 7bd6da80533e..e0203b979474 100644
@@ -386,22 +386,6 @@ exit:
 	return pylist;
 }
 
-static int is_printable_array(char *p, unsigned int len)
-{
-	unsigned int i;
-
-	if (!p || !len || p[len - 1] != 0)
-		return 0;
-
-	len--;
-
-	for (i = 0; i < len; i++) {
-		if (!isprint(p[i]) && !isspace(p[i]))
-			return 0;
-	}
-	return 1;
-}
-
 static void python_process_tracepoint(struct perf_sample *sample,
 				      struct perf_evsel *evsel,
 				      struct addr_location *al)
tools/perf/util/util.c +16 -0
index 5f44a21955cd..cee559d8c9e8 100644
@@ -746,3 +746,19 @@ void print_binary(unsigned char *data, size_t len,
 	}
 	printer(BINARY_PRINT_DATA_END, -1, extra);
 }
+
+int is_printable_array(char *p, unsigned int len)
+{
+	unsigned int i;
+
+	if (!p || !len || p[len - 1] != 0)
+		return 0;
+
+	len--;
+
+	for (i = 0; i < len; i++) {
+		if (!isprint(p[i]) && !isspace(p[i]))
+			return 0;
+	}
+	return 1;
+}
tools/perf/util/util.h +1 -0
index 843cbba8f9d3..e5f55477491d 100644
@@ -364,4 +364,5 @@ void print_binary(unsigned char *data, size_t len,
 extern int sched_getcpu(void);
 #endif
 
+int is_printable_array(char *p, unsigned int len);
 #endif /* GIT_COMPAT_UTIL_H */
Signature · 1 line
2.4.11
#6 lore raw

[tip:perf/core] perf tools: Make is_printable_array global

In reply to Jiri Olsa
perf tools: Make is_printable_array global
Commit-ID:  accaed2659530b4047678070cb23fd1d9a1c1a59
Gitweb:     http://git.kernel.org/tip/accaed2659530b4047678070cb23fd1d9a1c1a59
Author:     Jiri Olsa <[email protected]>
AuthorDate: Sat, 16 Jul 2016 18:11:19 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 18 Jul 2016 19:49:47 -0300

perf tools: Make is_printable_array global

It's used from 2 objects in perf, so it's better to keep just one copy.

---
 tools/perf/util/python.c                               | 12 ------------
 tools/perf/util/scripting-engines/trace-event-python.c | 16 ----------------
 tools/perf/util/util.c                                 | 16 ++++++++++++++++
 tools/perf/util/util.h                                 |  1 +
 4 files changed, 17 insertions(+), 28 deletions(-)
tools/perf/util/python.c +0 -12
index d32f970..a5fbc01 100644
@@ -295,18 +295,6 @@ static bool is_tracepoint(struct pyrf_event *pevent)
 	return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT;
 }
 
-static int is_printable_array(char *p, unsigned int len)
-{
-	unsigned int i;
-
-	for (i = 0; i < len; i++) {
-		if (!isprint(p[i]) && !isspace(p[i]))
-			return 0;
-	}
-
-	return 1;
-}
-
 static PyObject*
 tracepoint_field(struct pyrf_event *pe, struct format_field *field)
 {
tools/perf/util/scripting-engines/trace-event-python.c +0 -16
index 7bd6da8..e0203b9 100644
@@ -386,22 +386,6 @@ exit:
 	return pylist;
 }
 
-static int is_printable_array(char *p, unsigned int len)
-{
-	unsigned int i;
-
-	if (!p || !len || p[len - 1] != 0)
-		return 0;
-
-	len--;
-
-	for (i = 0; i < len; i++) {
-		if (!isprint(p[i]) && !isspace(p[i]))
-			return 0;
-	}
-	return 1;
-}
-
 static void python_process_tracepoint(struct perf_sample *sample,
 				      struct perf_evsel *evsel,
 				      struct addr_location *al)
tools/perf/util/util.c +16 -0
index 5f44a21..cee559d 100644
@@ -746,3 +746,19 @@ void print_binary(unsigned char *data, size_t len,
 	}
 	printer(BINARY_PRINT_DATA_END, -1, extra);
 }
+
+int is_printable_array(char *p, unsigned int len)
+{
+	unsigned int i;
+
+	if (!p || !len || p[len - 1] != 0)
+		return 0;
+
+	len--;
+
+	for (i = 0; i < len; i++) {
+		if (!isprint(p[i]) && !isspace(p[i]))
+			return 0;
+	}
+	return 1;
+}
tools/perf/util/util.h +1 -0
index 843cbba..e5f5547 100644
@@ -364,4 +364,5 @@ void print_binary(unsigned char *data, size_t len,
 extern int sched_getcpu(void);
 #endif
 
+int is_printable_array(char *p, unsigned int len);
 #endif /* GIT_COMPAT_UTIL_H */
author reviewer
#7 lore raw

PATCH v3 3/3 perf tests: Add is_printable_array test

In reply to Jiri Olsa

Add automated test for is_printable_array function.

---
 tools/perf/tests/Build                |  1 +
 tools/perf/tests/builtin-test.c       |  4 ++++
 tools/perf/tests/is_printable_array.c | 36 +++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h              |  1 +
 4 files changed, 42 insertions(+)
 create mode 100644 tools/perf/tests/is_printable_array.c
tools/perf/tests/Build +1 -0
index 4158422cc2a6..cb20ae1c0d35 100644
@@ -40,6 +40,7 @@ perf-y += event_update.o
 perf-y += event-times.o
 perf-y += backward-ring-buffer.o
 perf-y += sdt.o
+perf-y += is_printable_array.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
 	$(call rule_mkdir)
tools/perf/tests/builtin-test.c +4 -0
index 4dd2d050788a..10eb30686c9c 100644
@@ -222,6 +222,10 @@ static struct test generic_tests[] = {
 		.func = test__sdt_event,
 	},
 	{
+		.desc = "Test is_printable_array function",
+		.func = test__is_printable_array,
+	},
+	{
 		.func = NULL,
 	},
 };
tools/perf/tests/is_printable_array.c new file +36 -0
new file mode 100644
index 000000000000..42e13393e502
@@ -0,0 +1,36 @@
+#include <linux/compiler.h>
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+
+int test__is_printable_array(int subtest __maybe_unused)
+{
+	char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 };
+	char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 };
+	struct {
+		char		*buf;
+		unsigned int	 len;
+		int		 ret;
+	} t[] = {
+		{ (char *) "krava",	sizeof("krava"),	1 },
+		{ (char *) "krava",	sizeof("krava") - 1,	0 },
+		{ (char *) "",		sizeof(""),		1 },
+		{ (char *) "",		0,			0 },
+		{ NULL,			0,			0 },
+		{ buf1,			sizeof(buf1),		0 },
+		{ buf2,			sizeof(buf2),		0 },
+	};
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(t); i++) {
+		int ret;
+
+		ret = is_printable_array((char *) t[i].buf, t[i].len);
+		if (ret != t[i].ret) {
+			pr_err("failed: test %u\n", i);
+			return TEST_FAIL;
+		}
+	}
+
+	return TEST_OK;
+}
tools/perf/tests/tests.h +1 -0
index a0288f8092b2..9bfc0e06c61a 100644
@@ -89,6 +89,7 @@ int test__event_times(int subtest);
 int test__backward_ring_buffer(int subtest);
 int test__cpu_map_print(int subtest);
 int test__sdt_event(int subtest);
+int test__is_printable_array(int subtest);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT
Signature · 1 line
2.4.11
#8 lore raw

Re: [PATCH 3/3] perf tests: Add is_printable_array test

Quoted 51 lines · Sat, Jul 16, 2016 at 06:11:20PM CEST, [email protected] wrote:

Add automated test for is_printable_array function.

---

tools/perf/tests/Build                |  1 +
tools/perf/tests/builtin-test.c       |  4 ++++
tools/perf/tests/is_printable_array.c | 36 +++++++++++++++++++++++++++++++++++
tools/perf/tests/tests.h              |  1 +
4 files changed, 42 insertions(+)

create mode 100644 tools/perf/tests/is_printable_array.c

tools/perf/tests/Build +0 -0
index 4158422cc2a6..cb20ae1c0d35 100644
@@ -40,6 +40,7 @@ perf-y += event_update.o

perf-y += event-times.o
perf-y += backward-ring-buffer.o
perf-y += sdt.o
+perf-y += is_printable_array.o

$(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build

	$(call rule_mkdir)
tools/perf/tests/builtin-test.c +4 -0
index 4dd2d050788a..10eb30686c9c 100644
@@ -222,6 +222,10 @@ static struct test generic_tests[] = {
 		.func = test__sdt_event,
 	},
 	{
+		.desc = "Test is_printable_array function",
+		.func = test__is_printable_array,
+	},
+	{
 		.func = NULL,
 	},
 };
tools/perf/tests/is_printable_array.c new file +6 -0
new file mode 100644
index 000000000000..42e13393e502
@@ -0,0 +1,36 @@
+#include <linux/compiler.h>
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+
+int test__is_printable_array(int subtest __maybe_unused)

tools/perf/tests/is_printable_array.c line 16

Quoted 10 lines
tools/perf/tests/is_printable_array.c new file +10 -0
+{
+	char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 };
+	char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 };
+	struct {
+		char		*buf;
+		unsigned int	 len;
+		int		 ret;
+	} t[] = {
+		{ (char *) "krava",	sizeof("krava"),	1 },
+		{ (char *) "krava",	sizeof("krava") - 1,	0 },

"a cow" ? Really? :))

#9 lore raw

Re: [PATCH 3/3] perf tests: Add is_printable_array test

On Mon, Jul 18, 2016 at 01:46:02PM +0200, Jiri Pirko wrote:

SNIP

Quoted 16 lines
Quoted 16 lines
tools/perf/tests/is_printable_array.c new file +10 -0
new file mode 100644
index 000000000000..42e13393e502
@@ -0,0 +1,36 @@
+#include <linux/compiler.h>
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+
+int test__is_printable_array(int subtest __maybe_unused)
+{
+	char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 };
+	char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 };
+	struct {
Quoted 8 lines

tools/perf/tests/is_printable_array.c line 16

Quoted 6 lines
tools/perf/tests/is_printable_array.c new file +6 -0
+		char		*buf;
+		unsigned int	 len;
+		int		 ret;
+	} t[] = {
+		{ (char *) "krava",	sizeof("krava"),	1 },
+		{ (char *) "krava",	sizeof("krava") - 1,	0 },

"a cow" ? Really? :))

yea, trying to force it as 'perf animal' instead of that pony stuff ;-)

http://www.brendangregg.com/blog/2015-07-08/choosing-a-linux-tracer.html

jirka

#10 lore raw

Re: [PATCH 3/3] perf tests: Add is_printable_array test

Em Mon, Jul 18, 2016 at 02:14:09PM +0200, Jiri Olsa escreveu:

Quoted 29 lines · Jiri Pirko

SNIP

Quoted 16 lines
Quoted 16 lines
tools/perf/tests/is_printable_array.c new file +10 -0
new file mode 100644
index 000000000000..42e13393e502
@@ -0,0 +1,36 @@
+#include <linux/compiler.h>
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+
+int test__is_printable_array(int subtest __maybe_unused)
+{
+	char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 };
+	char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 };
+	struct {
Quoted 8 lines

tools/perf/tests/is_printable_array.c line 16

Quoted 6 lines
tools/perf/tests/is_printable_array.c new file +6 -0
+		char		*buf;
+		unsigned int	 len;
+		int		 ret;
+	} t[] = {
+		{ (char *) "krava",	sizeof("krava"),	1 },
+		{ (char *) "krava",	sizeof("krava") - 1,	0 },

"a cow" ? Really? :))

Quoted 3 lines

yea, trying to force it as 'perf animal' instead of that pony stuff ;-)

http://www.brendangregg.com/blog/2015-07-08/choosing-a-linux-tracer.html

Yeah, a vaca! 8-)

- ARnaldo

#11 lore raw

[tip:perf/core] perf tests: Add is_printable_array test

In reply to Jiri Olsa
perf tests: Add is_printable_array test
Commit-ID:  988dd774dcbd9151c2a643fc7284c5c3c4d0adb7
Gitweb:     http://git.kernel.org/tip/988dd774dcbd9151c2a643fc7284c5c3c4d0adb7
Author:     Jiri Olsa <[email protected]>
AuthorDate: Sat, 16 Jul 2016 18:11:20 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Mon, 18 Jul 2016 19:50:35 -0300

perf tests: Add is_printable_array test

Add automated test for is_printable_array function.

---
 tools/perf/tests/Build                |  1 +
 tools/perf/tests/builtin-test.c       |  4 ++++
 tools/perf/tests/is_printable_array.c | 36 +++++++++++++++++++++++++++++++++++
 tools/perf/tests/tests.h              |  1 +
 4 files changed, 42 insertions(+)
tools/perf/tests/Build +1 -0
index 4158422..cb20ae1 100644
@@ -40,6 +40,7 @@ perf-y += event_update.o
 perf-y += event-times.o
 perf-y += backward-ring-buffer.o
 perf-y += sdt.o
+perf-y += is_printable_array.o
 
 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build
 	$(call rule_mkdir)
tools/perf/tests/builtin-test.c +4 -0
index 4dd2d05..10eb306 100644
@@ -222,6 +222,10 @@ static struct test generic_tests[] = {
 		.func = test__sdt_event,
 	},
 	{
+		.desc = "Test is_printable_array function",
+		.func = test__is_printable_array,
+	},
+	{
 		.func = NULL,
 	},
 };
tools/perf/tests/is_printable_array.c new file +36 -0
new file mode 100644
index 0000000..42e1339
@@ -0,0 +1,36 @@
+#include <linux/compiler.h>
+#include "tests.h"
+#include "debug.h"
+#include "util.h"
+
+int test__is_printable_array(int subtest __maybe_unused)
+{
+	char buf1[] = { 'k', 'r', 4, 'v', 'a', 0 };
+	char buf2[] = { 'k', 'r', 'a', 'v', 4, 0 };
+	struct {
+		char		*buf;
+		unsigned int	 len;
+		int		 ret;
+	} t[] = {
+		{ (char *) "krava",	sizeof("krava"),	1 },
+		{ (char *) "krava",	sizeof("krava") - 1,	0 },
+		{ (char *) "",		sizeof(""),		1 },
+		{ (char *) "",		0,			0 },
+		{ NULL,			0,			0 },
+		{ buf1,			sizeof(buf1),		0 },
+		{ buf2,			sizeof(buf2),		0 },
+	};
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(t); i++) {
+		int ret;
+
+		ret = is_printable_array((char *) t[i].buf, t[i].len);
+		if (ret != t[i].ret) {
+			pr_err("failed: test %u\n", i);
+			return TEST_FAIL;
+		}
+	}
+
+	return TEST_OK;
+}
tools/perf/tests/tests.h +1 -0
index a0288f8..9bfc0e0 100644
@@ -89,6 +89,7 @@ int test__event_times(int subtest);
 int test__backward_ring_buffer(int subtest);
 int test__cpu_map_print(int subtest);
 int test__sdt_event(int subtest);
+int test__is_printable_array(int subtest);
 
 #if defined(__arm__) || defined(__aarch64__)
 #ifdef HAVE_DWARF_UNWIND_SUPPORT