Update the interface to make use of the collector interface.
Notable changes are the removal of the `output_path` path provided on
initialisation which will now be provided by the dedicated `set_output`
method.
Update `get_trace` to `get_data` to better reflect the purpose.
The return type of said method will be a `CollectorOutput` object will
contain one or more `CollectorOutputEntry` objects which will be used to
provide the `path`and `path_kind` attributes to indicate the path to the
obtained output and it's type (currently a "file" or "directory")
respectively.
The `AndroidTarget` class should not depend on ADB specific commands as
is is possible to use this target with other connection types e.g. ssh.
Therefore move the adb specific commands into the `AdbConnection`.
- `wait_for_device` and `reboot_bootloader` are now exposed in AndroidTarget
as generic methods and call through to the connection method.
- `adb_kill_server` is now a standalone function of the AdbConnection.
The `AndroidTarget` would ensure that when connecting to a IP target
that it disconnected first to prevent the connection getting stuck if
the connection was not closed correctly. Move this code into the
`AdbConnection` instead as this is more relevant.
While reading the DT-provided capacity values (exposed in sysfs) is
sufficient, get_capacities() also unconditionally fetches data from the
sched_domain procfs, which is only populated on kernels compiled with
CONFIG_SCHED_DEBUG.
Tweak the logic to only call get_sd_info() if it is both possible and
required.
This tracer is similar to the 'function_graph' tracer in that it helps us
trace function calls. It is however more lightweight, and only traces
functions entries (along with the caller of the function). It can also
happen that the kernel has support for the 'function' tracer but not for
'function_graph' (the opposite cannot be true, however).
We currently raise an exception when trying to use the 'function' or
'function_graph' tracer if the kernel wasn't compiled
CONFIG_FUNCTION_PROFILER, but that is a completely valid use.
Move the resolution of the model name from targets into Platform's
_set_model_from_target() (which was already attempting to do that via
dmidecode method).
The teardown() method was introduced in bb1552151a32 ("instruments:
Add teardown method to clean up tempfiles") but it uses an undeclared
variable tempdir. Make tempdir an object variable so that it can be
used in teardown().
The user can pass a dictionary containg the key and value
pairs with the extra ssh configuration options. Multiple
options will be passed as '-o key1=value1 -o key2=value2'
Signed-off-by: Michalis Spyrou <michalis.spyrou@arm.com>
The content of /proc/kallsyms depends on the value of
/proc/sys/kernel/kptr_restrict:
* If 0, restriction is lifted and kallsyms contains real addresses
* If 1, kallsyms will contain null pointers
Since trace-cmd records the content of kallsyms into the trace.dat and uses that
to pretty-print function names (function tracer/grapher), ensure that its
content is available.
Signed-off-by: Douglas RAILLARD <douglas.raillard@arm.com>
Unpickling of BaseException is done by feeding self.args to the exception type.
This self.args attribute is initialized in two places: in
BaseException.__new__ (before __init__ is called) and in BaseException.__init__
as well.
The following code ends up with self.args == ('hello',), instead of (1, 2):
class MyExcep(BaseException):
def __init__(self, foo, bar):
print('before super().__init__()', self.args)
super().__init__('hello')
print('after super().__init__()', self.args)
MyExcep(1, 2)
# Prints:
# before super().__init__() (1, 2)
# after super().__init__() ('hello',)
When unplickling such instance, ('hello',) will be fed to MyExcep.__init__(),
which will fail with a TypeError since it requires 2 positional arguments.
In order to fix that, super().__init__() needs to be handwritten instead of
getting the one from BaseException:
class MyBase(BaseException):
def __init__(self, msg):
self.msg = msg
class MyExcep(MyBase):
def __init__(self, foo, bar):
print('before super().__init__()', self.args)
super().__init__('hello')
print('after super().__init__()', self.args)
MyExcep(1, 2)
# Prints:
# before super().__init__() (1, 2)
# after super().__init__() (1, 2)
This will correctly initialize self.args == (1, 2), allowing unpickling to work.
The docstring of Controller.move_all_tasks_to() says that the function
moves all the tasks to the "dest" cgroup. However, it iterates over
self._cgroups, which is a dictionary that is lazily populated when you
call Controller.cgroup(). For example, this doesn't work:
cpuset_cg = target.cgroups.controller("cpuset")
cpuset_cg.move_all_tasks_to("top-app")
Because you haven't populated self._cgroups yet. You need to manually
populate the dictionary with something like:
for group in cpuset_cg.list_all():
cpuset_cg.cgroup(group)
before you can use move_all_tasks_to(). Iterate through
self.list_all() instead of self._cgroups to really move all tasks to
to the destination directory.
Controller.move_tasks() has a try-except block to get the cgroups of
the source and destination groups. Controller.cgroup() caches the
groups in self._cgroups and populates it if it hasn't been already.
Simplify move_tasks() and let it deal with source and dest cgroups
that exist but the controller hasn't loaded yet.
Not all devices have the `saved_cmdlines_size` node exposed and therefore
attempting to set this can fail. Raise an error for this only when
`strict` is set to `True` otherwise raise a warning instead.
Emit one warning message or one exception referring to the whole list of
unavailable events, rather than spreading it through multiple calls. In strict
mode, this allows the user to fix the whole list of bogus events at once rather
than incrementally.
Signed-off-by: Douglas RAILLARD <douglas.raillard@arm.com>
"function_graph" tracer allows getting funcgraph_entry/funcgraph_exit events for
listed functions. This allows getting precise information on when a given
function was called, and how long its execution took (to build a time-based
heatmap for example).
This can be enabled using:
FtraceCollector(target, functions=['foo', 'bar'], tracer='function_graph')
If needed, children functions can also be traced with
trace_children_functions=True .
Signed-off-by: Douglas RAILLARD <douglas.raillard@arm.com>
While tracing, ftrace records a mapping of PIDs to cmdlines. By default, it will
only record up to 128 such entries, which is not enough for a typical android
system. The consequence is trace-cmd reporting "<...>" as cmdline.
Allow setting that number to a higher value, and default to a comfortable 4096
entries.
Signed-off-by: Douglas RAILLARD <douglas.raillard@arm.com>
trace-cmd start -C <clock> allows selecting the ftrace clock. Expose that in
FtraceCollector API.
Signed-off-by: Douglas RAILLARD <douglas.raillard@arm.com>
On newer devices dumpsys output is more explanatory and does not only
contain numerical data. Update the parser to ignore non numerical
data for example the arguments that were passed and section headers.
As of commit 5601fdb1085af2eccf16a84b48c9995699bb8489 the
`connected_as_root` status is tracked in the connection. Add missing
implementation to `LocalConnection`.
A `Target` should be independent of the connection type used however we
do have some adb specific functionality as part of the `Target` for
speed/compatibility reasons. For the cases that we can perform the
operation in a connection agnostic method add alternative implementation
and for those raise a error to inform the user of the issue.
Un-memoize the `is_rooted` property of the connection and perform our
own caching instead as the state can be changed depending on the
connection status.