148f512ceSopenharmony_ci#!/usr/bin/env python
248f512ceSopenharmony_ci# -*- coding: utf-8 -*-
348f512ceSopenharmony_ci#   Copyright (c) 2021 Huawei Device Co., Ltd.
448f512ceSopenharmony_ci#   Licensed under the Apache License, Version 2.0 (the "License");
548f512ceSopenharmony_ci#   you may not use this file except in compliance with the License.
648f512ceSopenharmony_ci#   You may obtain a copy of the License at
748f512ceSopenharmony_ci#
848f512ceSopenharmony_ci#       http://www.apache.org/licenses/LICENSE-2.0
948f512ceSopenharmony_ci#
1048f512ceSopenharmony_ci#   Unless required by applicable law or agreed to in writing, software
1148f512ceSopenharmony_ci#   distributed under the License is distributed on an "AS IS" BASIS,
1248f512ceSopenharmony_ci#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1348f512ceSopenharmony_ci#   See the License for the specific language governing permissions and
1448f512ceSopenharmony_ci#   limitations under the License.
1548f512ceSopenharmony_ci
1648f512ceSopenharmony_ciimport os
1748f512ceSopenharmony_ciimport time
1848f512ceSopenharmony_ciimport argparse
1948f512ceSopenharmony_ciimport subprocess
2048f512ceSopenharmony_cifrom hiperf_utils import HdcInterface
2148f512ceSopenharmony_cifrom hiperf_utils import get_build_id
2248f512ceSopenharmony_cifrom hiperf_utils import get_architecture
2348f512ceSopenharmony_cifrom hiperf_utils import PerformanceProfile
2448f512ceSopenharmony_cifrom hiperf_utils import dir_check
2548f512ceSopenharmony_cifrom hiperf_utils import get_hiperf_binary_path
2648f512ceSopenharmony_cifrom hiperf_utils import bytes_to_str
2748f512ceSopenharmony_cifrom hiperf_utils import str_to_bytes
2848f512ceSopenharmony_cifrom hiperf_utils import remove
2948f512ceSopenharmony_ci
3048f512ceSopenharmony_ci
3148f512ceSopenharmony_cidef check_args(args):
3248f512ceSopenharmony_ci    if (not args.package_name) and args.ability:
3348f512ceSopenharmony_ci        raise Exception('-a can only be used when profiling an OHOS '
3448f512ceSopenharmony_ci                        'package_name.')
3548f512ceSopenharmony_ci    return True
3648f512ceSopenharmony_ci
3748f512ceSopenharmony_ci
3848f512ceSopenharmony_cidef get_module(args):
3948f512ceSopenharmony_ci    if args.prepare:
4048f512ceSopenharmony_ci        return "prepare"
4148f512ceSopenharmony_ci    elif args.start:
4248f512ceSopenharmony_ci        return "start"
4348f512ceSopenharmony_ci    elif args.pause:
4448f512ceSopenharmony_ci        return "pause"
4548f512ceSopenharmony_ci    elif args.resume:
4648f512ceSopenharmony_ci        return "resume"
4748f512ceSopenharmony_ci    elif args.stop:
4848f512ceSopenharmony_ci        return "stop"
4948f512ceSopenharmony_ci
5048f512ceSopenharmony_ci
5148f512ceSopenharmony_cidef parser_add_argument():
5248f512ceSopenharmony_ci    description = "Collect performance sampling information of" \
5348f512ceSopenharmony_ci                  " running [command]."
5448f512ceSopenharmony_ci    parser = argparse.ArgumentParser(description=description)
5548f512ceSopenharmony_ci
5648f512ceSopenharmony_ci    control_group = parser.add_argument_group(
5748f512ceSopenharmony_ci        'Select Control options').add_mutually_exclusive_group(required=True)
5848f512ceSopenharmony_ci    control_group.add_argument('--prepare', action='store_true',
5948f512ceSopenharmony_ci                               help='prepare need to add profiling target to '
6048f512ceSopenharmony_ci                                    'execute record .'
6148f512ceSopenharmony_ci                                    'Like --prepare -p 121')
6248f512ceSopenharmony_ci    control_group.add_argument('--start', action='store_true',
6348f512ceSopenharmony_ci                               help='start execute hiperf record')
6448f512ceSopenharmony_ci    control_group.add_argument('--pause', action='store_true',
6548f512ceSopenharmony_ci                               help='pause execute hiperf record')
6648f512ceSopenharmony_ci    control_group.add_argument('--resume', action='store_true',
6748f512ceSopenharmony_ci                               help='pause execute hiperf record')
6848f512ceSopenharmony_ci    control_group.add_argument('--stop', action='store_true',
6948f512ceSopenharmony_ci                               help='stop execute hiperf record'
7048f512ceSopenharmony_ci                                    'and file recv data file to local')
7148f512ceSopenharmony_ci
7248f512ceSopenharmony_ci    target_group = parser.add_argument_group(title='Select profiling target') \
7348f512ceSopenharmony_ci        .add_mutually_exclusive_group(required=False)
7448f512ceSopenharmony_ci    target_group.add_argument('-app', '--package_name',
7548f512ceSopenharmony_ci                              help="""Collect profile info for an OHOS app""")
7648f512ceSopenharmony_ci
7748f512ceSopenharmony_ci    target_group.add_argument('-lp', '--local_program',
7848f512ceSopenharmony_ci                              help="""Collect profile info
7948f512ceSopenharmony_ci                               for an local program.""")
8048f512ceSopenharmony_ci
8148f512ceSopenharmony_ci    target_group.add_argument('-cmd',
8248f512ceSopenharmony_ci                              help="""Running a command on the OHOS device.
8348f512ceSopenharmony_ci                              like as : -cmd "'ps -ef'".
8448f512ceSopenharmony_ci                              the ps will open as child process of hiperf
8548f512ceSopenharmony_ci                              and sample this process.""")
8648f512ceSopenharmony_ci
8748f512ceSopenharmony_ci    target_group.add_argument('-p', '--pid', nargs='*',
8848f512ceSopenharmony_ci                              help="""Limit the process id of the collection
8948f512ceSopenharmony_ci                         target.""")
9048f512ceSopenharmony_ci
9148f512ceSopenharmony_ci    target_group.add_argument('-t', '--tid', nargs='*',
9248f512ceSopenharmony_ci                              help="""Limit the thread id of the collection
9348f512ceSopenharmony_ci                        target.""")
9448f512ceSopenharmony_ci
9548f512ceSopenharmony_ci    target_group.add_argument('-sw', '--system_wide', action='store_true',
9648f512ceSopenharmony_ci                              help="""Collect system-wide information.
9748f512ceSopenharmony_ci                        This requires CAP_PERFMON (since Linux 5.8) or
9848f512ceSopenharmony_ci                        CAP_SYS_ADMIN capability or a
9948f512ceSopenharmony_ci                        /proc/sys/kernel/perf_event_paranoid
10048f512ceSopenharmony_ci                        value of less than 1.""")
10148f512ceSopenharmony_ci
10248f512ceSopenharmony_ci    record_group = parser.add_argument_group('Select recording options')
10348f512ceSopenharmony_ci    record_group.add_argument('-a', '--ability',
10448f512ceSopenharmony_ci                              help="""Used with -p. Profile the launch time of
10548f512ceSopenharmony_ci                        an ability in an OHOS app. The app will be started or
10648f512ceSopenharmony_ci                        restarted to run the ability.
10748f512ceSopenharmony_ci                        Like : -a .MainAbility """)
10848f512ceSopenharmony_ci
10948f512ceSopenharmony_ci    record_group.add_argument('-r', '--record_options',
11048f512ceSopenharmony_ci                              default='-f 1000 -s dwarf',
11148f512ceSopenharmony_ci                              help="""Set recording options for `hiperf record`
11248f512ceSopenharmony_ci                         command. Default is "'-f 1000 -s dwarf'".""")
11348f512ceSopenharmony_ci
11448f512ceSopenharmony_ci    record_group.add_argument('-lib', '--local_lib_dir', type=dir_check,
11548f512ceSopenharmony_ci                              help="""When profiling an OHOS app containing
11648f512ceSopenharmony_ci                         local thelocal libraries are usually stripped and lake
11748f512ceSopenharmony_ci                         of symbols and debug information to provide good
11848f512ceSopenharmony_ci                         profiling result. By using -lib, you tell
11948f512ceSopenharmony_ci                         command_script.py the path storing unstripped local
12048f512ceSopenharmony_ci                         libraries, and script will search all shared libraries
12148f512ceSopenharmony_ci                         with suffix .so in the directory. Then the local
12248f512ceSopenharmony_ci                         libraries will be downloaded on device and collected
12348f512ceSopenharmony_ci                         in build_cache.""")
12448f512ceSopenharmony_ci
12548f512ceSopenharmony_ci    record_group.add_argument('-o', '--output_perf_data', default='perf.data',
12648f512ceSopenharmony_ci                              help='The path to store profiling data. '
12748f512ceSopenharmony_ci                                   'Default is perf.data.')
12848f512ceSopenharmony_ci
12948f512ceSopenharmony_ci    other_group = parser.add_argument_group('Other options')
13048f512ceSopenharmony_ci
13148f512ceSopenharmony_ci    other_group.add_argument('--not_hdc_root', action='store_true',
13248f512ceSopenharmony_ci                             help="""Force hdc to run in non root mode. """)
13348f512ceSopenharmony_ci
13448f512ceSopenharmony_ci    args = parser.parse_args()
13548f512ceSopenharmony_ci    return args
13648f512ceSopenharmony_ci
13748f512ceSopenharmony_ci
13848f512ceSopenharmony_cidef main(args):
13948f512ceSopenharmony_ci    check_args(args)
14048f512ceSopenharmony_ci    args_mark = [args.package_name, args.local_program, args.cmd,
14148f512ceSopenharmony_ci                 args.pid, args.tid, args.system_wide]
14248f512ceSopenharmony_ci    any_args = any(args_mark)
14348f512ceSopenharmony_ci    if args.prepare and not any_args:
14448f512ceSopenharmony_ci        print("prepare need one of -app/-lp/-cmd/-p/-t/-sw "
14548f512ceSopenharmony_ci              "argument to execute record")
14648f512ceSopenharmony_ci        return False
14748f512ceSopenharmony_ci    profiler = PerformanceProfile(args, control_module=get_module(args))
14848f512ceSopenharmony_ci    profiler.profile()
14948f512ceSopenharmony_ci    return True
15048f512ceSopenharmony_ci
15148f512ceSopenharmony_ci
15248f512ceSopenharmony_ciif __name__ == '__main__':
15348f512ceSopenharmony_ci    main(parser_add_argument())
154