linux-trace-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
To: linux-trace-devel@vger.kernel.org
Cc: rostedt@goodmis.org, Valentin.Schneider@arm.com,
	douglas.raillard@arm.com,
	"Yordan Karadzhov (VMware)" <y.karadz@gmail.com>
Subject: [PATCH 2/5] Refactor the part of the interface that relies on libtraceevent
Date: Thu, 12 Dec 2019 11:02:29 +0200	[thread overview]
Message-ID: <20191212090232.24236-3-y.karadz@gmail.com> (raw)
In-Reply-To: <20191212090232.24236-1-y.karadz@gmail.com>

The part of the interface that relies on libtraceevent gets
re-implemented as an extension called "tracecruncher.ftracepy".
The new extension gets build together with the previously
implemented "tracecruncher.ksharkpy" extension.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 setup.py       |  11 ++-
 src/common.h   |   1 +
 src/ftracepy.c | 234 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 245 insertions(+), 1 deletion(-)
 create mode 100644 src/ftracepy.c

diff --git a/setup.py b/setup.py
index 6a1d2e8..dfe1d00 100644
--- a/setup.py
+++ b/setup.py
@@ -13,6 +13,8 @@ from Cython.Build import cythonize
 
 def main():
     kshark_path = '/usr/local/lib/kernelshark'
+    traceevent_path = '/usr/local/lib/traceevent/'
+    tracecmd_path = '/usr/local/lib/trace-cmd/'
 
     module_ks = Extension('tracecruncher.ksharkpy',
                           sources=['src/ksharkpy.c'],
@@ -25,6 +27,13 @@ def main():
                               ],
                           )
 
