summaryrefslogtreecommitdiff
path: root/simpleperf
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2017-06-21 12:19:36 -0700
committerYabin Cui <yabinc@google.com>2017-06-21 17:17:11 -0700
commitccf7a5eb35c30401670916250c27e4b79a4c8473 (patch)
treeb8af8e1e5ba6df6410d7b05fc4fae82cdba1406c /simpleperf
parent2c60e40066efabc7c7c5c9f920f45003b052ecbc (diff)
downloadextras-ccf7a5eb35c30401670916250c27e4b79a4c8473.tar.gz
simpleperf: Support Ctrl-C in app_profiler.py.
Bug: http://b/32834638 Test: kill app_profiler.py with Ctrl-C manually. Change-Id: I03b8813080b45e324c66ce3de27e5dd1f8849446
Diffstat (limited to 'simpleperf')
-rw-r--r--simpleperf/scripts/app_profiler.config2
-rw-r--r--simpleperf/scripts/app_profiler.py49
2 files changed, 42 insertions, 9 deletions
diff --git a/simpleperf/scripts/app_profiler.config b/simpleperf/scripts/app_profiler.config
index 63dbd962..752b85f7 100644
--- a/simpleperf/scripts/app_profiler.config
+++ b/simpleperf/scripts/app_profiler.config
@@ -49,7 +49,7 @@ if recompile_app and not launch_activity and not launch_inst_test:
# Profiling record options that will be passed directly to `simpleperf record` command on device.
-# As we can't stop profiling by Ctrl-C, we need to set how long to profile using "--duration".
+# You can set how long to profile using "--duration" option, or use Ctrl-C to stop profiling.
record_options = "-e cpu-cycles:u -f 4000 -g --duration 10"
diff --git a/simpleperf/scripts/app_profiler.py b/simpleperf/scripts/app_profiler.py
index 25098d30..055a2022 100644
--- a/simpleperf/scripts/app_profiler.py
+++ b/simpleperf/scripts/app_profiler.py
@@ -265,9 +265,35 @@ class AppProfiler(object):
def start_and_wait_profiling(self):
- self.run_in_app_dir([
- './simpleperf', 'record', self.config['record_options'], '-p',
- str(self.app_pid), '--symfs', '.'])
+ subproc = None
+ returncode = None
+ try:
+ args = self.get_run_in_app_dir_args([
+ './simpleperf', 'record', self.config['record_options'], '-p',
+ str(self.app_pid), '--symfs', '.'])
+ adb_args = [self.adb.adb_path] + args
+ log_debug('run adb cmd: %s' % adb_args)
+ subproc = subprocess.Popen(adb_args)
+ returncode = subproc.wait()
+ except KeyboardInterrupt:
+ if subproc:
+ self.stop_profiling()
+ returncode = 0
+ log_debug('run adb cmd: %s [result %s]' % (adb_args, returncode == 0))
+
+
+ def stop_profiling(self):
+ """ Stop profiling by sending SIGINT to simpleperf, and wait until it exits
+ to make sure perf.data is completely generated."""
+ has_killed = False
+ while True:
+ (result, _) = self.run_in_app_dir(['pidof', 'simpleperf'], check_result=False)
+ if not result:
+ break
+ if not has_killed:
+ has_killed = True
+ self.run_in_app_dir(['pkill', '-l', '2', 'simpleperf'], check_result=False)
+ time.sleep(1)
def collect_profiling_data(self):
@@ -280,13 +306,20 @@ class AppProfiler(object):
binary_cache_builder.build_binary_cache()
- def run_in_app_dir(self, args, stdout_file=None):
+ def run_in_app_dir(self, args, stdout_file=None, check_result=True):
+ args = self.get_run_in_app_dir_args(args)
+ if check_result:
+ return self.adb.check_run_and_return_output(args, stdout_file)
+ else:
+ return self.adb.run_and_return_output(args, stdout_file)
+
+
+ def get_run_in_app_dir_args(self, args):
if self.is_root_device:
- cmd = 'cd /data/data/' + self.config['app_package_name'] + ' && ' + (' '.join(args))
- return self.adb.check_run_and_return_output(['shell', cmd], stdout_file)
+ return ['shell', 'cd /data/data/' + self.config['app_package_name'] + ' && ' +
+ (' '.join(args))]
else:
- return self.adb.check_run_and_return_output(
- ['shell', 'run-as', self.config['app_package_name']] + args, stdout_file)
+ return ['shell', 'run-as', self.config['app_package_name']] + args
if __name__ == '__main__':