148f512ceSopenharmony_ci/*
248f512ceSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
448f512ceSopenharmony_ci * you may not use this file except in compliance with the License.
548f512ceSopenharmony_ci * You may obtain a copy of the License at
648f512ceSopenharmony_ci *
748f512ceSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
848f512ceSopenharmony_ci *
948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and
1348f512ceSopenharmony_ci * limitations under the License.
1448f512ceSopenharmony_ci */
1548f512ceSopenharmony_ci#ifndef SUBCOMMAND_RECORD_H
1648f512ceSopenharmony_ci#define SUBCOMMAND_RECORD_H
1748f512ceSopenharmony_ci
1848f512ceSopenharmony_ci// some debug feaure
1948f512ceSopenharmony_ci#define HIDEBUG_RECORD_NOT_PROCESS       0
2048f512ceSopenharmony_ci#define HIDEBUG_RECORD_NOT_PROCESS_VM    0
2148f512ceSopenharmony_ci#define HIDEBUG_RECORD_NOT_SAVE          0
2248f512ceSopenharmony_ci#define HIDEBUG_SKIP_PROCESS_SYMBOLS     0
2348f512ceSopenharmony_ci#define HIDEBUG_SKIP_MATCH_SYMBOLS       0
2448f512ceSopenharmony_ci#define HIDEBUG_SKIP_LOAD_KERNEL_SYMBOLS 0
2548f512ceSopenharmony_ci#define HIDEBUG_SKIP_SAVE_SYMBOLS        0
2648f512ceSopenharmony_ci#define USE_COLLECT_SYMBOLIC             1
2748f512ceSopenharmony_ci
2848f512ceSopenharmony_ci#include <functional>
2948f512ceSopenharmony_ci#include <thread>
3048f512ceSopenharmony_ci#include <unordered_map>
3148f512ceSopenharmony_ci#include <unordered_set>
3248f512ceSopenharmony_ci#include <chrono>
3348f512ceSopenharmony_ci#include "perf_event_record.h"
3448f512ceSopenharmony_ci#include "perf_events.h"
3548f512ceSopenharmony_ci#include "perf_file_writer.h"
3648f512ceSopenharmony_ci#include "subcommand.h"
3748f512ceSopenharmony_ci#include "virtual_runtime.h"
3848f512ceSopenharmony_ci
3948f512ceSopenharmony_cinamespace OHOS {
4048f512ceSopenharmony_cinamespace Developtools {
4148f512ceSopenharmony_cinamespace HiPerf {
4248f512ceSopenharmony_ciclass SubCommandRecord : public SubCommand {
4348f512ceSopenharmony_cipublic:
4448f512ceSopenharmony_ci    static constexpr int DEFAULT_CPU_PERCENT = 25;
4548f512ceSopenharmony_ci    static constexpr int MIN_CPU_PERCENT = 1;
4648f512ceSopenharmony_ci    static constexpr int MAX_CPU_PERCENT = 100;
4748f512ceSopenharmony_ci    static constexpr int MIN_SAMPLE_FREQUENCY = 1;
4848f512ceSopenharmony_ci    static constexpr int MAX_SAMPLE_FREQUENCY = 100000;
4948f512ceSopenharmony_ci    static constexpr int DEFAULT_MMAP_PAGES = 256;
5048f512ceSopenharmony_ci    static constexpr int MIN_PERF_MMAP_PAGE = 2;
5148f512ceSopenharmony_ci    static constexpr int MAX_PERF_MMAP_PAGE = 1024;
5248f512ceSopenharmony_ci    static constexpr int DEFAULT_CHECK_APP_MS = 10;
5348f512ceSopenharmony_ci    static constexpr int MIN_CHECK_APP_MS = 1;
5448f512ceSopenharmony_ci    static constexpr int MAX_CHECK_APP_MS = 200;
5548f512ceSopenharmony_ci    static constexpr float MIN_STOP_SECONDS = 0.100;
5648f512ceSopenharmony_ci    static constexpr float MAX_STOP_SECONDS = 10000.0;
5748f512ceSopenharmony_ci    static constexpr int MIN_SAVED_CMDLINES_SIZE = 512;
5848f512ceSopenharmony_ci    static constexpr int DEFAULT_SAVED_CMDLINES_SIZE = 2048;
5948f512ceSopenharmony_ci    static constexpr int MAX_SAVED_CMDLINES_SIZE = 4096;
6048f512ceSopenharmony_ci
6148f512ceSopenharmony_ci    SubCommandRecord()
6248f512ceSopenharmony_ci        // clang-format off
6348f512ceSopenharmony_ci        : SubCommand("record", "Collect performance sample information",
6448f512ceSopenharmony_ci        "Usage: hiperf record [options] [command [command-args]]\n"
6548f512ceSopenharmony_ci        "       Collect performance sampling information of running [command].\n"
6648f512ceSopenharmony_ci        "       The default options are: -c <all cpu> --cpu-limit 25 -d 10000.0 -e hw-cpu-cycles\n"
6748f512ceSopenharmony_ci        "       -f 4000 -m 1024 -o /data/local/tmp/perf.data.\n"
6848f512ceSopenharmony_ci        "   -a\n"
6948f512ceSopenharmony_ci        "         Collect system-wide information.\n"
7048f512ceSopenharmony_ci        "         for measures all processes/threads\n"
7148f512ceSopenharmony_ci        "         This requires CAP_PERFMON (since Linux 5.8) or CAP_SYS_ADMIN capability or a\n"
7248f512ceSopenharmony_ci        "         /proc/sys/kernel/perf_event_paranoid value of less than 1.\n"
7348f512ceSopenharmony_ci        "   --exclude-hiperf\n"
7448f512ceSopenharmony_ci        "         Don't record events issued by hiperf itself.\n"
7548f512ceSopenharmony_ci        "   -c <cpuid>[<,cpuid>]...\n"
7648f512ceSopenharmony_ci        "         cpuid should be 0,1,2...\n"
7748f512ceSopenharmony_ci        "         Limit the CPU that collects data.\n"
7848f512ceSopenharmony_ci        "         0 means cpu0, 1 means cpu1 ...\n"
7948f512ceSopenharmony_ci        "   --cpu-limit <percent>\n"
8048f512ceSopenharmony_ci        "         Set the max percent of cpu time used for recording.\n"
8148f512ceSopenharmony_ci        "         percent is in range [1-100], default is 25.\n"
8248f512ceSopenharmony_ci        "   -d <sec>\n"
8348f512ceSopenharmony_ci        "         stop in <sec> seconds. floating point number. seconds is in range [0.100-10000.0]\n"
8448f512ceSopenharmony_ci        "         default is 10000.0\n"
8548f512ceSopenharmony_ci        "   -f <freq>\n"
8648f512ceSopenharmony_ci        "         Set event sampling frequency. default is 4000 samples every second.\n"
8748f512ceSopenharmony_ci        "         check /proc/sys/kernel/perf_event_max_sample_rate for maximum allowed frequency\n"
8848f512ceSopenharmony_ci        "   --period <num>\n"
8948f512ceSopenharmony_ci        "         Set event sampling period for tracepoint events. recording one sample when <num> events happen.\n"
9048f512ceSopenharmony_ci        "         The default <num> is 1\n"
9148f512ceSopenharmony_ci        "   -e <event1[:<u|k>]>[,event1[:<u|k>]]...\n"
9248f512ceSopenharmony_ci        "         Customize the name of the event that needs to be sampled.\n"
9348f512ceSopenharmony_ci        "         The name can use the names listed in the list parameter.\n"
9448f512ceSopenharmony_ci        "         It can also be represented by the value of 0x<hex>.\n"
9548f512ceSopenharmony_ci        "           u - monitor user space events only\n"
9648f512ceSopenharmony_ci        "           k - monitor kernel space events only\n"
9748f512ceSopenharmony_ci        "   -g <event1[:<u|k>]>[,event1[:<u|k>]]...\n"
9848f512ceSopenharmony_ci        "         Put the events into a group, can set multiple groups by multiple -g\n"
9948f512ceSopenharmony_ci        "         PMU is required to report data in designated groups\n"
10048f512ceSopenharmony_ci        "         limited by HW capability, too many events cannot be reported in the same sampling)\n"
10148f512ceSopenharmony_ci        "   --no-inherit\n"
10248f512ceSopenharmony_ci        "         Don't trace child processes.\n"
10348f512ceSopenharmony_ci        "   -p <pid1>[,pid2]...\n"
10448f512ceSopenharmony_ci        "         Limit the process id of the collection target. Conflicts with the -a option.\n"
10548f512ceSopenharmony_ci        "   -t <tid1>[,tid2]...\n"
10648f512ceSopenharmony_ci        "         Limit the thread id of the collection target. Conflicts with the -a option.\n"
10748f512ceSopenharmony_ci        "   --exclude-tid <tid1>[,tid2]...\n"
10848f512ceSopenharmony_ci        "         Exclude threads of the collection target by thread ids. Conflicts with the -a option.\n"
10948f512ceSopenharmony_ci        "   --exclude-thread <tname1>[,tname2]...\n"
11048f512ceSopenharmony_ci        "         Exclude threads of the collection target by thread names. Conflicts with the -a option.\n"
11148f512ceSopenharmony_ci        "   --offcpu\n"
11248f512ceSopenharmony_ci        "         Trace when threads are scheduled off cpu.\n"
11348f512ceSopenharmony_ci        "   -j <branch_filter1>[,branch_filter2]...\n"
11448f512ceSopenharmony_ci        "         taken branch stack sampling, filter can be:\n"
11548f512ceSopenharmony_ci        "           any: any type of branch\n"
11648f512ceSopenharmony_ci        "           any_call: any function call or system call\n"
11748f512ceSopenharmony_ci        "           any_ret: any function return or system call return\n"
11848f512ceSopenharmony_ci        "           ind_call: any indirect branch\n"
11948f512ceSopenharmony_ci        "           ind_jmp: any indirect jump\n"
12048f512ceSopenharmony_ci        "           cond: conditional branches\n"
12148f512ceSopenharmony_ci        "           call: direct calls, including far (to/from kernel) calls\n"
12248f512ceSopenharmony_ci        "           u: only when the branch target is at the user level\n"
12348f512ceSopenharmony_ci        "           k: only when the branch target is in the kernel\n"
12448f512ceSopenharmony_ci        "         requires at least one of any, any_call, any_ret, ind_call, ind_jmp, cond, call\n"
12548f512ceSopenharmony_ci        "   -s / --call-stack <fp|dwarf[,size]>\n"
12648f512ceSopenharmony_ci        "         Setup and enable call stack (stack chain/backtrace) recording, Default is 'fp'.\n"
12748f512ceSopenharmony_ci        "           the value can be:\n"
12848f512ceSopenharmony_ci        "             fp: frame pointer\n"
12948f512ceSopenharmony_ci        "             dwarf: DWARF's CFI - Call Frame Information\n"
13048f512ceSopenharmony_ci        "               'dwarf,size' set sample stack size, size should be in 8~65528 and 8 byte aligned. \n"
13148f512ceSopenharmony_ci        "           as the method to collect the information used to show the call stacks.\n"
13248f512ceSopenharmony_ci        "   --kernel-callchain\n"
13348f512ceSopenharmony_ci        "         collect kernel callchain, must used with -s fp/dwarf simultaneously.\n"
13448f512ceSopenharmony_ci        "   --callchain-useronly\n"
13548f512ceSopenharmony_ci        "         collect only user callchain.\n"
13648f512ceSopenharmony_ci        "   --delay-unwind\n"
13748f512ceSopenharmony_ci        "         If '-s dwarf' used, stack will be unwind while recording, use this option to switch\n"
13848f512ceSopenharmony_ci        "         to unwind after recording.\n"
13948f512ceSopenharmony_ci        "   --disable-unwind\n"
14048f512ceSopenharmony_ci        "         If '-s dwarf' is used, stack will be unwind while recording by default\n"
14148f512ceSopenharmony_ci        "         use this option to disable unwinding.\n"
14248f512ceSopenharmony_ci        "   --disable-callstack-expand\n"
14348f512ceSopenharmony_ci        "         If '-s dwarf' is used, to break the 64k stack limit, callstack is merged by default\n"
14448f512ceSopenharmony_ci        "         to build more complete call stack. that may not be correct sometimes.\n"
14548f512ceSopenharmony_ci        "   --enable-debuginfo-symbolic\n"
14648f512ceSopenharmony_ci        "         If '-s fp/dwarf' is used, symbols in .gnu_debugdata section of an elf, also called minidebuginfo\n"
14748f512ceSopenharmony_ci        "         will be parsed, if not use this option, we will not parse minidebuginfo by default.\n"
14848f512ceSopenharmony_ci        "   --clockid <clock_id>\n"
14948f512ceSopenharmony_ci        "         Set the clock id to use for the various time fields in the perf_event_type records.\n"
15048f512ceSopenharmony_ci        "         monotonic and monotonic_raw are supported,\n"
15148f512ceSopenharmony_ci        "         some events might also allow boottime, realtime and clock_tai.\n"
15248f512ceSopenharmony_ci        "   --symbol-dir <dir>\n"
15348f512ceSopenharmony_ci        "         Set directory to look for symbol files, used for unwinding. \n"
15448f512ceSopenharmony_ci        "   -m <mmap_pages>\n"
15548f512ceSopenharmony_ci        "         Number of the mmap pages, used to receiving record data from kernel,\n"
15648f512ceSopenharmony_ci        "         must be a power of two, rang[2,1024], default is 1024.\n"
15748f512ceSopenharmony_ci        "   --app <package_name>\n"
15848f512ceSopenharmony_ci        "         Collect profile info for an OHOS app, the app must be debuggable.\n"
15948f512ceSopenharmony_ci        "         Record will exit if the process is not started within 10 seconds.\n"
16048f512ceSopenharmony_ci        "   --chkms <millisec>\n"
16148f512ceSopenharmony_ci        "         Set the interval of querying the <package_name>.\n"
16248f512ceSopenharmony_ci        "         <millisec> is in range [1-200], default is 10.\n"
16348f512ceSopenharmony_ci        "   --data-limit <SIZE[K|M|G]>\n"
16448f512ceSopenharmony_ci        "         Stop recording after SIZE bytes of records. Default is unlimited.\n"
16548f512ceSopenharmony_ci        "   -o <output_file_name>\n"
16648f512ceSopenharmony_ci        "         Set output file name, default is /data/local/tmp/perf.data.\n"
16748f512ceSopenharmony_ci        "   -z\n"
16848f512ceSopenharmony_ci        "         Compress record data.\n"
16948f512ceSopenharmony_ci        "   --restart\n"
17048f512ceSopenharmony_ci        "         Collect performance counter information of application startup.\n"
17148f512ceSopenharmony_ci        "         Record will exit if the process is not started within 30 seconds.\n"
17248f512ceSopenharmony_ci        "   --verbose\n"
17348f512ceSopenharmony_ci        "         Show more detailed reports.\n"
17448f512ceSopenharmony_ci        "   --control <command>\n"
17548f512ceSopenharmony_ci        "         Control sampling by <command>, the <command> can be:\n"
17648f512ceSopenharmony_ci        "           prepare: set arguments and prepare sampling\n"
17748f512ceSopenharmony_ci        "           start: start sampling\n"
17848f512ceSopenharmony_ci        "           pause: pause sampling\n"
17948f512ceSopenharmony_ci        "           resume: resume sampling\n"
18048f512ceSopenharmony_ci        "           stop: stop sampling\n"
18148f512ceSopenharmony_ci        "   --dedup_stack\n"
18248f512ceSopenharmony_ci        "         Remove duplicated stacks in perf record, conflicts with -a, only restrain using with -p\n"
18348f512ceSopenharmony_ci        "   --cmdline-size <size>\n"
18448f512ceSopenharmony_ci        "         set value to /sys/kernel/tracing/saved_cmdlines_size\n"
18548f512ceSopenharmony_ci        "         the value should be between 512 and 4096\n"
18648f512ceSopenharmony_ci        "   --report\n"
18748f512ceSopenharmony_ci        "         Report with callstack after record. Conflicts with the -a option.\n"
18848f512ceSopenharmony_ci        "   --dumpoptions\n"
18948f512ceSopenharmony_ci        "         Dump command options.\n"
19048f512ceSopenharmony_ci        )
19148f512ceSopenharmony_ci    // clang-format on
19248f512ceSopenharmony_ci    {
19348f512ceSopenharmony_ci    }
19448f512ceSopenharmony_ci
19548f512ceSopenharmony_ci    ~SubCommandRecord();
19648f512ceSopenharmony_ci    bool OnSubCommand(std::vector<std::string> &args) override;
19748f512ceSopenharmony_ci    bool ParseOption(std::vector<std::string> &args) override;
19848f512ceSopenharmony_ci    void DumpOptions(void) const override;
19948f512ceSopenharmony_ci
20048f512ceSopenharmony_ci    static bool RegisterSubCommandRecord(void);
20148f512ceSopenharmony_ci    std::map<const std::string, unsigned long long> speOptMap_ = {
20248f512ceSopenharmony_ci        {"branch_filter", 0},   {"load_filter", 0},
20348f512ceSopenharmony_ci        {"store_filter", 0},    {"ts_enable", 0},
20448f512ceSopenharmony_ci        {"pa_enable", 0},       {"jitter", 0},
20548f512ceSopenharmony_ci        {"min_latency", 0},      {"event_filter", 0},
20648f512ceSopenharmony_ci    };
20748f512ceSopenharmony_ci
20848f512ceSopenharmony_ciprivate:
20948f512ceSopenharmony_ci    PerfEvents perfEvents_;
21048f512ceSopenharmony_ci
21148f512ceSopenharmony_ci    bool targetSystemWide_ = false;
21248f512ceSopenharmony_ci    bool compressData_ = false;
21348f512ceSopenharmony_ci    bool noInherit_ = false;
21448f512ceSopenharmony_ci    bool excludeHiperf_ = false;
21548f512ceSopenharmony_ci    bool offCPU_ = false;
21648f512ceSopenharmony_ci    bool delayUnwind_ = false;
21748f512ceSopenharmony_ci    bool disableUnwind_ = false;
21848f512ceSopenharmony_ci    bool disableCallstackExpend_ = false;
21948f512ceSopenharmony_ci    bool enableDebugInfoSymbolic_ = false;
22048f512ceSopenharmony_ci    bool verboseReport_ = false;
22148f512ceSopenharmony_ci    bool kernelCallChain_ = true;
22248f512ceSopenharmony_ci    bool callChainUserOnly_ = false;
22348f512ceSopenharmony_ci    bool report_ = false;
22448f512ceSopenharmony_ci    float timeStopSec_ = PerfEvents::DEFAULT_TIMEOUT;
22548f512ceSopenharmony_ci    int frequency_ = 0;
22648f512ceSopenharmony_ci    int period_ = 0;
22748f512ceSopenharmony_ci    int cpuPercent_ = DEFAULT_CPU_PERCENT;
22848f512ceSopenharmony_ci    int mmapPages_ = MAX_PERF_MMAP_PAGE;
22948f512ceSopenharmony_ci    int cmdlinesSize_ = DEFAULT_SAVED_CMDLINES_SIZE;
23048f512ceSopenharmony_ci    int oldCmdlinesSize_ = 0;
23148f512ceSopenharmony_ci    std::vector<std::string> symbolDir_ = {};
23248f512ceSopenharmony_ci    std::string outputFilename_ = "/data/local/tmp/perf.data";
23348f512ceSopenharmony_ci    std::string appPackage_ = {};
23448f512ceSopenharmony_ci    int checkAppMs_ = DEFAULT_CHECK_APP_MS;
23548f512ceSopenharmony_ci    std::string clockId_ = {};
23648f512ceSopenharmony_ci    std::string strLimit_ = {};
23748f512ceSopenharmony_ci    std::vector<pid_t> selectCpus_ = {};
23848f512ceSopenharmony_ci    std::vector<pid_t> selectPids_ = {};
23948f512ceSopenharmony_ci    std::vector<pid_t> selectTids_ = {};
24048f512ceSopenharmony_ci    std::vector<pid_t> excludeTids_ = {};
24148f512ceSopenharmony_ci    bool restart_ = false;
24248f512ceSopenharmony_ci    std::vector<std::string> selectEvents_ = {};
24348f512ceSopenharmony_ci    std::vector<std::string> speOptions_ = {};
24448f512ceSopenharmony_ci    std::vector<std::vector<std::string>> selectGroups_ = {};
24548f512ceSopenharmony_ci    std::vector<std::string> callStackType_ = {};
24648f512ceSopenharmony_ci    std::vector<std::string> vecBranchFilters_ = {};
24748f512ceSopenharmony_ci    std::vector<std::string> trackedCommand_ = {};
24848f512ceSopenharmony_ci    std::vector<std::string> excludeThreadNames_ = {};
24948f512ceSopenharmony_ci
25048f512ceSopenharmony_ci    bool GetOptions(std::vector<std::string> &args);
25148f512ceSopenharmony_ci    bool CheckArgsRange();
25248f512ceSopenharmony_ci    bool CheckOptions();
25348f512ceSopenharmony_ci    bool GetSpeOptions();
25448f512ceSopenharmony_ci    bool CheckDataLimitOption();
25548f512ceSopenharmony_ci    bool CheckSelectCpuPidOption();
25648f512ceSopenharmony_ci    bool GetOptionFrequencyAndPeriod(std::vector<std::string> &args);
25748f512ceSopenharmony_ci
25848f512ceSopenharmony_ci    bool isCallStackDwarf_ = false;
25948f512ceSopenharmony_ci    bool isCallStackFp_ = false;
26048f512ceSopenharmony_ci    uint32_t callStackDwarfSize_ = MAX_SAMPLE_STACK_SIZE;
26148f512ceSopenharmony_ci    uint64_t branchSampleType_ = 0;
26248f512ceSopenharmony_ci    uint64_t dataSizeLimit_ = 0;
26348f512ceSopenharmony_ci    bool isDataSizeLimitStop_ = false;
26448f512ceSopenharmony_ci
26548f512ceSopenharmony_ci    std::unique_ptr<PerfFileWriter> fileWriter_ = nullptr;
26648f512ceSopenharmony_ci
26748f512ceSopenharmony_ci    // for client
26848f512ceSopenharmony_ci    int clientPipeInput_ = -1;
26948f512ceSopenharmony_ci    int clientPipeOutput_ = -1;
27048f512ceSopenharmony_ci    int nullFd_ = -1;
27148f512ceSopenharmony_ci    std::thread clientCommandHanle_;
27248f512ceSopenharmony_ci    bool clientExit_ = false;
27348f512ceSopenharmony_ci    void ClientCommandHandle();
27448f512ceSopenharmony_ci    bool ClientCommandResponse(bool OK);
27548f512ceSopenharmony_ci    bool IsSamplingRunning();
27648f512ceSopenharmony_ci    // for cmdline client
27748f512ceSopenharmony_ci    std::string controlCmd_ = {};
27848f512ceSopenharmony_ci    bool isFifoServer_ = false;
27948f512ceSopenharmony_ci    bool isFifoClient_ = false;
28048f512ceSopenharmony_ci    bool dedupStack_ = false;
28148f512ceSopenharmony_ci    std::map<pid_t, std::vector<pid_t>> mapPids_;
28248f512ceSopenharmony_ci    bool ProcessControl();
28348f512ceSopenharmony_ci    bool CreateFifoServer();
28448f512ceSopenharmony_ci    bool SendFifoAndWaitReply(const std::string &cmd, const std::chrono::milliseconds &timeOut);
28548f512ceSopenharmony_ci    bool WaitFifoReply(int fd, const std::chrono::milliseconds &timeOut);
28648f512ceSopenharmony_ci    void CloseClientThread();
28748f512ceSopenharmony_ci
28848f512ceSopenharmony_ci    bool PreparePerfEvent();
28948f512ceSopenharmony_ci    bool PrepareSysKernel();
29048f512ceSopenharmony_ci    bool PrepareVirtualRuntime();
29148f512ceSopenharmony_ci
29248f512ceSopenharmony_ci    size_t recordSamples_ = 0;
29348f512ceSopenharmony_ci    size_t recordNoSamples_ = 0;
29448f512ceSopenharmony_ci
29548f512ceSopenharmony_ci    bool isNeedSetPerfHarden_ = false;
29648f512ceSopenharmony_ci    bool isSpe_ = false;
29748f512ceSopenharmony_ci
29848f512ceSopenharmony_ci    // callback to process record
29948f512ceSopenharmony_ci    bool ProcessRecord(std::unique_ptr<PerfEventRecord>);
30048f512ceSopenharmony_ci    bool SaveRecord(std::unique_ptr<PerfEventRecord>, bool ptrReleaseFlag = false);
30148f512ceSopenharmony_ci
30248f512ceSopenharmony_ci    // file format like as 0,1-3,4-6,7,8
30348f512ceSopenharmony_ci    uint32_t GetCountFromFile(const std::string &fileName);
30448f512ceSopenharmony_ci    std::string GetCpuDescFromFile();
30548f512ceSopenharmony_ci    bool AddCpuFeature();
30648f512ceSopenharmony_ci    void AddMemTotalFeature();
30748f512ceSopenharmony_ci    void AddEventDescFeature();
30848f512ceSopenharmony_ci    void AddRecordTimeFeature();
30948f512ceSopenharmony_ci    void AddWorkloadCmdFeature();
31048f512ceSopenharmony_ci    void AddCommandLineFeature();
31148f512ceSopenharmony_ci    void AddCpuOffFeature();
31248f512ceSopenharmony_ci    void AddDevhostFeature();
31348f512ceSopenharmony_ci    bool AddFeatureRecordFile();
31448f512ceSopenharmony_ci
31548f512ceSopenharmony_ci    bool CreateInitRecordFile(bool compressData = false);
31648f512ceSopenharmony_ci    bool FinishWriteRecordFile();
31748f512ceSopenharmony_ci    bool PostProcessRecordFile();
31848f512ceSopenharmony_ci    bool RecordCompleted();
31948f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_TIME
32048f512ceSopenharmony_ci    void ReportTime();
32148f512ceSopenharmony_ci#endif
32248f512ceSopenharmony_ci
32348f512ceSopenharmony_ci    bool CollectionSymbol(std::unique_ptr<PerfEventRecord> record);
32448f512ceSopenharmony_ci    void CollectSymbol(PerfRecordSample *sample);
32548f512ceSopenharmony_ci    bool SetPerfLimit(const std::string& file, int value, std::function<bool (int, int)> const& cmd,
32648f512ceSopenharmony_ci        const std::string& param);
32748f512ceSopenharmony_ci    bool SetPerfCpuMaxPercent();
32848f512ceSopenharmony_ci    bool SetPerfMaxSampleRate();
32948f512ceSopenharmony_ci    bool SetPerfEventMlock();
33048f512ceSopenharmony_ci    bool SetPerfHarden();
33148f512ceSopenharmony_ci
33248f512ceSopenharmony_ci    bool TraceOffCpu();
33348f512ceSopenharmony_ci    bool ParseCallStackOption(const std::vector<std::string> &callStackType);
33448f512ceSopenharmony_ci    bool ParseDataLimitOption(const std::string &str);
33548f512ceSopenharmony_ci    bool ParseBranchSampleType(const std::vector<std::string> &vecBranchSampleTypes);
33648f512ceSopenharmony_ci    bool ParseControlCmd(const std::string cmd);
33748f512ceSopenharmony_ci    bool CheckTargetProcessOptions();
33848f512ceSopenharmony_ci    bool CheckTargetPids();
33948f512ceSopenharmony_ci    bool CheckReportOption();
34048f512ceSopenharmony_ci    void WriteCommEventBeforeSampling();
34148f512ceSopenharmony_ci    void RemoveVdsoTmpFile();
34248f512ceSopenharmony_ci
34348f512ceSopenharmony_ci    VirtualRuntime virtualRuntime_;
34448f512ceSopenharmony_ci#if USE_COLLECT_SYMBOLIC
34548f512ceSopenharmony_ci    std::unordered_map<pid_t, std::unordered_set<uint64_t>> kernelThreadSymbolsHits_;
34648f512ceSopenharmony_ci    kSymbolsHits kernelSymbolsHits_;
34748f512ceSopenharmony_ci    uSymbolsHits userSymbolsHits_;
34848f512ceSopenharmony_ci    void SymbolicHits();
34948f512ceSopenharmony_ci#endif
35048f512ceSopenharmony_ci
35148f512ceSopenharmony_ci#ifdef HIPERF_DEBUG_TIME
35248f512ceSopenharmony_ci    std::chrono::microseconds prcessRecordTimes_ = std::chrono::microseconds::zero();
35348f512ceSopenharmony_ci    std::chrono::microseconds saveRecordTimes_ = std::chrono::microseconds::zero();
35448f512ceSopenharmony_ci    std::chrono::microseconds saveFeatureTimes_ = std::chrono::microseconds::zero();
35548f512ceSopenharmony_ci#endif
35648f512ceSopenharmony_ci    std::chrono::time_point<std::chrono::steady_clock> startSaveFileTimes_;
35748f512ceSopenharmony_ci
35848f512ceSopenharmony_ci    void SetHM();
35948f512ceSopenharmony_ci    void SetSavedCmdlinesSize();
36048f512ceSopenharmony_ci    void RecoverSavedCmdlinesSize();
36148f512ceSopenharmony_ci    bool OnlineReportData();
36248f512ceSopenharmony_ci};
36348f512ceSopenharmony_ci} // namespace HiPerf
36448f512ceSopenharmony_ci} // namespace Developtools
36548f512ceSopenharmony_ci} // namespace OHOS
36648f512ceSopenharmony_ci#endif // SUBCOMMAND_RECORD_H
367