+    module_ft = Extension('tracecruncher.ftracepy',
+                          sources=['src/ftracepy.c'],
+                          library_dirs=[kshark_path, traceevent_path, tracecmd_path],
+                          runtime_library_dirs=[kshark_path, traceevent_path, tracecmd_path],
+                          libraries=['kshark', 'traceevent', 'tracecmd'],
+                          )
+
     setup(name='tracecruncher',
           version='0.1.0',
           description='NumPy based interface for accessing tracing data in Python.',
@@ -33,7 +42,7 @@ def main():
           url='https://github.com/vmware/trace-cruncher',
           license='LGPL-2.1',
           packages=find_packages(),
-          ext_modules=[module_ks],
+          ext_modules=[module_ks, module_ft],
           classifiers=[
               'Development Status :: 3 - Alpha',
               'Programming Language :: Python :: 3',
diff --git a/src/common.h b/src/common.h
index d7d355a..632e17a 100644
--- a/src/common.h
+++ b/src/common.h
@@ -9,6 +9,7 @@
 
 #define TRACECRUNCHER_ERROR	tracecruncher_error
 #define KSHARK_ERROR		kshark_error
+#define FTRACE_ERROR		ftrace_error
 
 #define KS_INIT_ERROR \
 	PyErr_SetString(KSHARK_ERROR, "libshark failed to initialize");
diff --git a/src/ftracepy.c b/src/ftracepy.c
new file mode 100644
index 0000000..e23b875
--- /dev/null
+++ b/src/ftracepy.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: LGPL-2.1
+
+/*
+ * Copyright (C) 2019 VMware Inc, Yordan Karadzhov (VMware) <y.karadz@gmail.com>
+ */
+
+// Python
+#include <Python.h>
+
+// trace-cmd
+#include "trace-cmd/trace-cmd.h"
+
+// KernelShark
+#include "kernelshark/libkshark.h"
+#include "kernelshark/libkshark-tepdata.h"
+
+// trace-cruncher
+#include "common.h"
+
+static PyObject *KSHARK_ERROR = NULL;
+static PyObject *FTRACE_ERROR = NULL;
+
+static PyObject *method_event_id(PyObject *self, PyObject *args,
+						 PyObject *kwargs)
+{
+	struct kshark_context *kshark_ctx = NULL;
+	struct tep_event *event;
+	const char *system, *name;
+
+	static char *kwlist[] = {"system", "event", NULL};
+	if (!PyArg_ParseTupleAndKeywords(args,
+					 kwargs,
+					 "ss",
+					 kwlist,
+					 &system,
+					 &name)) {
+		return NULL;
+	}
+
+	if (!kshark_instance(&kshark_ctx)) {
+		KS_INIT_ERROR
+		return NULL;
+	}
+
+	event = tep_find_event_by_name(kshark_ctx->pevent, system, name);
+	if (!event) {
+		PyErr_Format(FTRACE_ERROR,
+			     "Failed to find event '%s/%s'",
+			     system, name);
+	}
+
+	return PyLong_FromLong(event->id);
+}
+
+static PyObject *method_read_event_field(PyObject *self, PyObject *args,
+							 PyObject *kwargs)
+{
+	struct kshark_context *kshark_ctx = NULL;
+	struct tep_format_field *evt_field;
+	struct tep_record *record;
+	struct tep_event *event;
+	unsigned long long val;
+	const char *field;
+	uint64_t offset;
+	int event_id, ret;
+
+	static char *kwlist[] = {"offset", "event_id", "field", NULL};
+	if(!PyArg_ParseTupleAndKeywords(args,
+					kwargs,
+					"Lis",
+					kwlist,
+					&offset,
+					&event_id,
+					&field)) {
+		return NULL;
+	}
+
+	if (!kshark_instance(&kshark_ctx)) {
+		KS_INIT_ERROR
+		return NULL;
+	}
+
+	event = tep_find_event(kshark_ctx->pevent, event_id);
+	if (!event) {
+		PyErr_Format(FTRACE_ERROR,
+			     "Failed to find event '%i'",
+			     event_id);
+		return NULL;
+	}
+
+	evt_field = tep_find_any_field(event, field);
+	if (!evt_field) {
+		PyErr_Format(FTRACE_ERROR,
+			     "Failed to find field '%s' of event '%i'",
+			     field, event_id);
+		return NULL;
+	}
+
+	record = tracecmd_read_at(kshark_ctx->handle, offset, NULL);
+	if (!record) {
+		PyErr_Format(FTRACE_ERROR,
+			     "Failed to read record at offset '%i'",
+			     offset);
+		return NULL;
+	}
+
+	ret = tep_read_number_field(evt_field, record->data, &val);
+	free_record(record);
+
+	if (ret != 0) {
+		PyErr_Format(FTRACE_ERROR,
+			     "Failed to read field '%s' of event '%i'",
+			     field, event_id);
+		return NULL;
+	}
+
+	return PyLong_FromLong(val);
+}
+
+static PyObject *method_get_function(PyObject *self, PyObject *args,
+						     PyObject *kwargs)
+{
+	struct kshark_context *kshark_ctx = NULL;
+	unsigned long long address;
+	const char *func;
+
+	static char *kwlist[] = {"address"};
+	if (!PyArg_ParseTupleAndKeywords(args,
+					 kwargs,
+					 "i",
+					 kwlist,
+					 &address)) {
+		return NULL;
+	}
+
+	if (!kshark_instance(&kshark_ctx)) {
+		KS_INIT_ERROR
+		return NULL;
+	}
+
+	func = tep_find_function(kshark_ctx->pevent, address);
+	if (!func)
+		Py_RETURN_NONE;
+
+	return PyUnicode_FromString(func);
+}
+
+static PyObject *method_map_instruction_address(PyObject *self, PyObject *args,
+								PyObject *kwargs)
+{
+	struct kshark_context *kshark_ctx = NULL;
+	struct tracecmd_proc_addr_map *mem_map;
+	unsigned long long proc_addr, obj_addr;
+	int pid;
+	PyObject *ret;
+
+	static char *kwlist[] = {"pid", "proc_addr"};
+	if (!PyArg_ParseTupleAndKeywords(args,
+					 kwargs,
+					 "iL",
+					 kwlist,
+					 &pid,
+					 &proc_addr)) {
+		return NULL;
+	}
+
+	if (!kshark_instance(&kshark_ctx)) {
+		KS_INIT_ERROR
+		return NULL;
+	}
+
+	mem_map = tracecmd_search_task_map(kshark_ctx->handle,
+					   pid, proc_addr);
+
+	if (!mem_map)
+		Py_RETURN_NONE;
+
+	ret = PyDict_New();
+
+	PyDict_SetItemString(ret, "obj_file",
+			     PyUnicode_FromString(mem_map->lib_name));
+
+	obj_addr = proc_addr - mem_map->start;
+	PyDict_SetItemString(ret, "address", PyLong_FromLong(obj_addr));
+
+	return ret;
+}
+
+static PyMethodDef ftracepy_methods[] = {
+	{"event_id",
+	 (PyCFunction) method_event_id,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Get the Id of the event from its name"
+	},
+	{"read_event_field",
+	 (PyCFunction) method_read_event_field,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Get the value of an event field having a given name"
+	},
+	{"get_function",
+	 (PyCFunction) method_get_function,
+	 METH_VARARGS | METH_KEYWORDS,
+	 ""
+	},
+	{"map_instruction_address",
+	 (PyCFunction) method_map_instruction_address,
+	 METH_VARARGS | METH_KEYWORDS,
+	 ""
+	},
+	{NULL, NULL, 0, NULL}
+};
+
+static struct PyModuleDef ftracepy_module = {
+	PyModuleDef_HEAD_INIT,
+	"ftracepy",
+	"",
+	-1,
+	ftracepy_methods
+};
+
+PyMODINIT_FUNC PyInit_ftracepy(void)
+{
+	PyObject *module =  PyModule_Create(&ftracepy_module);
+
+	KSHARK_ERROR = PyErr_NewException("tracecruncher.ftracepy.ks_error",
+					  NULL, NULL);
+	PyModule_AddObject(module, "ks_error", KSHARK_ERROR);
+
+	FTRACE_ERROR = PyErr_NewException("tracecruncher.ftracepy.ft_error",
+					  NULL, NULL);
+	PyModule_AddObject(module, "ft_error", FTRACE_ERROR);
+
+	return module;
+}
-- 
2.20.1


  parent reply	other threads:[~2019-12-12  9:03 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-12-12  9:02 [PATCH 0/5] Build trace-cruncher as Python pakage Yordan Karadzhov (VMware)
2019-12-12  9:02 ` [PATCH 1/5] Refactor the part of the interface that relies on libkshark Yordan Karadzhov (VMware)
2019-12-12  9:02 ` Yordan Karadzhov (VMware) [this message]
2019-12-12  9:02 ` [PATCH 3/5] Refactor NumPy based data wrapper Yordan Karadzhov (VMware)
2019-12-12  9:02 ` [PATCH 4/5] Add "utils" Yordan Karadzhov (VMware)
2019-12-12  9:02 ` [PATCH 5/5] Adapt the sched_wakeup.py example script to use the new tracecruncher module Yordan Karadzhov (VMware)
2019-12-31 18:37 ` [PATCH 0/5] Build trace-cruncher as Python pakage Douglas Raillard
2020-01-07 16:59   ` Yordan Karadzhov (VMware)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191212090232.24236-3-y.karadz@gmail.com \
    --to=y.karadz@gmail.com \
    --cc=Valentin.Schneider@arm.com \
    --cc=douglas.raillard@arm.com \
    --cc=linux-trace-devel@vger.kernel.org \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).