summaryrefslogtreecommitdiffstats
path: root/tools/perf/util/scripting-engines
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2016-07-16 18:11:18 +0200
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-07-19 00:48:04 +0200
commit249de6e074580988d3ee4902236803098e2cda4c (patch)
tree05febc54f0086c078d723c719eb65bbecf3303a2 /tools/perf/util/scripting-engines
parentperf probe: Warn unmatched function filter correctly (diff)
downloadlinux-249de6e074580988d3ee4902236803098e2cda4c.tar.xz
linux-249de6e074580988d3ee4902236803098e2cda4c.zip
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. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Reported-and-Tested-by: Jiri Pirko <jiri@mellanox.com> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Steven Rostedt <rostedt@goodmis.org> Link: http://lkml.kernel.org/r/1468685480-18951-2-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/scripting-engines')
-rw-r--r--tools/perf/util/scripting-engines/trace-event-python.c39
1 files changed, 33 insertions, 6 deletions
diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c
index 6ac6b7a33f42..7bd6da80533e 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -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);
}