mirror of
https://github.com/ARM-software/devlib.git
synced 2025-03-04 17:27:51 +00:00
ftrace: Add write-to-disk mode
Allow using trace-cmd record that continuously dump the trace to disk, allowing to overcome the buffer size limitations when recording for extended periods of time.
This commit is contained in:
parent
9ec36e9040
commit
e551b46207
@ -21,6 +21,7 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
import contextlib
|
import contextlib
|
||||||
from shlex import quote
|
from shlex import quote
|
||||||
|
import signal
|
||||||
|
|
||||||
from devlib.collector import (CollectorBase, CollectorOutput,
|
from devlib.collector import (CollectorBase, CollectorOutput,
|
||||||
CollectorOutputEntry)
|
CollectorOutputEntry)
|
||||||
@ -71,6 +72,7 @@ class FtraceCollector(CollectorBase):
|
|||||||
report_on_target=False,
|
report_on_target=False,
|
||||||
trace_clock='local',
|
trace_clock='local',
|
||||||
saved_cmdlines_nr=4096,
|
saved_cmdlines_nr=4096,
|
||||||
|
mode='write-to-memory',
|
||||||
):
|
):
|
||||||
super(FtraceCollector, self).__init__(target)
|
super(FtraceCollector, self).__init__(target)
|
||||||
self.events = events if events is not None else DEFAULT_EVENTS
|
self.events = events if events is not None else DEFAULT_EVENTS
|
||||||
@ -97,6 +99,8 @@ class FtraceCollector(CollectorBase):
|
|||||||
self.trace_clock = trace_clock
|
self.trace_clock = trace_clock
|
||||||
self.saved_cmdlines_nr = saved_cmdlines_nr
|
self.saved_cmdlines_nr = saved_cmdlines_nr
|
||||||
self._reset_needed = True
|
self._reset_needed = True
|
||||||
|
self.mode = mode
|
||||||
|
self._bg_cmd = None
|
||||||
|
|
||||||
# pylint: disable=bad-whitespace
|
# pylint: disable=bad-whitespace
|
||||||
# Setup tracing paths
|
# Setup tracing paths
|
||||||
@ -311,18 +315,33 @@ class FtraceCollector(CollectorBase):
|
|||||||
with contextlib.suppress(TargetStableError):
|
with contextlib.suppress(TargetStableError):
|
||||||
self.target.write_value('/proc/sys/kernel/kptr_restrict', 0)
|
self.target.write_value('/proc/sys/kernel/kptr_restrict', 0)
|
||||||
|
|
||||||
self.target.execute(
|
params = '-B devlib {buffer_size} {cmdlines_size} {clock} {events} {tracer} {functions}'.format(
|
||||||
'{} start -B devlib {buffer_size} {cmdlines_size} {clock} {events} {tracer} {functions}'.format(
|
events=self.event_string,
|
||||||
self.target_binary,
|
tracer=tracer_string,
|
||||||
events=self.event_string,
|
functions=tracecmd_functions,
|
||||||
tracer=tracer_string,
|
buffer_size='-b {}'.format(self.buffer_size) if self.buffer_size is not None else '',
|
||||||
functions=tracecmd_functions,
|
clock='-C {}'.format(self.trace_clock) if self.trace_clock else '',
|
||||||
buffer_size='-b {}'.format(self.buffer_size) if self.buffer_size is not None else '',
|
cmdlines_size='--cmdlines-size {}'.format(self.saved_cmdlines_nr) if self.saved_cmdlines_nr is not None else '',
|
||||||
clock='-C {}'.format(self.trace_clock) if self.trace_clock else '',
|
|
||||||
cmdlines_size='--cmdlines-size {}'.format(self.saved_cmdlines_nr) if self.saved_cmdlines_nr is not None else '',
|
|
||||||
),
|
|
||||||
as_root=True,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mode = self.mode
|
||||||
|
if mode == 'write-to-disk':
|
||||||
|
bg_cmd = self.target.background(
|
||||||
|
# cd into the working_directory first to workaround this issue:
|
||||||
|
# https://lore.kernel.org/linux-trace-devel/20240119162743.1a107fa9@gandalf.local.home/
|
||||||
|
f'cd {self.target.working_directory} && devlib-signal-target {self.target_binary} record -o {quote(self.target_output_file)} {params}',
|
||||||
|
as_root=True,
|
||||||
|
)
|
||||||
|
assert self._bg_cmd is None
|
||||||
|
self._bg_cmd = bg_cmd.__enter__()
|
||||||
|
elif mode == 'write-to-memory':
|
||||||
|
self.target.execute(
|
||||||
|
f'{self.target_binary} start {params}',
|
||||||
|
as_root=True,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown mode {mode}')
|
||||||
|
|
||||||
if self.automark:
|
if self.automark:
|
||||||
self.mark_start()
|
self.mark_start()
|
||||||
|
|
||||||
@ -352,8 +371,21 @@ class FtraceCollector(CollectorBase):
|
|||||||
self.stop_time = time.time()
|
self.stop_time = time.time()
|
||||||
if self.automark:
|
if self.automark:
|
||||||
self.mark_stop()
|
self.mark_stop()
|
||||||
self.target.execute('{} stop -B devlib'.format(self.target_binary),
|
|
||||||
timeout=TIMEOUT, as_root=True)
|
mode = self.mode
|
||||||
|
if mode == 'write-to-disk':
|
||||||
|
bg_cmd = self._bg_cmd
|
||||||
|
self._bg_cmd = None
|
||||||
|
assert bg_cmd is not None
|
||||||
|
bg_cmd.send_signal(signal.SIGINT)
|
||||||
|
bg_cmd.communicate()
|
||||||
|
bg_cmd.__exit__(None, None, None)
|
||||||
|
elif mode == 'write-to-memory':
|
||||||
|
self.target.execute('{} stop -B devlib'.format(self.target_binary),
|
||||||
|
timeout=TIMEOUT, as_root=True)
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown mode {mode}')
|
||||||
|
|
||||||
self._reset_needed = True
|
self._reset_needed = True
|
||||||
|
|
||||||
def set_output(self, output_path):
|
def set_output(self, output_path):
|
||||||
@ -364,9 +396,18 @@ class FtraceCollector(CollectorBase):
|
|||||||
def get_data(self):
|
def get_data(self):
|
||||||
if self.output_path is None:
|
if self.output_path is None:
|
||||||
raise RuntimeError("Output path was not set.")
|
raise RuntimeError("Output path was not set.")
|
||||||
self.target.execute('{0} extract -B devlib -o {1}; chmod 666 {1}'.format(self.target_binary,
|
|
||||||
self.target_output_file),
|
busybox = quote(self.target.busybox)
|
||||||
timeout=TIMEOUT, as_root=True)
|
|
||||||
|
mode = self.mode
|
||||||
|
if mode == 'write-to-disk':
|
||||||
|
# Interrupting trace-cmd record will make it create the file
|
||||||
|
pass
|
||||||
|
elif mode == 'write-to-memory':
|
||||||
|
cmd = f'{self.target_binary} extract -B devlib -o {self.target_output_file} && {busybox} chmod 666 {self.target_output_file}'
|
||||||
|
self.target.execute(cmd, timeout=TIMEOUT, as_root=True)
|
||||||
|
else:
|
||||||
|
raise ValueError(f'Unknown mode {mode}')
|
||||||
|
|
||||||
# The size of trace.dat will depend on how long trace-cmd was running.
|
# The size of trace.dat will depend on how long trace-cmd was running.
|
||||||
# Therefore timout for the pull command must also be adjusted
|
# Therefore timout for the pull command must also be adjusted
|
||||||
|
Loading…
x
Reference in New Issue
Block a user