* [PATCH 0/8] trace-cruncher:Fixes before v0.2 (Beta)
@ 2022-02-10 15:23 Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 1/8] trace-cruncher: Prefix all python class names with 'tc_' Yordan Karadzhov (VMware)
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: Yordan Karadzhov (VMware) @ 2022-02-10 15:23 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Yordan Karadzhov (VMware)
Yordan Karadzhov (VMware) (8):
trace-cruncher: Prefix all python class names with 'tc_'
trace-cruncher: Fix bug in the constructor if tc_synth class
trace-cruncher: Add tests for synth helper APIs
trace-cruncher: Code cleanup in the constructor of tc_synth
trace-cruncher: Rename python function argument in PyFtrace_eprobe
trace-cruncher: Add tc_eprobe class to ft_utiles
trace-cruncher: Check kernel support in the eprobe constructor
trace-cruncher: Add more comments to the examples
examples/eprobe.py | 23 ++-
examples/hist.py | 32 ++++
examples/hist_oop.py | 24 ++-
examples/kprobe_open.py | 6 +-
examples/synth_oop.py | 14 +-
examples/syscall_trace.py | 4 +-
src/ftracepy-utils.c | 50 +++++-
tracecruncher/ft_utils.py | 144 ++++++++++++------
tracecruncher/ks_utils.py | 6 +-
.../tests/1_unit/test_01_ftracepy_unit.py | 100 ++++++++----
10 files changed, 295 insertions(+), 108 deletions(-)
mode change 100644 => 100755 examples/hist_oop.py
mode change 100644 => 100755 examples/synth_oop.py
--
2.32.0
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/8] trace-cruncher: Prefix all python class names with 'tc_'
2022-02-10 15:23 [PATCH 0/8] trace-cruncher:Fixes before v0.2 (Beta) Yordan Karadzhov (VMware)
@ 2022-02-10 15:23 ` Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 2/8] trace-cruncher: Fix bug in the constructor if tc_synth class Yordan Karadzhov (VMware)
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Yordan Karadzhov (VMware) @ 2022-02-10 15:23 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Yordan Karadzhov (VMware)
All classes defined by the high-level python APIs are renamed to
include 'tc_' prefix. This is done in order to avoid confusion with
the equivalent constructor methods, defined by the low-level APIs.
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
examples/hist_oop.py | 10 ++--
examples/kprobe_open.py | 6 +-
examples/synth_oop.py | 14 ++---
tracecruncher/ft_utils.py | 47 ++++++++-------
tracecruncher/ks_utils.py | 6 +-
.../tests/1_unit/test_01_ftracepy_unit.py | 58 +++++++++----------
6 files changed, 74 insertions(+), 67 deletions(-)
mode change 100644 => 100755 examples/hist_oop.py
mode change 100644 => 100755 examples/synth_oop.py
diff --git a/examples/hist_oop.py b/examples/hist_oop.py
old mode 100644
new mode 100755
index 1a3aab6..578b699
--- a/examples/hist_oop.py
+++ b/examples/hist_oop.py
@@ -15,7 +15,7 @@ name = 'khist_example_oop'
cmds = ['start', 'stop', 'show', 'continue', 'clear', 'close']
-evt = tc.event('kmem', 'kmalloc')
+evt = tc.tc_event('kmem', 'kmalloc')
axes={'call_site': 'sym',
'bytes_req': 'n'}
@@ -36,8 +36,8 @@ if __name__ == "__main__":
arg1 = sys.argv[1]
if arg1.isdigit() or arg1 == 'start':
# Create the kernel tracing histogram.
- hist = tc.create_khist(name=name, event=evt, axes=axes, weights=weights,
- sort_keys=sort_keys, sort_dir=sort_dir)
+ hist = tc.create_hist(name=name, event=evt, axes=axes, weights=weights,
+ sort_keys=sort_keys, sort_dir=sort_dir)
# Start taking data.
hist.start()
@@ -58,8 +58,8 @@ if __name__ == "__main__":
else:
# Try to find an existing histogram with the same definition.
# The returned histogram is detached from the trace-cruncher module.
- hist = tc.find_khist(name=name, event=evt, axes=axes, weights=weights,
- sort_keys=sort_keys, sort_dir=sort_dir)
+ hist = tc.find_hist(name=name, event=evt, axes=axes, weights=weights,
+ sort_keys=sort_keys, sort_dir=sort_dir)
if arg1 == 'stop':
# Stop taking data.
diff --git a/examples/kprobe_open.py b/examples/kprobe_open.py
index 141df66..8ab5ae3 100755
--- a/examples/kprobe_open.py
+++ b/examples/kprobe_open.py
@@ -38,9 +38,9 @@ fields = tc.kprobe_add_ptr_arg(name='mode',
fields=fields)
# Create the kprobe event.
-open_probe = tc.kprobe(name='open',
- func='do_sys_openat2',
- fields=fields)
+open_probe = tc.tc_kprobe(name='open',
+ func='do_sys_openat2',
+ fields=fields)
tep = tc.local_tep()
tc.short_kprobe_print(tep, [open_probe])
diff --git a/examples/synth_oop.py b/examples/synth_oop.py
old mode 100644
new mode 100755
index e95f796..201e4df
--- a/examples/synth_oop.py
+++ b/examples/synth_oop.py
@@ -14,25 +14,25 @@ import tracecruncher.ft_utils as tc
# Get the static kernel event 'sched_waking' and 'sched_switch' from system
# 'sched'. Those two events will be used to create the synthetic event.
-swaking = tc.event('sched', 'sched_waking')
-sswitch = tc.event('sched', 'sched_switch')
+swaking = tc.tc_event('sched', 'sched_waking')
+sswitch = tc.tc_event('sched', 'sched_switch')
# Add to the synth. event two fields from the 'start' event (sched_waking). In the
# synth. event, the field 'target_cpu' will be renamed to 'cpu'. Use the 'pid' field
# for matching with the corresponding 'end' event.
-start = tc.ksynth_event_item(event=swaking, fields=['target_cpu', 'prio'], match='pid')
-start = tc.ksynth_field_rename(start, field='target_cpu', name='cpu')
+start = tc.synth_event_item(event=swaking, fields=['target_cpu', 'prio'], match='pid')
+start = tc.synth_field_rename(start, field='target_cpu', name='cpu')
# Add to the synth. event one field from the 'end' event (sched_switch).
# Use the 'next_pid' field for matching with the corresponding 'start' event.
-end = tc.ksynth_event_item(event=sswitch, fields=['prev_prio'], match='next_pid')
+end = tc.synth_event_item(event=sswitch, fields=['prev_prio'], match='next_pid')
# Define a synthetic event. The 'match' value will be recorder as a field in the
# synth. event using 'pid' as name. We also add to the synth. event a field that
# measures the time-difference between the 'start' and 'end' events. This new field
# will use 'hd' time resolution (nanoseconds).
-synth = tc.ksynth(name='synth_wakeup', start_event=start, end_event=end,
- synth_fields=[tc.ksynth_field_deltaT(hd=True)], match_name='pid')
+synth = tc.tc_synth(name='synth_wakeup', start_event=start, end_event=end,
+ synth_fields=[tc.synth_field_deltaT(hd=True)], match_name='pid')
# Create new instance of Ftrace.
inst = ft.create_instance()
diff --git a/tracecruncher/ft_utils.py b/tracecruncher/ft_utils.py
index 741887b..f4d1f05 100644
--- a/tracecruncher/ft_utils.py
+++ b/tracecruncher/ft_utils.py
@@ -37,7 +37,7 @@ def short_kprobe_print(tep, events):
tep.short_kprobe_print(id=e.evt_id, system=e.system, event=e.name)
-class event:
+class tc_event:
def __init__(self, system, name, static=True):
""" Constructor.
"""
@@ -81,7 +81,7 @@ class event:
event=self.name)
-class _kprobe_base(event):
+class _kprobe_base(tc_event):
def __init__(self, name, func):
""" Constructor.
"""
@@ -96,7 +96,8 @@ class _kprobe_base(event):
self.kp.register()
self.evt_id = find_event_id(system=ft.tc_event_system(), event=self.name)
-class kprobe(_kprobe_base):
+
+class tc_kprobe(_kprobe_base):
def __init__(self, name, func, fields):
""" Constructor.
"""
@@ -106,24 +107,28 @@ class kprobe(_kprobe_base):
self.kp = ft.kprobe(event=self.name, function=self.func, probe=probe)
self.register()
+
def kprobe_add_raw_field(name, probe, fields={}):
""" Add a raw definition of a data field to the probe descriptor.
"""
fields[str(name)] = str(probe)
return fields
+
def kprobe_add_arg(name, param_id, param_type, fields={}):
""" Add a function parameter data field to the probe descriptor.
"""
probe = '$arg{0}:{1}'.format(param_id, param_type)
return kprobe_add_raw_field(name=name, probe=probe, fields=fields)
+
def kprobe_add_ptr_arg(name, param_id, param_type, offset=0, fields={}):
""" Add a pointer function parameter data field to the probe descriptor.
"""
probe = '+{0}($arg{1}):{2}'.format(offset, param_id, param_type)
return kprobe_add_raw_field(name=name, probe=probe, fields=fields)
+
def kprobe_add_array_arg(name, param_id, param_type, offset=0,
size=-1, fields={}):
""" Add an array function parameter data field to the probe descriptor.
@@ -138,6 +143,7 @@ def kprobe_add_array_arg(name, param_id, param_type, offset=0,
probe += '($arg{0})):{1}'.format(param_id, param_type)
return kprobe_add_raw_field(name=field_name, probe=probe, fields=fields)
+
def kprobe_add_string_arg(name, param_id, offset=0, usr_space=False, fields={}):
""" Add a string function parameter data field to the probe descriptor.
"""
@@ -148,6 +154,7 @@ def kprobe_add_string_arg(name, param_id, offset=0, usr_space=False, fields={}):
offset=offset,
fields=fields)
+
def kprobe_add_string_array_arg(name, param_id, offset=0, usr_space=False,
size=-1, fields={}):
""" Add a string array function parameter data field to the probe descriptor.
@@ -160,6 +167,7 @@ def kprobe_add_string_array_arg(name, param_id, offset=0, usr_space=False,
size=size,
fields=fields)
+
def kprobe_parse_record_array_field(event, record, field, size=-1):
""" Parse the content of an array function parameter data field.
"""
@@ -177,7 +185,7 @@ def kprobe_parse_record_array_field(event, record, field, size=-1):
return arr
-class kretval_probe(_kprobe_base):
+class tc_kretval_probe(_kprobe_base):
def __init__(self, name, func):
""" Constructor.
"""
@@ -186,7 +194,7 @@ class kretval_probe(_kprobe_base):
self.kp.register()
-class khist:
+class tc_hist:
def __init__(self, name, event, axes, weights=[],
sort_keys=[], sort_dir={}, find=False):
""" Constructor.
@@ -282,13 +290,12 @@ class khist:
return self.data()
-def create_khist(name, event, axes, weights=[],
- sort_keys=[], sort_dir={}):
+def create_hist(name, event, axes, weights=[], sort_keys=[], sort_dir={}):
""" Create new kernel histogram.
"""
try:
- hist = khist(name=name, event=event, axes=axes, weights=weights,
- sort_keys=sort_keys, sort_dir=sort_dir, find=False)
+ hist = tc_hist(name=name, event=event, axes=axes, weights=weights,
+ sort_keys=sort_keys, sort_dir=sort_dir, find=False)
except Exception as err:
msg = 'Failed to create histogram \'{0}\''.format(name)
raise RuntimeError(msg) from err
@@ -296,20 +303,20 @@ def create_khist(name, event, axes, weights=[],
return hist
-def find_khist(name, event, axes, instance=None,
- weights=[], sort_keys=[], sort_dir={}):
+def find_hist(name, event, axes, weights=[], sort_keys=[], sort_dir={}):
""" Find existing kernel histogram.
"""
try:
- hist = khist(name=name, event=event, axes=axes, weights=weights,
- sort_keys=sort_keys, sort_dir=sort_dir, find=True)
+ hist = tc_hist(name=name, event=event, axes=axes, weights=weights,
+ sort_keys=sort_keys, sort_dir=sort_dir, find=True)
except Exception as err:
msg = 'Failed to find histogram \'{0}\''.format(name)
raise RuntimeError(msg) from err
return hist
-class ksynth(event):
+
+class tc_synth(tc_event):
def __init__(self, name, start_event, end_event,
synth_fields=None, match_name=ft.no_arg()):
""" Constructor.
@@ -380,7 +387,7 @@ class ksynth(event):
return self.synth.repr(event=True, hist_start=True, hist_end=True)
-def ksynth_event_item(event, match, fields=[]):
+def synth_event_item(event, match, fields=[]):
""" Create descriptor for an event item (component) of a synthetic event.
To be used as a start/end event.
"""
@@ -393,7 +400,7 @@ def ksynth_event_item(event, match, fields=[]):
return sub_evt
-def ksynth_field_rename(event, field, name):
+def synth_field_rename(event, field, name):
""" Change the name of a field in the event component of a synthetic event.
"""
pos = event['fields'].index(field)
@@ -402,7 +409,7 @@ def ksynth_field_rename(event, field, name):
return event
-def ksynth_field_deltaT(name='delta_T', hd=False):
+def synth_field_deltaT(name='delta_T', hd=False):
""" Create descriptor for time-diference synthetic field.
"""
if hd:
@@ -411,19 +418,19 @@ def ksynth_field_deltaT(name='delta_T', hd=False):
return 'delta_t {0} hd'.format(name)
-def ksynth_field_delta_start(name, start_field, end_field):
+def synth_field_delta_start(name, start_field, end_field):
""" Create descriptor for field diference (start - end) synthetic field.
"""
return 'delta_start {0} {1} {2}'.format(name, start_field, end_field)
-def ksynth_field_delta_end(name, start_field, end_field):
+def synth_field_delta_end(name, start_field, end_field):
""" Create descriptor for field diference (end - start) synthetic field.
"""
return 'delta_end {0} {1} {2}'.format(name, start_field, end_field)
-def ksynth_field_sum(name, start_field, end_field):
+def synth_field_sum(name, start_field, end_field):
""" Create descriptor for field sum synthetic field.
"""
return 'sum {0} {1} {2}'.format(name, start_field, end_field)
diff --git a/tracecruncher/ks_utils.py b/tracecruncher/ks_utils.py
index 15c7835..90dca31 100644
--- a/tracecruncher/ks_utils.py
+++ b/tracecruncher/ks_utils.py
@@ -21,7 +21,7 @@ def size(data):
raise Exception('Data size is unknown.')
-class trace_file_stream:
+class tc_file_stream:
def __init__(self, file_name='', buffer_name='top'):
""" Constructor.
"""
@@ -216,12 +216,12 @@ class ks_session:
def open_file(file_name):
""" Open a trace file for reading.
"""
- return trace_file_stream(file_name)
+ return tc_file_stream(file_name)
def open_buffer(file_name, buffer_name):
""" Open a aprticular buffer in a trace file for reading.
"""
- s = trace_file_stream()
+ s = tc_file_stream()
s.open_buffer(file_name, buffer_name)
return s
diff --git a/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py b/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
index 70f5d29..aea29db 100644
--- a/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
+++ b/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
@@ -664,8 +664,8 @@ tgr_file = '{0}/instances/{1}_inst/events/{2}/{3}/trigger'.format(ft.dir(), hist
class HistOopTestCase(unittest.TestCase):
def test_hist_create(self):
- evt = tc.event(evt_sys, evt_name)
- hist = tc.create_khist(name=hist_name, event=evt, axes=axes, weights=weights,
+ evt = tc.tc_event(evt_sys, evt_name)
+ hist = tc.create_hist(name=hist_name, event=evt, axes=axes, weights=weights,
sort_keys=sort_keys, sort_dir=sort_dir)
f = open(tgr_file)
h_buff = f.read()
@@ -677,8 +677,8 @@ class HistOopTestCase(unittest.TestCase):
f.close()
def test_hist_ctrl(self):
- evt = tc.event(evt_sys, evt_name)
- hist = tc.create_khist(name=hist_name, event=evt, axes=axes, weights=weights,
+ evt = tc.tc_event(evt_sys, evt_name)
+ hist = tc.create_hist(name=hist_name, event=evt, axes=axes, weights=weights,
sort_keys=sort_keys, sort_dir=sort_dir)
f = open(tgr_file)
h_buff = f.read()
@@ -715,32 +715,32 @@ class HistOopTestCase(unittest.TestCase):
f.close()
def test_1_detach(self):
- evt = tc.event(evt_sys, evt_name)
- hist = tc.create_khist(name=hist_name, event=evt, axes=axes, weights=weights,
- sort_keys=sort_keys, sort_dir=sort_dir)
+ evt = tc.tc_event(evt_sys, evt_name)
+ hist = tc.create_hist(name=hist_name, event=evt, axes=axes, weights=weights,
+ sort_keys=sort_keys, sort_dir=sort_dir)
self.assertTrue(hist.is_attached())
hist.detach()
self.assertFalse(hist.is_attached())
def test_2_attach(self):
- evt = tc.event(evt_sys, evt_name)
- hist = tc.find_khist(name=hist_name, event=evt, axes=axes, weights=weights,
- sort_keys=sort_keys, sort_dir=sort_dir)
+ evt = tc.tc_event(evt_sys, evt_name)
+ hist = tc.find_hist(name=hist_name, event=evt, axes=axes, weights=weights,
+ sort_keys=sort_keys, sort_dir=sort_dir)
self.assertFalse(hist.is_attached())
hist.attach()
self.assertTrue(hist.is_attached())
def test_hist_err(self):
- evt = tc.event(evt_sys, evt_name)
+ evt = tc.tc_event(evt_sys, evt_name)
err = 'Failed to find histogram'
with self.assertRaises(Exception) as context:
- hist = tc.find_khist(name=hist_name, event=evt, axes=axes, weights=weights,
- sort_keys=sort_keys, sort_dir=sort_dir)
+ hist = tc.find_hist(name=hist_name, event=evt, axes=axes, weights=weights,
+ sort_keys=sort_keys, sort_dir=sort_dir)
self.assertTrue(err in str(context.exception))
-class SyntTestCase(unittest.TestCase):
+class SynthTestCase(unittest.TestCase):
def test_synt_create(self):
synth = ft.synth(name='wakeup_lat',
start_sys='sched', start_evt='sched_waking',
@@ -825,32 +825,32 @@ class SyntTestCase(unittest.TestCase):
self.assertEqual('none', synth.get_filter())
synth.unregister()
-swaking = tc.event('sched', 'sched_waking')
-sswitch = tc.event('sched', 'sched_switch')
+swaking = tc.tc_event('sched', 'sched_waking')
+sswitch = tc.tc_event('sched', 'sched_switch')
-class SyntTestCase(unittest.TestCase):
+class SynthOopTestCase(unittest.TestCase):
def test_synt_create(self):
- start = tc.ksynth_event_item(event=swaking,
- fields=['target_cpu', 'prio'],
- match='pid')
+ start = tc.synth_event_item(event=swaking,
+ fields=['target_cpu', 'prio'],
+ match='pid')
self.assertEqual(start['fields'], ['target_cpu', 'prio'])
self.assertEqual(start['match'], 'pid')
self.assertEqual(start['field_names'], [None, None])
- start = tc.ksynth_field_rename(start,
- field='target_cpu', name='cpu')
+ start = tc.synth_field_rename(start,
+ field='target_cpu', name='cpu')
self.assertEqual(start['field_names'], ['cpu', None])
- end = tc.ksynth_event_item(event=sswitch,
- fields=['prev_prio'],
- match='next_pid')
+ end = tc.synth_event_item(event=sswitch,
+ fields=['prev_prio'],
+ match='next_pid')
self.assertEqual(end['fields'], ['prev_prio'])
self.assertEqual(end['match'], 'next_pid')
- synth = tc.ksynth(name='synth_wakeup',
- start_event=start, end_event=end,
- synth_fields=[tc.ksynth_field_deltaT(hd=True)],
- match_name='pid')
+ synth = tc.tc_synth(name='synth_wakeup',
+ start_event=start, end_event=end,
+ synth_fields=[tc.synth_field_deltaT(hd=True)],
+ match_name='pid')
synth_str = synth.__repr__().split('\n')
event = synth_str[0]
--
2.32.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/8] trace-cruncher: Fix bug in the constructor if tc_synth class
2022-02-10 15:23 [PATCH 0/8] trace-cruncher:Fixes before v0.2 (Beta) Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 1/8] trace-cruncher: Prefix all python class names with 'tc_' Yordan Karadzhov (VMware)
@ 2022-02-10 15:23 ` Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 3/8] trace-cruncher: Add tests for synth helper APIs Yordan Karadzhov (VMware)
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Yordan Karadzhov (VMware) @ 2022-02-10 15:23 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Yordan Karadzhov (VMware)
There is a missing argument when calling one of the low-level APIs for
synthetic events (add_sum()). In the patch we also add comments, in order
to make this part of the code more readable.
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
tracecruncher/ft_utils.py | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/tracecruncher/ft_utils.py b/tracecruncher/ft_utils.py
index f4d1f05..7e0e642 100644
--- a/tracecruncher/ft_utils.py
+++ b/tracecruncher/ft_utils.py
@@ -357,6 +357,8 @@ class tc_synth(tc_event):
for f in synth_fields:
args = f.split(' ')
if args[0] == 'delta_t' and len(args) < 4:
+ # The expected format is: 'delta_t [name] hd'.
+ # Arguments 1 and 2 are optional.
if len(args) == 1:
self.synth.add_delta_T()
elif len(args) == 3 and args[2] == 'hd':
@@ -366,15 +368,26 @@ class tc_synth(tc_event):
else:
self.synth.add_delta_T(name=args[1])
elif args[0] == 'delta_start' and len(args) == 4:
+ # The expected format is:
+ # 'delta_start [name] [start_field] [end_field]'.
self.synth.add_delta_start(name=args[1],
start_field=args[2],
end_field=args[3])
+
elif args[0] == 'delta_end' and len(args) == 4:
+ # The expected format is:
+ # 'delta_end [name] [start_field] [end_field]'.
self.synth.add_delta_end(name=args[1],
start_field=args[2],
end_field=args[3])
- elif args[0] == 'delta_start' and len(args) == 3:
- self.synth.add_sum(start_field=args[1], end_field=args[2])
+
+ elif args[0] == 'sun' and len(args) == 4:
+ # The expected format is:
+ # 'sum [name] [start_field] [end_field]'.
+ self.synth.add_sum(name=args[1],
+ start_field=args[2],
+ end_field=args[3])
+
else:
raise ValueError('Invalid synth. field \'{0}\''.format(f))
--
2.32.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/8] trace-cruncher: Add tests for synth helper APIs
2022-02-10 15:23 [PATCH 0/8] trace-cruncher:Fixes before v0.2 (Beta) Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 1/8] trace-cruncher: Prefix all python class names with 'tc_' Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 2/8] trace-cruncher: Fix bug in the constructor if tc_synth class Yordan Karadzhov (VMware)
@ 2022-02-10 15:23 ` Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 4/8] trace-cruncher: Code cleanup in the constructor of tc_synth Yordan Karadzhov (VMware)
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Yordan Karadzhov (VMware) @ 2022-02-10 15:23 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Yordan Karadzhov (VMware)
Test cases for the helpers, providing a descriptor strings for synthetic
fields. The patch includes a fix of a bug discovered with the new tests.
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
tracecruncher/ft_utils.py | 6 ++---
.../tests/1_unit/test_01_ftracepy_unit.py | 22 +++++++++++++++++++
2 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/tracecruncher/ft_utils.py b/tracecruncher/ft_utils.py
index 7e0e642..6db426e 100644
--- a/tracecruncher/ft_utils.py
+++ b/tracecruncher/ft_utils.py
@@ -425,10 +425,8 @@ def synth_field_rename(event, field, name):
def synth_field_deltaT(name='delta_T', hd=False):
""" Create descriptor for time-diference synthetic field.
"""
- if hd:
- return 'delta_t {0} hd'.format(name)
-
- return 'delta_t {0} hd'.format(name)
+ d = 'delta_t {0}'.format(name)
+ return (d, d+' hd')[hd]
def synth_field_delta_start(name, start_field, end_field):
diff --git a/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py b/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
index aea29db..f942b6b 100644
--- a/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
+++ b/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
@@ -829,6 +829,28 @@ swaking = tc.tc_event('sched', 'sched_waking')
sswitch = tc.tc_event('sched', 'sched_switch')
class SynthOopTestCase(unittest.TestCase):
+ def test_field_deltaT(self):
+ f = tc.synth_field_deltaT()
+ self.assertEqual(f, 'delta_t delta_T')
+ f = tc.synth_field_deltaT(hd=True)
+ self.assertEqual(f, 'delta_t delta_T hd')
+ f = tc.synth_field_deltaT(name='dT', hd=True)
+ self.assertEqual(f, 'delta_t dT hd')
+ f = tc.synth_field_deltaT(name='dT', hd=False)
+ self.assertEqual(f, 'delta_t dT')
+
+ def test_field_delta_start(self):
+ f = tc.synth_field_delta_start('dS', 'foo', 'bar')
+ self.assertEqual(f, 'delta_start dS foo bar')
+
+ def test_field_delta_end(self):
+ f = tc.synth_field_delta_end('dE', 'foo', 'bar')
+ self.assertEqual(f, 'delta_end dE foo bar')
+
+ def test_field_sum(self):
+ f = tc.synth_field_sum('Sm', 'foo', 'bar')
+ self.assertEqual(f, 'sum Sm foo bar')
+
def test_synt_create(self):
start = tc.synth_event_item(event=swaking,
fields=['target_cpu', 'prio'],
--
2.32.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/8] trace-cruncher: Code cleanup in the constructor of tc_synth
2022-02-10 15:23 [PATCH 0/8] trace-cruncher:Fixes before v0.2 (Beta) Yordan Karadzhov (VMware)
` (2 preceding siblings ...)
2022-02-10 15:23 ` [PATCH 3/8] trace-cruncher: Add tests for synth helper APIs Yordan Karadzhov (VMware)
@ 2022-02-10 15:23 ` Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 5/8] trace-cruncher: Rename python function argument in PyFtrace_eprobe Yordan Karadzhov (VMware)
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Yordan Karadzhov (VMware) @ 2022-02-10 15:23 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Yordan Karadzhov (VMware)
No functional changes are introduced. Just simplifying the code and
making it have more pythonic style.
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
tracecruncher/ft_utils.py | 20 ++++++--------------
1 file changed, 6 insertions(+), 14 deletions(-)
diff --git a/tracecruncher/ft_utils.py b/tracecruncher/ft_utils.py
index 6db426e..67e020f 100644
--- a/tracecruncher/ft_utils.py
+++ b/tracecruncher/ft_utils.py
@@ -331,24 +331,16 @@ class tc_synth(tc_event):
end_match=end_event['match'],
match_name=match_name)
- start_fields = end_fields = []
-
- if 'fields' in start_event:
- start_fields = start_event['fields']
-
- start_field_names = [None] * len(start_fields)
- if 'field_names' in start_event:
- start_field_names = start_event['field_names']
+ start_fields = ([], start_event['fields'])['fields' in start_event]
+ start_field_names = ([None] * len(start_fields),
+ start_event['field_names'])['field_names' in start_event]
self.synth.add_start_fields(fields=start_fields,
names=start_field_names)
- if 'fields' in end_event:
- end_fields = end_event['fields']
-
- end_field_names = [None] * len(end_fields)
- if 'field_names' in end_event:
- end_field_names = end_event['field_names']
+ end_fields = ([], end_event['fields'])['fields' in end_event]
+ end_field_names = ([None] * len(end_fields),
+ end_event['field_names'])['field_names' in end_event]
self.synth.add_end_fields(fields=end_fields,
names=end_field_names)
--
2.32.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/8] trace-cruncher: Rename python function argument in PyFtrace_eprobe
2022-02-10 15:23 [PATCH 0/8] trace-cruncher:Fixes before v0.2 (Beta) Yordan Karadzhov (VMware)
` (3 preceding siblings ...)
2022-02-10 15:23 ` [PATCH 4/8] trace-cruncher: Code cleanup in the constructor of tc_synth Yordan Karadzhov (VMware)
@ 2022-02-10 15:23 ` Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 6/8] trace-cruncher: Add tc_eprobe class to ft_utiles Yordan Karadzhov (VMware)
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Yordan Karadzhov (VMware) @ 2022-02-10 15:23 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Yordan Karadzhov (VMware)
The keyword (named) argument of the eprobe constrictor is renamed from
'fetchargs' to 'fetch_fields'. This is done because the old name can be
confusing, since the probe is supposed to fetch a field of event (not a
function argument). The new name also makes a better match with the
'snake case' naming convention used in trace-cruncher.
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
examples/syscall_trace.py | 2 +-
src/ftracepy-utils.c | 2 +-
tracecruncher/tests/1_unit/test_01_ftracepy_unit.py | 6 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/examples/syscall_trace.py b/examples/syscall_trace.py
index 7d6f399..bfa56ed 100755
--- a/examples/syscall_trace.py
+++ b/examples/syscall_trace.py
@@ -24,7 +24,7 @@ args = 'file=+0($file):ustring delta_T=$delta_T:s64'
eprobe = ft.eprobe(event=eprobe_evt,
target_system='synthetic', target_event=synth_evt,
- fetchargs=args)
+ fetch_fields=args)
synth = ft.synth(name=synth_evt,
start_sys='syscalls', start_evt='sys_enter_' + syscall,
diff --git a/src/ftracepy-utils.c b/src/ftracepy-utils.c
index b262c19..20f0cd9 100644
--- a/src/ftracepy-utils.c
+++ b/src/ftracepy-utils.c
@@ -2366,7 +2366,7 @@ struct tep_event *dynevent_get_event(PyDynevent *event,
PyObject *PyFtrace_eprobe(PyObject *self, PyObject *args, PyObject *kwargs)
{
- static char *kwlist[] = {"event", "target_system", "target_event", "fetchargs", NULL};
+ static char *kwlist[] = {"event", "target_system", "target_event", "fetch_fields", NULL};
const char *event, *target_system, *target_event, *fetchargs;
struct tracefs_dynevent *eprobe;
PyObject *py_dyn;
diff --git a/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py b/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
index f942b6b..6fdd053 100644
--- a/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
+++ b/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
@@ -473,13 +473,13 @@ class EprobeTestCase(unittest.TestCase):
evt2_args = 'res=$ret:u64'
ep1 = ft.eprobe(event=evt1, target_system=evt1_tsys, target_event=evt1_tevent,
- fetchargs=evt1_args)
+ fetch_fields=evt1_args)
self.assertEqual(evt1, ep1.event())
self.assertEqual("{}.{}".format(evt1_tsys, evt1_tevent), ep1.address())
self.assertEqual(evt1_args, ep1.probe())
ep2 = ft.eprobe(event=evt2, target_system=evt2_tsys, target_event=evt2_tevent,
- fetchargs=evt2_args)
+ fetch_fields=evt2_args)
self.assertEqual(evt2, ep2.event())
self.assertEqual("{}.{}".format(evt2_tsys, evt2_tevent), ep2.address())
self.assertEqual(evt2_args, ep2.probe())
@@ -496,7 +496,7 @@ class EprobeTestCase(unittest.TestCase):
evt1_args = 'res=$ret:u64'
ep1 = ft.eprobe(event=evt1, target_system=evt1_tsys, target_event=evt1_tevent,
- fetchargs=evt1_args)
+ fetch_fields=evt1_args)
ep1.register()
inst = ft.create_instance(instance_name)
ep1.enable(instance=inst)
--
2.32.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/8] trace-cruncher: Add tc_eprobe class to ft_utiles
2022-02-10 15:23 [PATCH 0/8] trace-cruncher:Fixes before v0.2 (Beta) Yordan Karadzhov (VMware)
` (4 preceding siblings ...)
2022-02-10 15:23 ` [PATCH 5/8] trace-cruncher: Rename python function argument in PyFtrace_eprobe Yordan Karadzhov (VMware)
@ 2022-02-10 15:23 ` Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 7/8] trace-cruncher: Check kernel support in the eprobe constructor Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 8/8] trace-cruncher: Add more comments to the examples Yordan Karadzhov (VMware)
7 siblings, 0 replies; 9+ messages in thread
From: Yordan Karadzhov (VMware) @ 2022-02-10 15:23 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Yordan Karadzhov (VMware)
Define a Python class and helper methods to be used for easy manipulation
of kernel eprobes.
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
examples/eprobe.py | 13 ++++-
tracecruncher/ft_utils.py | 56 ++++++++++++++++---
.../tests/1_unit/test_01_ftracepy_unit.py | 14 +++++
3 files changed, 72 insertions(+), 11 deletions(-)
diff --git a/examples/eprobe.py b/examples/eprobe.py
index 85b0685..a8be907 100755
--- a/examples/eprobe.py
+++ b/examples/eprobe.py
@@ -11,8 +11,10 @@ import sys
import tracecruncher.ftracepy as ft
import tracecruncher.ft_utils as tc
-open_probe = ft.eprobe(event='sopen_in', target_system='syscalls',
- target_event='sys_enter_openat', fetchargs='file=+0($filename):ustring')
+fields = tc.eprobe_add_string_field(name='file', target_field='filename',
+ usr_space=True)
+event = tc.tc_event('syscalls', 'sys_enter_openat')
+eprobe = tc.tc_eprobe(name='sopen_in', target_event=event, fields=fields)
tep = tc.local_tep()
@@ -25,5 +27,10 @@ if __name__ == "__main__":
sys.exit(1)
inst = ft.create_instance(tracing_on=False)
- open_probe.enable(instance=inst)
+
+ # Enable the probe.
+ eprobe.enable(instance=inst)
+
+ # Subscribe for the kprobe event (using the default function name 'callback')
+ # and trace the user process.
ft.trace_process(instance=inst, argv=sys.argv[1:])
diff --git a/tracecruncher/ft_utils.py b/tracecruncher/ft_utils.py
index 67e020f..b27f38a 100644
--- a/tracecruncher/ft_utils.py
+++ b/tracecruncher/ft_utils.py
@@ -81,22 +81,29 @@ class tc_event:
event=self.name)
-class _kprobe_base(tc_event):
- def __init__(self, name, func):
+class _dynevent(tc_event):
+ def __init__(self, name):
""" Constructor.
"""
super().__init__(system=ft.tc_event_system(), name=name, static=False)
- self.func = func
- self.kp = None
+ self.evt = None
self.evt_id = -1
def register(self):
""" Register this probe to Ftrace.
"""
- self.kp.register()
+ self.evt.register()
self.evt_id = find_event_id(system=ft.tc_event_system(), event=self.name)
+class _kprobe_base(_dynevent):
+ def __init__(self, name, func):
+ """ Constructor.
+ """
+ super().__init__(name=name)
+ self.func = func
+
+
class tc_kprobe(_kprobe_base):
def __init__(self, name, func, fields):
""" Constructor.
@@ -104,7 +111,7 @@ class tc_kprobe(_kprobe_base):
super().__init__(name, func)
self.fields = fields
probe = ' '.join('{!s}={!s}'.format(key,val) for (key, val) in self.fields.items())
- self.kp = ft.kprobe(event=self.name, function=self.func, probe=probe)
+ self.evt = ft.kprobe(event=self.name, function=self.func, probe=probe)
self.register()
@@ -190,8 +197,41 @@ class tc_kretval_probe(_kprobe_base):
""" Constructor.
"""
super().__init__(name, func)
- self.kp = ft.kprobe(event=self.name, function=self.func)
- self.kp.register()
+ self.evt = ft.kprobe(event=self.name, function=self.func)
+ self.register()
+
+
+class tc_eprobe(_dynevent):
+ def __init__(self, name, target_event, fields):
+ """ Constructor.
+ """
+ super().__init__(name=name)
+ self.target_event = target_event
+ self.fields = fields
+ probe = ' '.join('{!s}={!s}'.format(key,val) for (key, val) in self.fields.items())
+ self.evt = ft.eprobe(event=self.name,
+ target_system=target_event.system,
+ target_event=target_event.name,
+ fetch_fields=probe)
+ self.register()
+
+
+def eprobe_add_ptr_field(name, target_field, field_type, offset=0, fields={}):
+ """ Add a pointer data field to the eprobe descriptor.
+ """
+ probe = '+{0}(${1}):{2}'.format(offset, target_field, field_type)
+ return kprobe_add_raw_field(name=name, probe=probe, fields=fields)
+
+
+def eprobe_add_string_field(name, target_field, offset=0, usr_space=False, fields={}):
+ """ Add a string data field to the eprobe descriptor.
+ """
+ f_type = 'ustring' if usr_space else 'string'
+ return eprobe_add_ptr_field(name=name,
+ target_field=target_field,
+ field_type=f_type,
+ offset=offset,
+ fields=fields)
class tc_hist:
diff --git a/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py b/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
index 6fdd053..debdd83 100644
--- a/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
+++ b/tracecruncher/tests/1_unit/test_01_ftracepy_unit.py
@@ -507,6 +507,20 @@ class EprobeTestCase(unittest.TestCase):
ret = ep1.is_enabled(instance=inst)
self.assertEqual(ret, '0')
+class EprobeOopTestCase(unittest.TestCase):
+ def test_eprobe(self):
+ fields = tc.eprobe_add_string_field(name='file',
+ target_field='filename',
+ usr_space=True)
+ self.assertEqual(fields, {'file': '+0($filename):ustring'})
+
+ if kernel_version < (5, 15):
+ return
+
+ event = tc.tc_event('syscalls', 'sys_enter_openat')
+ eprobe = tc.tc_eprobe(name='opn', target_event=event, fields=fields)
+ self.assertEqual(eprobe.evt.probe(), 'file=+0($filename):ustring')
+
class TracingOnTestCase(unittest.TestCase):
def test_ON_OF(self):
ft.tracing_ON()
--
2.32.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 7/8] trace-cruncher: Check kernel support in the eprobe constructor
2022-02-10 15:23 [PATCH 0/8] trace-cruncher:Fixes before v0.2 (Beta) Yordan Karadzhov (VMware)
` (5 preceding siblings ...)
2022-02-10 15:23 ` [PATCH 6/8] trace-cruncher: Add tc_eprobe class to ft_utiles Yordan Karadzhov (VMware)
@ 2022-02-10 15:23 ` Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 8/8] trace-cruncher: Add more comments to the examples Yordan Karadzhov (VMware)
7 siblings, 0 replies; 9+ messages in thread
From: Yordan Karadzhov (VMware) @ 2022-02-10 15:23 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Yordan Karadzhov (VMware)
'eprobes' have been introduced in kernel version 5.15. Before trying to
create eprobe, we have to check if suport is avaiable. In the case of
using an older version of the kernel, an apropriate error message is
provided.
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
src/ftracepy-utils.c | 48 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/src/ftracepy-utils.c b/src/ftracepy-utils.c
index 20f0cd9..85f5bbc 100644
--- a/src/ftracepy-utils.c
+++ b/src/ftracepy-utils.c
@@ -12,6 +12,7 @@
// C
#include <search.h>
#include <string.h>
+#include <sys/utsname.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
@@ -23,6 +24,47 @@ PyObject *TFS_ERROR;
PyObject *TEP_ERROR;
PyObject *TRACECRUNCHER_ERROR;
+static char *kernel_version()
+{
+ struct utsname uts;
+
+ if (uname(&uts) != 0) {
+ PyErr_SetString(TFS_ERROR, "Failed to get kernel version.");
+ return NULL;
+ }
+
+ return strdup(uts.release);
+}
+
+static bool check_kernel_support(const char *api, int major, int minor)
+{
+ char *buff, *this_kernel = kernel_version();
+ const char *dlm = ".";
+ bool ret = false;
+ int mj, mn;
+
+ buff = strtok(this_kernel, dlm);
+ mj = atoi(buff);
+ if (mj > major)
+ ret = true;
+
+ if (mj == major) {
+ buff = strtok(NULL, dlm);
+ mn = atoi(buff);
+ if (mn >= minor)
+ ret = true;
+ }
+
+ free(this_kernel);
+ if (!ret) {
+ PyErr_Format(TFS_ERROR,
+ "Using \'%s()\' requires kernel versions >= %i.%i",
+ api, major, minor);
+ }
+
+ return ret;
+}
+
static const char *get_instance_name(struct tracefs_instance *instance);
static char *tfs_error_log(struct tracefs_instance *instance, bool *ok)
@@ -2382,6 +2424,10 @@ PyObject *PyFtrace_eprobe(PyObject *self, PyObject *args, PyObject *kwargs)
return NULL;
}
+ /* 'eprobes' are introduced in kernel version 5.15. */
+ if (!check_kernel_support("eprobe", 5, 15))
+ return NULL;
+
eprobe = tracefs_eprobe_alloc(TC_SYS, event, target_system, target_event, fetchargs);
if (!eprobe) {
MEM_ERROR;
@@ -2395,7 +2441,7 @@ PyObject *PyFtrace_eprobe(PyObject *self, PyObject *args, PyObject *kwargs)
* there is no need to 'destroy' this event at exit.
*/
set_destroy_flag(py_dyn, false);
- return py_dyn;;
+ return py_dyn;
}
static PyObject *set_filter(PyObject *args, PyObject *kwargs,
--
2.32.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 8/8] trace-cruncher: Add more comments to the examples
2022-02-10 15:23 [PATCH 0/8] trace-cruncher:Fixes before v0.2 (Beta) Yordan Karadzhov (VMware)
` (6 preceding siblings ...)
2022-02-10 15:23 ` [PATCH 7/8] trace-cruncher: Check kernel support in the eprobe constructor Yordan Karadzhov (VMware)
@ 2022-02-10 15:23 ` Yordan Karadzhov (VMware)
7 siblings, 0 replies; 9+ messages in thread
From: Yordan Karadzhov (VMware) @ 2022-02-10 15:23 UTC (permalink / raw)
To: linux-trace-devel; +Cc: Yordan Karadzhov (VMware)
The changes aim to ease the understanding of the examples.
No functional changes are introduced.
Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com>
---
examples/eprobe.py | 10 +++++++++-
examples/hist.py | 32 ++++++++++++++++++++++++++++++++
examples/hist_oop.py | 14 +++++++++++---
examples/syscall_trace.py | 2 +-
4 files changed, 53 insertions(+), 5 deletions(-)
diff --git a/examples/eprobe.py b/examples/eprobe.py
index a8be907..44fc7cd 100755
--- a/examples/eprobe.py
+++ b/examples/eprobe.py
@@ -11,21 +11,29 @@ import sys
import tracecruncher.ftracepy as ft
import tracecruncher.ft_utils as tc
+# Create an 'eprobe' that will be attached to the static event 'sys_enter_openat'
+# from system 'syscalls'. The probe will decode the string field of the event
+# called 'filename' and will record its content using the name 'file'.
fields = tc.eprobe_add_string_field(name='file', target_field='filename',
usr_space=True)
event = tc.tc_event('syscalls', 'sys_enter_openat')
eprobe = tc.tc_eprobe(name='sopen_in', target_event=event, fields=fields)
-tep = tc.local_tep()
+# Define a callback function that will print
+# a short human-readable version of the 'eprobe'.
+tep = tc.local_tep()
def callback(event, record):
print(tep.info(event, record))
+
if __name__ == "__main__":
if len(sys.argv) < 2:
print('Usage: ', sys.argv[0], ' [PROCESS]')
sys.exit(1)
+ # Create new Ftrace instance to work in. The tracing in this new instance
+ # is not going to be enabled yet.
inst = ft.create_instance(tracing_on=False)
# Enable the probe.
diff --git a/examples/hist.py b/examples/hist.py
index d668039..044be79 100755
--- a/examples/hist.py
+++ b/examples/hist.py
@@ -16,6 +16,20 @@ inst_name = 'khist_example'
cmds = ['start', 'stop', 'show', 'continue', 'clear', 'close']
def get_hist():
+ # From the event 'kmalloc' in system 'kmem', create a two-dimensional
+ # histogram, using the event fields 'call_site' and 'bytes_req'.
+ #
+ # The field 'call_site' will be displayed as a kernel symbol.
+ # The field 'bytes_req' will be displayed as normal field (wothout
+ # modifying the type).
+ #
+ # Instead of just recording the "hitcount" in each bin of the histogram,
+ # we will use the 'value' of 'bytes_alloc' as a weight of the individual
+ # histogram entries (events).
+ #
+ # The results will be ordered using 'bytes_req' as a primary and
+ # 'bytes_alloc' as a secondary sorting criteria. For 'bytes_req' we will
+ # use descending order.
hist = ft.hist(name='h1',
system='kmem',
event='kmalloc',
@@ -37,30 +51,48 @@ if __name__ == "__main__":
arg1 = sys.argv[1]
if arg1.isdigit() or arg1 == 'start':
+ # Create new Ftrace instance and a tracing histogram.
inst = ft.create_instance(name=inst_name)
hist = get_hist()
+
+ # Start taking data.
hist.start(inst)
if arg1.isdigit():
+ # Take data for a while, then stop, print the result, close
+ # the histogram and exit.
time.sleep(int(arg1))
hist.stop(inst)
print(hist.read(inst))
hist.close(inst)
else:
+ # Detach the 'hist' object from the trace-cruncher module. This
+ # will prevent the kernel histogram from being destroyed when the
+ # module is closed (at exit).
ft.detach(inst)
else:
+ # Try to find existing Ftrace instance and histogram with the same
+ # definitions. The returned instancd is detached from the
+ # trace-cruncher module.
inst = ft.find_instance(name=inst_name)
hist = get_hist()
if arg1 == 'stop':
+ # Stop taking data.
hist.stop(inst)
elif arg1 == 'show':
+ # Print the collected data.
print(hist.read(inst))
elif arg1 == 'continue':
+ # Continue taking data.
hist.resume(inst)
elif arg1 == 'clear':
+ # Reset the histogram.
hist.clear(inst)
if arg1 == 'close':
+ # Destroy the histogram in the kernel and attach the instance to
+ # the trace-cruncher module. This will ensure that the instance
+ # will be destroyed when the module is closed (at exit).
ft.attach(inst)
hist.close(inst)
diff --git a/examples/hist_oop.py b/examples/hist_oop.py
index 578b699..507269f 100755
--- a/examples/hist_oop.py
+++ b/examples/hist_oop.py
@@ -12,18 +12,26 @@ import time
import tracecruncher.ft_utils as tc
name = 'khist_example_oop'
-
cmds = ['start', 'stop', 'show', 'continue', 'clear', 'close']
+# From the event 'kmalloc' in system 'kmem', create a two-dimensional
+# histogram, using the event fields 'call_site' and 'bytes_req'.
+# The field 'call_site' will be displayed as a kernel symbol.
+# The field 'bytes_req' will be displayed as normal field (wothout
+# modifying the type).
evt = tc.tc_event('kmem', 'kmalloc')
-
axes={'call_site': 'sym',
'bytes_req': 'n'}
+# Instead of just recording the "hitcount" in each bin of the histogram,
+# we will use the 'value' of 'bytes_alloc' as a weight of the individual
+# histogram entries (events).
weights=['bytes_alloc']
+# The results will be ordered using 'bytes_req' as a primary and
+# 'bytes_alloc' as a secondary sorting criteria. For 'bytes_req' we will
+# use descending order.
sort_keys=['bytes_req', 'bytes_alloc']
-
sort_dir={'bytes_req': 'desc'}
if __name__ == "__main__":
diff --git a/examples/syscall_trace.py b/examples/syscall_trace.py
index bfa56ed..1117fab 100755
--- a/examples/syscall_trace.py
+++ b/examples/syscall_trace.py
@@ -19,7 +19,7 @@ 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
+# pointer argument of the system call and to calculate the time spent between
# 'sys_enter_XXX' and 'sys_exit_XXX' (syscall duration).
eprobe = ft.eprobe(event=eprobe_evt,
--
2.32.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2022-02-10 15:24 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-02-10 15:23 [PATCH 0/8] trace-cruncher:Fixes before v0.2 (Beta) Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 1/8] trace-cruncher: Prefix all python class names with 'tc_' Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 2/8] trace-cruncher: Fix bug in the constructor if tc_synth class Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 3/8] trace-cruncher: Add tests for synth helper APIs Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 4/8] trace-cruncher: Code cleanup in the constructor of tc_synth Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 5/8] trace-cruncher: Rename python function argument in PyFtrace_eprobe Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 6/8] trace-cruncher: Add tc_eprobe class to ft_utiles Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 7/8] trace-cruncher: Check kernel support in the eprobe constructor Yordan Karadzhov (VMware)
2022-02-10 15:23 ` [PATCH 8/8] trace-cruncher: Add more comments to the examples Yordan Karadzhov (VMware)
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).