Skip to content

Commit

Permalink
perf script python: Fix string vs byte array resolving
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jiri Olsa authored and Arnaldo Carvalho de Melo committed Jul 18, 2016
1 parent e704934 commit 249de6e
Showing 1 changed file with 33 additions and 6 deletions.
39 changes: 33 additions & 6 deletions tools/perf/util/scripting-engines/trace-event-python.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,21 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
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,
Expand Down Expand Up @@ -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);
}
Expand Down

0 comments on commit 249de6e

Please sign in to comment.