mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-04-20 09:40:50 +01:00
Merge pull request #62 from ep1cman/trace-cmd-target-extract
trace-cmd: Added ability to generate reports on target device
This commit is contained in:
commit
e5c6ef5368
@ -22,7 +22,7 @@ import subprocess
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
|
||||||
from wlauto import Instrument, Parameter, Executable
|
from wlauto import Instrument, Parameter, Executable
|
||||||
from wlauto.exceptions import InstrumentError, ConfigError
|
from wlauto.exceptions import InstrumentError, ConfigError, DeviceError
|
||||||
from wlauto.core import signal
|
from wlauto.core import signal
|
||||||
from wlauto.utils.types import boolean
|
from wlauto.utils.types import boolean
|
||||||
|
|
||||||
@ -133,12 +133,7 @@ class TraceCmdInstrument(Instrument):
|
|||||||
"""),
|
"""),
|
||||||
Parameter('report', kind=boolean, default=True,
|
Parameter('report', kind=boolean, default=True,
|
||||||
description="""
|
description="""
|
||||||
Specifies whether host-side reporting should be performed once the binary trace has been
|
Specifies whether reporting should be performed once the binary trace has been generated.
|
||||||
pulled form the device.
|
|
||||||
|
|
||||||
.. note:: This requires the latest version of trace-cmd to be installed on the host (the
|
|
||||||
one in your distribution's repos may be too old).
|
|
||||||
|
|
||||||
"""),
|
"""),
|
||||||
Parameter('no_install', kind=boolean, default=False,
|
Parameter('no_install', kind=boolean, default=False,
|
||||||
description="""
|
description="""
|
||||||
@ -146,6 +141,15 @@ class TraceCmdInstrument(Instrument):
|
|||||||
not already a trace-cmd on the device, an error is raised.
|
not already a trace-cmd on the device, an error is raised.
|
||||||
|
|
||||||
"""),
|
"""),
|
||||||
|
Parameter('report_on_target', kind=boolean, default=False,
|
||||||
|
description="""
|
||||||
|
When enabled generation of reports will be done host-side because the generated file is
|
||||||
|
very large. If trace-cmd is not available on the host device this setting and be disabled
|
||||||
|
and the report will be generated on the target device.
|
||||||
|
|
||||||
|
.. note:: This requires the latest version of trace-cmd to be installed on the host (the
|
||||||
|
one in your distribution's repos may be too old).
|
||||||
|
"""),
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, device, **kwargs):
|
def __init__(self, device, **kwargs):
|
||||||
@ -227,45 +231,35 @@ class TraceCmdInstrument(Instrument):
|
|||||||
# 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
|
||||||
# accordingly.
|
# accordingly.
|
||||||
pull_timeout = (self.stop_time - self.start_time)
|
self._pull_timeout = (self.stop_time - self.start_time) # pylint: disable=attribute-defined-outside-init
|
||||||
self.device.pull_file(self.output_file, context.output_directory, timeout=pull_timeout)
|
self.device.pull_file(self.output_file, context.output_directory, timeout=self._pull_timeout)
|
||||||
context.add_iteration_artifact('bintrace', OUTPUT_TRACE_FILE, kind='data',
|
context.add_iteration_artifact('bintrace', OUTPUT_TRACE_FILE, kind='data',
|
||||||
description='trace-cmd generated ftrace dump.')
|
description='trace-cmd generated ftrace dump.')
|
||||||
|
|
||||||
local_trace_file = os.path.join(context.output_directory, OUTPUT_TRACE_FILE)
|
|
||||||
local_txt_trace_file = os.path.join(context.output_directory, OUTPUT_TEXT_FILE)
|
local_txt_trace_file = os.path.join(context.output_directory, OUTPUT_TEXT_FILE)
|
||||||
|
|
||||||
if self.report:
|
if self.report:
|
||||||
# To get the output of trace.dat, trace-cmd must be installed
|
# To get the output of trace.dat, trace-cmd must be installed
|
||||||
# This is done host-side because the generated file is very large
|
# By default this is done host-side because the generated file is
|
||||||
if not os.path.isfile(local_trace_file):
|
# very large
|
||||||
self.logger.warning('Not generating trace.txt, as {} does not exist.'.format(OUTPUT_TRACE_FILE))
|
if self.report_on_target:
|
||||||
try:
|
self._generate_report_on_target(context)
|
||||||
command = 'trace-cmd report {} > {}'.format(local_trace_file, local_txt_trace_file)
|
else:
|
||||||
self.logger.debug(command)
|
self._generate_report_on_host(context)
|
||||||
process = subprocess.Popen(command, stderr=subprocess.PIPE, shell=True)
|
|
||||||
_, error = process.communicate()
|
if os.path.isfile(local_txt_trace_file):
|
||||||
if process.returncode:
|
context.add_iteration_artifact('txttrace', OUTPUT_TEXT_FILE, kind='export',
|
||||||
raise InstrumentError('trace-cmd returned non-zero exit code {}'.format(process.returncode))
|
description='trace-cmd generated ftrace dump.')
|
||||||
if error:
|
self.logger.debug('Verifying traces.')
|
||||||
# logged at debug level, as trace-cmd always outputs some
|
with open(local_txt_trace_file) as fh:
|
||||||
# errors that seem benign.
|
for line in fh:
|
||||||
self.logger.debug(error)
|
if 'EVENTS DROPPED' in line:
|
||||||
if os.path.isfile(local_txt_trace_file):
|
self.logger.warning('Dropped events detected.')
|
||||||
context.add_iteration_artifact('txttrace', OUTPUT_TEXT_FILE, kind='export',
|
break
|
||||||
description='trace-cmd generated ftrace dump.')
|
else:
|
||||||
self.logger.debug('Verifying traces.')
|
self.logger.debug('Trace verified.')
|
||||||
with open(local_txt_trace_file) as fh:
|
else:
|
||||||
for line in fh:
|
self.logger.warning('Could not generate trace.txt.')
|
||||||
if 'EVENTS DROPPED' in line:
|
|
||||||
self.logger.warning('Dropped events detected.')
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
self.logger.debug('Trace verified.')
|
|
||||||
else:
|
|
||||||
self.logger.warning('Could not generate trace.txt.')
|
|
||||||
except OSError:
|
|
||||||
raise InstrumentError('Could not find trace-cmd. Please make sure it is installed and is in PATH.')
|
|
||||||
|
|
||||||
def teardown(self, context):
|
def teardown(self, context):
|
||||||
self.device.delete_file(os.path.join(self.device.working_directory, OUTPUT_TRACE_FILE))
|
self.device.delete_file(os.path.join(self.device.working_directory, OUTPUT_TRACE_FILE))
|
||||||
@ -315,8 +309,37 @@ class TraceCmdInstrument(Instrument):
|
|||||||
self.logger.warning('Failed to set trace buffer size to {}, value set was {}'.format(target_buffer_size, buffer_size))
|
self.logger.warning('Failed to set trace buffer size to {}, value set was {}'.format(target_buffer_size, buffer_size))
|
||||||
break
|
break
|
||||||
|
|
||||||
|
def _generate_report_on_target(self, context):
|
||||||
|
try:
|
||||||
|
trace_file = self.output_file
|
||||||
|
txt_trace_file = os.path.join(self.device.working_directory, OUTPUT_TEXT_FILE)
|
||||||
|
command = 'trace-cmd report {} > {}'.format(trace_file, txt_trace_file)
|
||||||
|
self.device.execute(command)
|
||||||
|
self.device.pull_file(txt_trace_file, context.output_directory, timeout=self._pull_timeout)
|
||||||
|
except DeviceError:
|
||||||
|
raise InstrumentError('Could not generate TXT report on target.')
|
||||||
|
|
||||||
|
def _generate_report_on_host(self, context):
|
||||||
|
local_trace_file = os.path.join(context.output_directory, OUTPUT_TRACE_FILE)
|
||||||
|
local_txt_trace_file = os.path.join(context.output_directory, OUTPUT_TEXT_FILE)
|
||||||
|
command = 'trace-cmd report {} > {}'.format(local_trace_file, local_txt_trace_file)
|
||||||
|
self.logger.debug(command)
|
||||||
|
if not os.path.isfile(local_trace_file):
|
||||||
|
self.logger.warning('Not generating trace.txt, as {} does not exist.'.format(OUTPUT_TRACE_FILE))
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
process = subprocess.Popen(command, stderr=subprocess.PIPE, shell=True)
|
||||||
|
_, error = process.communicate()
|
||||||
|
if process.returncode:
|
||||||
|
raise InstrumentError('trace-cmd returned non-zero exit code {}'.format(process.returncode))
|
||||||
|
if error:
|
||||||
|
# logged at debug level, as trace-cmd always outputs some
|
||||||
|
# errors that seem benign.
|
||||||
|
self.logger.debug(error)
|
||||||
|
except OSError:
|
||||||
|
raise InstrumentError('Could not find trace-cmd. Please make sure it is installed and is in PATH.')
|
||||||
|
|
||||||
|
|
||||||
def _build_trace_events(events):
|
def _build_trace_events(events):
|
||||||
event_string = ' '.join(['-e {}'.format(e) for e in events])
|
event_string = ' '.join(['-e {}'.format(e) for e in events])
|
||||||
return event_string
|
return event_string
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user