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