diff options
author | Josef Bacik <jbacik@fb.com> | 2014-09-25 13:43:57 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2015-06-10 15:11:26 -0400 |
commit | 5e814403f528bed7c7a549651a38d12dbf76ae4b (patch) | |
tree | dd50a352452241a736e859dc780badf6e7cd8ddd | |
parent | f267243158b247fa7400744fd9b5c8a9bd94d085 (diff) | |
download | trace-cmd-5e814403f528bed7c7a549651a38d12dbf76ae4b.tar.gz |
trace-cmd: Add helper to read *_stack ftrace events
The user_stack and kernel_stack events are special in that they are dynamic
arrays but aren't labeled as __data_loc like other dynamic arrays. This isn't a
big deal since they look the same, they have a "caller" field which is an array
of unsigned longs. This patch adds a helper to the python bindings to read
these arrays in, lookup the function and append them to a python list.
Link: http://lkml.kernel.org/r/1411667037-27105-1-git-send-email-jbacik@fb.com
Signed-off-by: Josef Bacik <jbacik@fb.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | ctracecmd.i | 37 | ||||
-rw-r--r-- | tracecmd.py | 8 |
2 files changed, 45 insertions, 0 deletions
diff --git a/ctracecmd.i b/ctracecmd.i index 3970803d..3b80f01b 100644 --- a/ctracecmd.i +++ b/ctracecmd.i @@ -49,6 +49,43 @@ void py_pevent_register_event_handler(struct pevent *pevent, int id, python_callback, pyfunc); } +static PyObject *py_field_get_stack(struct pevent *pevent, + struct pevent_record *record, + struct event_format *event, + int long_size) +{ + PyObject *list; + struct format_field *field; + void *data = record->data; + const char *func = NULL; + unsigned long addr; + + field = pevent_find_any_field(event, "caller"); + if (!field) { + PyErr_SetString(PyExc_TypeError, + "Event doesn't have caller field"); + return NULL; + } + + list = PyList_New(0); + + for (data += field->offset; data < record->data + record->size; + data += long_size) { + addr = pevent_read_number(event->pevent, data, long_size); + + if ((long_size == 8 && addr == (unsigned long long)-1) || + ((int)addr == -1)) + break; + func = pevent_find_function(event->pevent, addr); + if (PyList_Append(list, PyString_FromString(func))) { + Py_DECREF(list); + return NULL; + } + } + + return list; +} + static PyObject *py_field_get_data(struct format_field *f, struct pevent_record *r) { if (!strncmp(f->type, "__data_loc ", 11)) { diff --git a/tracecmd.py b/tracecmd.py index cdd619b2..358185bd 100644 --- a/tracecmd.py +++ b/tracecmd.py @@ -117,6 +117,10 @@ class Event(object, DictMixin): return None return py_field_get_str(f, self._record) + def stack_field(self, long_size): + return py_field_get_stack(self._pevent, self._record, self._format, + long_size) + class TraceSeq(object): def __init__(self, trace_seq): self._trace_seq = trace_seq @@ -192,6 +196,10 @@ class Trace(object): def cpus(self): return tracecmd_cpus(self._handle) + @cached_property + def long_size(self): + return tracecmd_long_size(self._handle) + def read_event(self, cpu): rec = tracecmd_read_data(self._handle, cpu) if rec: |