Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(171)

Unified Diff: tools/telemetry/telemetry/core/platform/profiler/perf_profiler.py

Issue 290173006: telemetry: Improve symfs generation on Android (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Mock out perf binary. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/telemetry/core/platform/profiler/perf_profiler.py
diff --git a/tools/telemetry/telemetry/core/platform/profiler/perf_profiler.py b/tools/telemetry/telemetry/core/platform/profiler/perf_profiler.py
index 49ecc7cca0f79d2629f1bc42c7131419ac09476b..53ff8af68d2637f416d2600a313274a56b35ca23 100644
--- a/tools/telemetry/telemetry/core/platform/profiler/perf_profiler.py
+++ b/tools/telemetry/telemetry/core/platform/profiler/perf_profiler.py
@@ -12,7 +12,7 @@ import tempfile
from telemetry.core import util
from telemetry.core.platform import profiler
-from telemetry.core.platform.profiler import android_prebuilt_profiler_helper
+from telemetry.core.platform.profiler import android_profiling_helper
class _SingleProcessPerfProfiler(object):
@@ -21,7 +21,8 @@ class _SingleProcessPerfProfiler(object):
On android, this profiler uses pre-built binaries from AOSP.
See more details in prebuilt/android/README.txt.
"""
- def __init__(self, pid, output_file, browser_backend, platform_backend):
+ def __init__(self, pid, output_file, browser_backend, platform_backend,
+ perf_binary):
self._pid = pid
self._browser_backend = browser_backend
self._platform_backend = platform_backend
@@ -30,8 +31,6 @@ class _SingleProcessPerfProfiler(object):
self._is_android = platform_backend.GetOSName() == 'android'
cmd_prefix = []
if self._is_android:
- perf_binary = android_prebuilt_profiler_helper.GetDevicePath(
- 'perf')
cmd_prefix = ['adb', '-s', browser_backend.adb.device_serial(), 'shell',
perf_binary]
output_file = os.path.join('/sdcard', 'perf_profiles',
@@ -39,8 +38,9 @@ class _SingleProcessPerfProfiler(object):
self._device_output_file = output_file
browser_backend.adb.RunShellCommand(
'mkdir -p ' + os.path.dirname(self._device_output_file))
+ browser_backend.adb.RunShellCommand('rm -f ' + self._device_output_file)
else:
- cmd_prefix = ['perf']
+ cmd_prefix = [perf_binary]
# In perf 3.13 --call-graph requires an argument, so use
# the -g short-hand which does not.
self._proc = subprocess.Popen(cmd_prefix +
@@ -79,81 +79,30 @@ Try rerunning this script under sudo or setting
self._tmp_output_file.close()
cmd = 'perf report -n -i %s' % self._output_file
if self._is_android:
- print 'On Android, assuming $CHROMIUM_OUT_DIR/Release/lib has a fresh'
- print 'symbolized library matching the one on device.'
+ device = self._browser_backend.adb.device()
+ device.old_interface.Adb().Pull(self._device_output_file,
+ self._output_file)
+ required_libs = \
+ android_profiling_helper.GetRequiredLibrariesForPerfProfile(
+ self._output_file)
+ symfs_root = os.path.dirname(self._output_file)
+ kallsyms = android_profiling_helper.CreateSymFs(device,
+ symfs_root,
+ required_libs,
+ use_symlinks=True)
+ cmd += ' --symfs %s --kallsyms %s' % (symfs_root, kallsyms)
+
objdump_path = os.path.join(os.environ.get('ANDROID_TOOLCHAIN',
'$ANDROID_TOOLCHAIN'),
'arm-linux-androideabi-objdump')
print 'If you have recent version of perf (3.10+), append the following '
print 'to see annotated source code (by pressing the \'a\' key): '
print ' --objdump %s' % objdump_path
- cmd += ' ' + ' '.join(self._PrepareAndroidSymfs())
+
print 'To view the profile, run:'
print ' ', cmd
return self._output_file
- def _PrepareAndroidSymfs(self):
- """Create a symfs directory using an Android device.
-
- Create a symfs directory by pulling the necessary files from an Android
- device.
-
- Returns:
- List of arguments to be passed to perf to point it to the created symfs.
- """
- assert self._is_android
- device = self._browser_backend.adb.device()
- device.old_interface.Adb().Pull(self._device_output_file, self._output_file)
- symfs_dir = os.path.dirname(self._output_file)
- host_app_symfs = os.path.join(symfs_dir, 'data', 'app-lib')
- if not os.path.exists(host_app_symfs):
- os.makedirs(host_app_symfs)
- # On Android, the --symfs parameter needs to map a directory structure
- # similar to the device, that is:
- # --symfs=/tmp/foobar and then inside foobar there'll be something like
- # /tmp/foobar/data/app-lib/$PACKAGE/libname.so
- # Assume the symbolized library under out/Release/lib is equivalent to
- # the one in the device, and symlink it in the host to match --symfs.
- device_dir = filter(
- lambda app_lib: app_lib.startswith(self._browser_backend.package),
- device.old_interface.RunShellCommand('ls /data/app-lib'))
- os.symlink(os.path.abspath(
- os.path.join(util.GetChromiumSrcDir(),
- os.environ.get('CHROMIUM_OUT_DIR', 'out'),
- 'Release', 'lib')),
- os.path.join(host_app_symfs, device_dir[0]))
-
- # Also pull copies of common system libraries from the device so perf can
- # resolve their symbols. Only copy a subset of libraries to make this
- # faster.
- # TODO(skyostil): Find a way to pull in all system libraries without being
- # too slow.
- host_system_symfs = os.path.join(symfs_dir, 'system', 'lib')
- if not os.path.exists(host_system_symfs):
- os.makedirs(host_system_symfs)
- common_system_libs = [
- 'libandroid*.so',
- 'libart.so',
- 'libc.so',
- 'libdvm.so',
- 'libEGL*.so',
- 'libGL*.so',
- 'libm.so',
- 'libRS.so',
- 'libskia.so',
- 'libstdc++.so',
- 'libstlport.so',
- 'libz.so',
- ]
- for lib in common_system_libs:
- device.old_interface.Adb().Pull('/system/lib/%s' % lib,
- host_system_symfs)
- # Pull a copy of the kernel symbols.
- host_kallsyms = os.path.join(symfs_dir, 'kallsyms')
- if not os.path.exists(host_kallsyms):
- device.old_interface.Adb().Pull('/proc/kallsyms', host_kallsyms)
- return ['--kallsyms', host_kallsyms, '--symfs', symfs_dir]
-
def _GetStdOut(self):
self._tmp_output_file.flush()
try:
@@ -170,18 +119,17 @@ class PerfProfiler(profiler.Profiler):
browser_backend, platform_backend, output_path, state)
process_output_file_map = self._GetProcessOutputFileMap()
self._process_profilers = []
+ perf_binary = 'perf'
if platform_backend.GetOSName() == 'android':
- android_prebuilt_profiler_helper.InstallOnDevice(
- browser_backend.adb.device(), 'perf')
- # Make sure kernel pointers are not hidden.
- browser_backend.adb.device().old_interface.SetProtectedFileContents(
- '/proc/sys/kernel/kptr_restrict', '0')
+ perf_binary = android_profiling_helper.PrepareDeviceForPerf(
+ browser_backend.adb.device())
+
for pid, output_file in process_output_file_map.iteritems():
if 'zygote' in output_file:
continue
self._process_profilers.append(
_SingleProcessPerfProfiler(
- pid, output_file, browser_backend, platform_backend))
+ pid, output_file, browser_backend, platform_backend, perf_binary))
@classmethod
def name(cls):

Powered by Google App Engine
This is Rietveld 408576698