1 /* 2 * Copyright (c) 2021-2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef HIPERF_CLIENT_H_ 16 #define HIPERF_CLIENT_H_ 17 18 #include <chrono> 19 #include <string> 20 #include <vector> 21 22 namespace OHOS { 23 namespace Developtools { 24 namespace HiPerf { 25 namespace HiperfClient { 26 const std::string TempBinPath = "/data/local/tmp/"; 27 const std::string ReplyOK = "OK\n"; 28 const std::string ReplyFAIL = "FAIL\n"; 29 const std::string ReplyStart = "START\n"; 30 const std::string ReplyOutput = "OUTPUT\n"; 31 const std::string ReplyOutputCheck = "OUTPUT_CHECK\n"; 32 const std::string ReplyStop = "STOP\n"; 33 const std::string ReplyPause = "PAUSE\n"; 34 const std::string ReplyResume = "RESUME\n"; 35 const std::string ReplyCheck = "CHECK\n"; 36 #define HIPERF_EXIT_CODE 0 37 38 class RecordOption { 39 public: 40 /** 41 * Set output file name, default is perf.data 42 */ SetOutputFilename(const std::string & outputFilename)43 void SetOutputFilename(const std::string &outputFilename) 44 { 45 outputFileName_ = outputFilename; 46 } 47 /** 48 * Get output file name 49 */ GetOutputFileName()50 const std::string GetOutputFileName() const 51 { 52 return outputFileName_; 53 } 54 55 /** 56 * Get the default events for select. 57 */ GetSelectEvents()58 const std::vector<std::string> &GetSelectEvents() const 59 { 60 return selectEvents_; 61 } 62 63 /** 64 * Collect system-wide information for measures all processes/threads 65 * default is disable. 66 */ 67 void SetTargetSystemWide(bool enable); 68 /** 69 * Compress record data. default is disable. 70 */ 71 void SetCompressData(bool enable); 72 /** 73 * Specify cpu ID, cpu ID shoule be 0,1,2... 74 */ 75 void SetSelectCpus(const std::vector<int> &cpus); 76 /** 77 * Stop in <timeStopSec> seconds. default is 10000 seconds 78 */ 79 void SetTimeStopSec(int timeStopSec); 80 /** 81 * Set event sampling frequency. default is 4000 samples every second. 82 */ 83 void SetFrequency(int frequency); 84 /** 85 * Set event sampling period for tracepoint events. 86 * recording one sample when <period> events happen. 87 * default is 1 88 */ 89 void SetPeriod(int period); 90 /** 91 * Customize the name of the event that needs to be sampled. 92 */ 93 void SetSelectEvents(const std::vector<std::string> &selectEvents); 94 /** 95 * Customize the name of the event that needs to be grouped. 96 * the function is added on the basis of the function of the SetSelectEvents(). 97 */ 98 void SetSelectGroups(const std::vector<std::string> &selectGroups); 99 /** 100 * Set to don't tracing child processes. default is disable 101 */ 102 void SetNoInherit(bool enable); 103 /** 104 * Set the limit process id of the collection target. 105 * Conflicts with the SetTargetSystemWide(true). 106 */ 107 void SetSelectPids(const std::vector<pid_t> &selectPids); 108 /** 109 * Set default sampling parameters with specifying the select duration. 110 * default is 10 seconds. 111 */ 112 void SetCallStackSamplingConfigs(int duration); 113 /** 114 * Set the limit thread id of the collection target. 115 * Conflicts with the SetTargetSystemWide(true). 116 */ 117 void SetSelectTids(const std::vector<pid_t> &selectTids); 118 /** 119 * Set don’t record events issued by hiperf itself. 120 */ 121 void SetExcludePerf(bool excludePerf); 122 /** 123 * Set the max percent of cpu time used for recording. 124 * percent is in range [1-100], default is 25 125 */ 126 void SetCpuPercent(int cpuPercent); 127 /** 128 * Set tracing when threads are scheduled off cpu, default is disable 129 */ 130 void SetOffCPU(bool offCPU); 131 /** 132 * Set call-graph (stack chain/backtrace) recording, Default is 'fp'. 133 * as the method to collect the information used to show the call graphs. 134 * the value can be: 135 * fp: frame pointer 136 * dwarf: DWARF's CFI - Call Frame Information 137 * 'dwarf,###' set sample stack size, size should be in 8~65528 and 8 byte aligned. 138 */ 139 void SetCallGraph(const std::string &sampleTypes); 140 /** 141 * Set to unwind after recording. 142 * If '-g dwarf' used, stack will be unwind while recording by default 143 */ 144 void SetDelayUnwind(bool delayUnwind); 145 /** 146 * Set to disable unwinding. 147 * If '-g dwarf' used, stack will be unwind while recording by default 148 */ 149 void SetDisableUnwind(bool disableUnwind); 150 /** 151 * Set callstack don't merged. 152 * If '-g dwarf' is used, to break the 64k stack limit, callstack is merged by default 153 */ 154 void SetDisableCallstackMerge(bool disableCallstackMerge); 155 /** 156 * Set directory to look for symbol files, used for unwinding. 157 */ 158 void SetSymbolDir(const std::string &symbolDir_); 159 /** 160 * Set to stop recording after <SIZE> bytes of records. Default is unlimited 161 * format like: SIZE[K|M|G] 162 */ 163 void SetDataLimit(const std::string &limit); 164 /** 165 * Set a OHOS app name, collect profile info for this app, the app must be debuggable. 166 */ 167 void SetAppPackage(const std::string &appPackage); 168 /** 169 * Set the clock id to use for the various time fields in the perf_event_type records. 170 */ 171 void SetClockId(const std::string &clockId); 172 /** 173 * Set to take branch stack sampling, filter can be 174 * any: any type of branch 175 * any_call: any function call or system call 176 * any_ret: any function return or system call return 177 * ind_call: any indirect branch 178 * call: direct calls, including far (to/from kernel) calls 179 * u: only when the branch target is at the user level 180 * k: only when the branch target is in the kernel\n" 181 */ 182 void SetVecBranchSampleTypes(const std::vector<std::string> &vecBranchSampleTypes); 183 /** 184 * Set the size of the buffer used to receiving sample data from kernel, 185 * must be a power of two. If not set, a value <=1024 will be used. 186 */ 187 void SetMmapPages(int mmapPages); 188 /** 189 * Set to report with callstack after recording, default is disable 190 */ 191 void SetReport(bool report); 192 /** 193 * Set the limit processes that do not need to be recorded, 194 * must be used with the SetTargetSystemWide(true). 195 */ 196 void SetExcludeProcess(const std::vector<std::string>& excludeProcess); 197 /** 198 * Set record mode of collect data of the previous period, default is disable 199 */ 200 void SetBackTrack(bool backtrack); 201 /** 202 * Set the time of collect data of the previous period, default is 10 seconds. 203 * Must be used with the SetBackTrack(true). 204 */ 205 void SetBackTrackSec(int backTracesec); 206 207 /** 208 * Get the string vector of all options. 209 */ GetOptionVecString()210 const std::vector<std::string> &GetOptionVecString() const 211 { 212 return args_; 213 } 214 215 /** 216 * Get TimeSpec attribute 217 */ IsTimeSpecified()218 bool IsTimeSpecified() const 219 { 220 return timeSpec_; 221 } 222 private: 223 bool timeSpec_ = false; 224 std::vector<std::string> args_ = {}; 225 std::vector<std::string> selectEvents_ = {"hw-cpu-cycles:u"}; 226 std::string outputFileName_ = ""; 227 228 void SetOption(const std::string &name, bool enable); 229 void SetOption(const std::string &name, int value); 230 void SetOption(const std::string &name, const std::vector<int> &vInt); 231 void SetOption(const std::string &name, const std::string &str); 232 void SetOption(const std::string &name, const std::vector<std::string> &vStr); 233 }; 234 235 class Client { 236 public: 237 /** 238 * Set output dir and constuct 239 */ 240 explicit Client(const std::string &outputDir = TempBinPath); 241 ~Client(); 242 /** 243 * Start record with default options 244 */ 245 bool Start(); 246 /** 247 * Start record with options of string vector 248 */ 249 bool Start(const std::vector<std::string> &args, bool immediately = true); 250 /** 251 * Start record with options of RecordOption 252 */ 253 bool Start(const RecordOption &option); 254 /** 255 * Start record synchronizely with specified time 256 */ 257 bool RunHiperfCmdSync(const RecordOption &option); 258 /** 259 * prepare record with options of RecordOption 260 */ 261 bool PrePare(const RecordOption &option); 262 /** 263 * Start recording after prepare 264 */ 265 bool StartRun(); 266 /** 267 * Pause recording 268 */ 269 bool Pause(); 270 /** 271 * Resume recording 272 */ 273 bool Resume(); 274 /** 275 * Output recording 276 */ 277 bool Output(); 278 /** 279 * Stop recording 280 */ 281 bool Stop(); 282 /** 283 * Check the client is ready 284 */ 285 bool IsReady(); 286 /** 287 * Set the output dir 288 */ 289 bool Setup(std::string outputDir); 290 291 /** 292 * Get the output dir 293 */ GetOutputDir()294 const std::string &GetOutputDir() const 295 { 296 return outputDir_; 297 } 298 /** 299 * Get the command path 300 */ GetCommandPath()301 const std::string &GetCommandPath() const 302 { 303 return executeCommandPath_; 304 } 305 /** 306 * Get the the fullpath of output file 307 */ GetOutputPerfDataPath()308 const std::string GetOutputPerfDataPath() const 309 { 310 return outputDir_ + outputFileName_; 311 } 312 313 /** 314 * Child run execv cmd 315 */ 316 void ChildRunExecv(std::vector<std::string> &cmd); 317 /** 318 * Prepare execv cmd 319 */ 320 void PrepareExecCmd(std::vector<std::string> &cmd); 321 /** 322 * Parent wait for child exit 323 */ 324 bool ParentWait(pid_t &wpid, pid_t pid, int &childStatus); 325 void SetDebugMode(); 326 void SetDebugMuchMode(); 327 void EnableHilog(); 328 void KillChild(); 329 private: 330 static constexpr int64_t HIPERF_TIMEOUT_MILLISECOND = 4000; 331 332 bool WaitCommandReply(std::chrono::milliseconds = std::chrono::milliseconds(HIPERF_TIMEOUT_MILLISECOND)); 333 bool SendCommandAndWait(const std::string &cmd); 334 void GetExecCmd(std::vector<std::string> &cmd, int pipeIn, int pipeOut, 335 const std::vector<std::string> &args); 336 337 void GetExecCmd(std::vector<std::string> &cmd, 338 const std::vector<std::string> &args); 339 std::string outputDir_ = ""; 340 std::string outputFileName_ = ""; 341 std::string executeCommandPath_ = ""; 342 bool ready_ = false; 343 pid_t myPid_ = -1; 344 bool debug_ = false; 345 bool debugMuch_ = false; 346 bool hilog_ = false; 347 348 int clientToServerFd_ = -1; 349 int serverToClientFd_ = -1; 350 pid_t hperfPid_ = -1; 351 pid_t hperfPrePid_ = -1; // hiperf pid for prepare mode 352 }; 353 } // namespace HiperfClient 354 } // namespace HiPerf 355 } // namespace Developtools 356 } // namespace OHOS 357 #endif // HIPERF_CLIENT_H_ 358