Re: [PATCH] trace-cruncher: Add support for event probes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 24.01.22 г. 17:20 ч., Tzvetomir Stoyanov (VMware) wrote:
Event probe (eprobe) is a new type of ftrace dynamic events, introduced
in the Linux kernel 5.15 version. It is useful to have support for it in
trace-cruncher, as it allows more flexibility when printing event's
data.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@xxxxxxxxx>
---
  src/ftracepy-utils.c                          | 34 ++++++++++++++++
  src/ftracepy-utils.h                          |  3 ++
  src/ftracepy.c                                |  5 +++
  .../tests/1_unit/test_01_ftracepy_unit.py     | 39 +++++++++++++++++++
  4 files changed, 81 insertions(+)

diff --git a/src/ftracepy-utils.c b/src/ftracepy-utils.c
index cecb180..28ed7b9 100644
--- a/src/ftracepy-utils.c
+++ b/src/ftracepy-utils.c
@@ -2064,6 +2064,40 @@ PyObject *PyFtrace_register_kretprobe(PyObject *self, PyObject *args,
  	return PyDynevent_New(kprobe);
  }
+PyObject *PyFtrace_register_eprobe(PyObject *self, PyObject *args,
+						   PyObject *kwargs)
+{

It seems that we have an inconsistency in the naming convention of the 'constructor' methods. The 'constructor' for kprobes is called 'register_kprobe', while for histograms and synthetic events we have just 'hist' and 'synth'. Lets use the short naming here (just 'eprobe') and you can remove the 'register' prefix from the constructor for kprobes in another patch.

+	static char *kwlist[] = {"event", "target_system", "target_event", "fetchargs", NULL};
+	const char *event, *target_system, *target_event, *fetchargs;
+	struct tracefs_dynevent *eprobe;
+
+	if (!PyArg_ParseTupleAndKeywords(args,
+					 kwargs,
+					 "ssss",
+					 kwlist,
+					 &event,
+					 &target_system,
+					 &target_event,
+					 &fetchargs)) {
+		return NULL;
+	}
+
+	eprobe = tracefs_eprobe_alloc(TC_SYS, event, target_system, target_event, fetchargs);
+	if (!eprobe) {
+		MEM_ERROR;
+		return NULL;
+	}
+
+	if (tracefs_dynevent_create(eprobe) < 0) {
+		TfsError_fmt(NULL, "Failed to create eprobe '%s'", event);
+		tracefs_dynevent_free(eprobe);
+		return NULL;
+	}
+
+	return PyDynevent_New(eprobe);
+}
+
+
  PyObject *PyDynevent_set_filter(PyDynevent *self, PyObject *args,
  						  PyObject *kwargs)
  {
diff --git a/src/ftracepy-utils.h b/src/ftracepy-utils.h
index fc5016c..1030a50 100644
--- a/src/ftracepy-utils.h
+++ b/src/ftracepy-utils.h
@@ -207,6 +207,9 @@ PyObject *PyFtrace_register_kprobe(PyObject *self, PyObject *args,
  PyObject *PyFtrace_register_kretprobe(PyObject *self, PyObject *args,
  						      PyObject *kwargs);
+PyObject *PyFtrace_register_eprobe(PyObject *self, PyObject *args,
+						   PyObject *kwargs);
+
  PyObject *PyFtrace_hist(PyObject *self, PyObject *args,
  					PyObject *kwargs);
diff --git a/src/ftracepy.c b/src/ftracepy.c
index f59bd4c..50ee4d3 100644
--- a/src/ftracepy.c
+++ b/src/ftracepy.c
@@ -377,6 +377,11 @@ static PyMethodDef ftracepy_methods[] = {
  	 METH_VARARGS | METH_KEYWORDS,
  	 "Define a kretprobe."
  	},
+	{"register_eprobe",
+	 (PyCFunction) PyFtrace_register_eprobe,
+	 METH_VARARGS | METH_KEYWORDS,
+	 "Define an eprobe."
+	},
  	{"hist",
  	 (PyCFunction) PyFtrace_hist,
  	 METH_VARARGS | METH_KEYWORDS,
diff --git a/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py b/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
index 51970d3..12b58a0 100644
--- a/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
+++ b/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py


Please move the tests in separate patch!

@@ -457,6 +457,45 @@ class KprobeTestCase(unittest.TestCase):
          ret = kp1.is_enabled(instance=inst)
          self.assertEqual(ret, '0')
+class EprobeTestCase(unittest.TestCase):
+    def test_register_eprobe(self):

This fails on my machine, because I am still on the 5.13 kernel. Maybe somewhere up in the file you can add a global variable defined like this:

kernel_version = tuple(map(int, (os.uname()[2].split('.')[:2])))

and here you can check the kernel version

	if kernel_version < (5, 15):
		return

+        evt1 = 'sopen_in'
+        evt1_tsys = 'syscalls'
+        evt1_tevent = 'sys_enter_openat'
+        evt1_args = 'file=+0($filename):ustring'
+        evt2 = 'sopen_out'
+        evt2_tsys = 'syscalls'
+        evt2_tevent = 'sys_exit_openat'
+        evt2_args = 'res=$ret:u64'
+
+        ep1 = ft.register_eprobe(event=evt1, target_system=evt1_tsys, target_event=evt1_tevent,
+                                 fetchargs=evt1_args)
+        self.assertEqual(evt1, ep1.event())
+        self.assertEqual("{}.{}".format(evt1_tsys, evt1_tevent), ep1.address())
+        self.assertEqual(evt1_args, ep1.probe())
+
+        ep2 = ft.register_eprobe(event=evt2, target_system=evt2_tsys, target_event=evt2_tevent,
+                                 fetchargs=evt2_args)
+        self.assertEqual(evt2, ep2.event())
+        self.assertEqual("{}.{}".format(evt2_tsys, evt2_tevent), ep2.address())
+        self.assertEqual(evt2_args, ep2.probe())
+
+    def test_enable_eprobe(self):

Another kernel version check

+        evt1 = 'sopen_out'
+        evt1_tsys = 'syscalls'
+        evt1_tevent = 'sys_exit_openat'
+        evt1_args = 'res=$ret:u64'
+
+        ep1 = ft.register_eprobe(event=evt1, target_system=evt1_tsys, target_event=evt1_tevent,
+                                 fetchargs=evt1_args)
+        inst = ft.create_instance(instance_name)
+        ep1.enable(instance=inst)
+        ret = ep1.is_enabled(instance=inst)
+        self.assertEqual(ret, '1')
+
+        ep1.disable(instance=inst)
+        ret = ep1.is_enabled(instance=inst)
+        self.assertEqual(ret, '0')
class TracingOnTestCase(unittest.TestCase):
      def test_ON_OF(self):



Ideally, there must be one more patch that will add an example.
Thanks!

Yordan



[Index of Archives]     [Linux USB Development]     [Linux USB Development]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux