diff mbox series

[2/2] trace-cruncher: Add example of tracing systemcalls

Message ID 20220128182102.8672-3-y.karadz@gmail.com (mailing list archive)
State Accepted
Headers show
Series SysCall tracing | expand

Commit Message

Yordan Karadzhov Jan. 28, 2022, 6:21 p.m. UTC
This is a very basic example, demonstrating how the low-level APIs can
be used to trace system calls.

Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
 examples/syscall_trace.py | 66 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100755 examples/syscall_trace.py
diff mbox series

Patch

diff --git a/examples/syscall_trace.py b/examples/syscall_trace.py
new file mode 100755
index 0000000..7d6f399
--- /dev/null
+++ b/examples/syscall_trace.py
@@ -0,0 +1,66 @@ 
+#!/usr/bin/env python3
+
+"""
+SPDX-License-Identifier: CC-BY-4.0
+
+Copyright 2022 VMware Inc, Yordan Karadzhov (VMware) <y.karadz@gmail.com>
+"""
+
+import sys
+
+import tracecruncher.ftracepy as ft
+import tracecruncher.ft_utils as tc
+
+eprobe_evt = 'eprobe_open'
+synth_evt = 'synth_open'
+syscall = 'openat'
+args = 'file=+0($file):ustring delta_T=$delta_T:s64'
+
+# In order to trace a system call, we will create a synthetic event that
+# combines the 'sys_enter_XXX' and 'sys_exit_XXX' static events. A dynamic
+# 'eprobe' will be attached to this synthetic event in order to decode the
+# pointer argument of the system and to calculate the time spend between
+# 'sys_enter_XXX' and 'sys_exit_XXX' (syscall duration).
+
+eprobe = ft.eprobe(event=eprobe_evt,
+                   target_system='synthetic', target_event=synth_evt,
+                   fetchargs=args)
+
+synth = ft.synth(name=synth_evt,
+                 start_sys='syscalls', start_evt='sys_enter_' + syscall,
+                 end_sys='syscalls',   end_evt='sys_exit_' + syscall,
+                 start_match='common_pid', end_match='common_pid')
+
+# Add to the synth. event one field from the 'start' event. In the synth. event,
+# the field 'filename' will be renamed to 'file'.
+synth.add_start_fields(fields=['filename'], names=['file'])
+
+# Add to the synth. event a field that measures the time-difference between
+# the 'start' and 'end' events. Use 'hd' time resolution (nanoseconds).
+synth.add_delta_T(hd=True)
+
+# The synthetic event must be registered first (and destroyed last), because the
+# eprobe depends on it. Note that the order in which the events are allocated
+# will be the order in which Python will destroy them at exit.
+synth.register()
+eprobe.register()
+
+tep = tc.local_tep()
+eprobe_id = tep.get_event(system=ft.tc_event_system(), name=eprobe_evt).id()
+
+def callback(event, record):
+    if event.id() == eprobe_id:
+        # Print only the dynamic eprobe.
+        print(tep.info(event, record))
+
+if __name__ == "__main__":
+    if len(sys.argv) < 2:
+        print('Usage: ', sys.argv[0], ' [PROCESS]')
+        sys.exit(1)
+
+    inst = ft.create_instance(tracing_on=False)
+
+    # Enable the two events and trace the user process.
+    synth.enable(instance=inst)
+    eprobe.enable(instance=inst)
+    ft.trace_process(instance=inst, argv=sys.argv[1:])