1b0e7dd80Sopenharmony_ci/* 2b0e7dd80Sopenharmony_ci * Copyright (C) 2022-2024 Huawei Device Co., Ltd. 3b0e7dd80Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b0e7dd80Sopenharmony_ci * you may not use this file except in compliance with the License. 5b0e7dd80Sopenharmony_ci * You may obtain a copy of the License at 6b0e7dd80Sopenharmony_ci * 7b0e7dd80Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b0e7dd80Sopenharmony_ci * 9b0e7dd80Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b0e7dd80Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b0e7dd80Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b0e7dd80Sopenharmony_ci * See the License for the specific language governing permissions and 13b0e7dd80Sopenharmony_ci * limitations under the License. 14b0e7dd80Sopenharmony_ci */ 15b0e7dd80Sopenharmony_ci 16b0e7dd80Sopenharmony_ci#include <cinttypes> 17b0e7dd80Sopenharmony_ci#include <csignal> 18b0e7dd80Sopenharmony_ci#include <cstdio> 19b0e7dd80Sopenharmony_ci#include <cstdlib> 20b0e7dd80Sopenharmony_ci#include <cstring> 21b0e7dd80Sopenharmony_ci#include <ctime> 22b0e7dd80Sopenharmony_ci#include <fcntl.h> 23b0e7dd80Sopenharmony_ci#include <fstream> 24b0e7dd80Sopenharmony_ci#include <getopt.h> 25b0e7dd80Sopenharmony_ci#include <map> 26b0e7dd80Sopenharmony_ci#include <regex> 27b0e7dd80Sopenharmony_ci#include <sstream> 28b0e7dd80Sopenharmony_ci#include <string> 29b0e7dd80Sopenharmony_ci#include <sys/stat.h> 30b0e7dd80Sopenharmony_ci#include <sys/types.h> 31b0e7dd80Sopenharmony_ci#include <thread> 32b0e7dd80Sopenharmony_ci#include <unistd.h> 33b0e7dd80Sopenharmony_ci#include <vector> 34b0e7dd80Sopenharmony_ci#include <memory> 35b0e7dd80Sopenharmony_ci#include <iostream> 36b0e7dd80Sopenharmony_ci#include <zlib.h> 37b0e7dd80Sopenharmony_ci 38b0e7dd80Sopenharmony_ci#include "hitrace_meter.h" 39b0e7dd80Sopenharmony_ci#include "common_utils.h" 40b0e7dd80Sopenharmony_ci#include "trace_collector_client.h" 41b0e7dd80Sopenharmony_ci#include "hitrace_osal.h" 42b0e7dd80Sopenharmony_ci#include "securec.h" 43b0e7dd80Sopenharmony_ci 44b0e7dd80Sopenharmony_ciusing namespace std; 45b0e7dd80Sopenharmony_ciusing namespace OHOS::HiviewDFX::HitraceOsal; 46b0e7dd80Sopenharmony_ci 47b0e7dd80Sopenharmony_cinamespace { 48b0e7dd80Sopenharmony_ci 49b0e7dd80Sopenharmony_cistruct TraceArgs { 50b0e7dd80Sopenharmony_ci std::string tags; 51b0e7dd80Sopenharmony_ci std::string tagGroups; 52b0e7dd80Sopenharmony_ci std::string clockType; 53b0e7dd80Sopenharmony_ci int bufferSize = 0; 54b0e7dd80Sopenharmony_ci int fileSize = 0; 55b0e7dd80Sopenharmony_ci bool overwrite = true; 56b0e7dd80Sopenharmony_ci std::string output; 57b0e7dd80Sopenharmony_ci 58b0e7dd80Sopenharmony_ci int duration = 0; 59b0e7dd80Sopenharmony_ci bool isCompress = false; 60b0e7dd80Sopenharmony_ci}; 61b0e7dd80Sopenharmony_ci 62b0e7dd80Sopenharmony_cienum RunningState { 63b0e7dd80Sopenharmony_ci /* Initial value */ 64b0e7dd80Sopenharmony_ci STATE_NULL = 0, 65b0e7dd80Sopenharmony_ci 66b0e7dd80Sopenharmony_ci /* Record a short trace */ 67b0e7dd80Sopenharmony_ci RECORDING_SHORT_TEXT = 1, // --text 68b0e7dd80Sopenharmony_ci RECORDING_SHORT_RAW = 2, // --raw 69b0e7dd80Sopenharmony_ci 70b0e7dd80Sopenharmony_ci /* Record a long trace */ 71b0e7dd80Sopenharmony_ci RECORDING_LONG_BEGIN = 10, // --trace_begin 72b0e7dd80Sopenharmony_ci RECORDING_LONG_DUMP = 11, // --trace_dump 73b0e7dd80Sopenharmony_ci RECORDING_LONG_FINISH = 12, // --trace_finish 74b0e7dd80Sopenharmony_ci RECORDING_LONG_FINISH_NODUMP = 13, // --trace_finish_nodump 75b0e7dd80Sopenharmony_ci RECORDING_LONG_BEGIN_RECORD = 14, // --trace_begin --record 76b0e7dd80Sopenharmony_ci RECORDING_LONG_FINISH_RECORD = 15, // --trace_finish --record 77b0e7dd80Sopenharmony_ci 78b0e7dd80Sopenharmony_ci /* Manipulating trace services in snapshot mode */ 79b0e7dd80Sopenharmony_ci SNAPSHOT_START = 20, // --start_bgsrv 80b0e7dd80Sopenharmony_ci SNAPSHOT_DUMP = 21, // --dump_bgsrv 81b0e7dd80Sopenharmony_ci SNAPSHOT_STOP = 22, // --stop_bgsrv 82b0e7dd80Sopenharmony_ci 83b0e7dd80Sopenharmony_ci /* Help Info */ 84b0e7dd80Sopenharmony_ci SHOW_HELP = 31, // -h, --help 85b0e7dd80Sopenharmony_ci SHOW_LIST_CATEGORY = 32, // -l, --list_categories 86b0e7dd80Sopenharmony_ci}; 87b0e7dd80Sopenharmony_ci 88b0e7dd80Sopenharmony_ciconst std::map<RunningState, std::string> STATE_INFO = { 89b0e7dd80Sopenharmony_ci { STATE_NULL, "STATE_NULL" }, 90b0e7dd80Sopenharmony_ci { RECORDING_SHORT_TEXT, "RECORDING_SHORT_TEXT" }, 91b0e7dd80Sopenharmony_ci { RECORDING_SHORT_RAW, "RECORDING_SHORT_RAW" }, 92b0e7dd80Sopenharmony_ci { RECORDING_LONG_BEGIN, "RECORDING_LONG_BEGIN" }, 93b0e7dd80Sopenharmony_ci { RECORDING_LONG_DUMP, "RECORDING_LONG_DUMP" }, 94b0e7dd80Sopenharmony_ci { RECORDING_LONG_FINISH_NODUMP, "RECORDING_LONG_FINISH_NODUMP" }, 95b0e7dd80Sopenharmony_ci { RECORDING_LONG_BEGIN_RECORD, "RECORDING_LONG_BEGIN_RECORD" }, 96b0e7dd80Sopenharmony_ci { RECORDING_LONG_FINISH_RECORD, "RECORDING_LONG_FINISH_RECORD" }, 97b0e7dd80Sopenharmony_ci { SNAPSHOT_START, "SNAPSHOT_START" }, 98b0e7dd80Sopenharmony_ci { SNAPSHOT_DUMP, "SNAPSHOT_DUMP" }, 99b0e7dd80Sopenharmony_ci { SNAPSHOT_STOP, "SNAPSHOT_STOP" }, 100b0e7dd80Sopenharmony_ci { SHOW_HELP, "SHOW_HELP" }, 101b0e7dd80Sopenharmony_ci { SHOW_LIST_CATEGORY, "SHOW_LIST_CATEGORY" }, 102b0e7dd80Sopenharmony_ci}; 103b0e7dd80Sopenharmony_ci 104b0e7dd80Sopenharmony_ciconstexpr struct option LONG_OPTIONS[] = { 105b0e7dd80Sopenharmony_ci { "buffer_size", required_argument, nullptr, 0 }, 106b0e7dd80Sopenharmony_ci { "trace_clock", required_argument, nullptr, 0 }, 107b0e7dd80Sopenharmony_ci { "help", no_argument, nullptr, 0 }, 108b0e7dd80Sopenharmony_ci { "output", required_argument, nullptr, 0 }, 109b0e7dd80Sopenharmony_ci { "time", required_argument, nullptr, 0 }, 110b0e7dd80Sopenharmony_ci { "text", no_argument, nullptr, 0 }, 111b0e7dd80Sopenharmony_ci { "raw", no_argument, nullptr, 0 }, 112b0e7dd80Sopenharmony_ci { "trace_begin", no_argument, nullptr, 0 }, 113b0e7dd80Sopenharmony_ci { "trace_finish", no_argument, nullptr, 0 }, 114b0e7dd80Sopenharmony_ci { "trace_finish_nodump", no_argument, nullptr, 0 }, 115b0e7dd80Sopenharmony_ci { "record", no_argument, nullptr, 0 }, 116b0e7dd80Sopenharmony_ci { "trace_dump", no_argument, nullptr, 0 }, 117b0e7dd80Sopenharmony_ci { "list_categories", no_argument, nullptr, 0 }, 118b0e7dd80Sopenharmony_ci { "overwrite", no_argument, nullptr, 0 }, 119b0e7dd80Sopenharmony_ci { "start_bgsrv", no_argument, nullptr, 0 }, 120b0e7dd80Sopenharmony_ci { "dump_bgsrv", no_argument, nullptr, 0 }, 121b0e7dd80Sopenharmony_ci { "stop_bgsrv", no_argument, nullptr, 0 }, 122b0e7dd80Sopenharmony_ci { "file_size", required_argument, nullptr, 0 }, 123b0e7dd80Sopenharmony_ci { nullptr, 0, nullptr, 0 }, 124b0e7dd80Sopenharmony_ci}; 125b0e7dd80Sopenharmony_ciconst unsigned int CHUNK_SIZE = 65536; 126b0e7dd80Sopenharmony_ci 127b0e7dd80Sopenharmony_ciconstexpr const char *TRACE_TAG_PROPERTY = "debug.hitrace.tags.enableflags"; 128b0e7dd80Sopenharmony_ci 129b0e7dd80Sopenharmony_ci// various operating paths of ftrace 130b0e7dd80Sopenharmony_ciconstexpr const char *TRACING_ON_PATH = "tracing_on"; 131b0e7dd80Sopenharmony_ciconstexpr const char *TRACE_PATH = "trace"; 132b0e7dd80Sopenharmony_ciconstexpr const char *TRACE_MARKER_PATH = "trace_marker"; 133b0e7dd80Sopenharmony_ci 134b0e7dd80Sopenharmony_ci// support customization of some parameters 135b0e7dd80Sopenharmony_ciconst int KB_PER_MB = 1024; 136b0e7dd80Sopenharmony_ciconst int MIN_BUFFER_SIZE = 256; 137b0e7dd80Sopenharmony_ciconst int MAX_BUFFER_SIZE = 307200; // 300 MB 138b0e7dd80Sopenharmony_ciconst int HM_MAX_BUFFER_SIZE = 1024 * KB_PER_MB; // 1024 MB 139b0e7dd80Sopenharmony_ciconst int DEFAULT_BUFFER_SIZE = 18432; // 18 MB 140b0e7dd80Sopenharmony_ciconstexpr unsigned int MAX_OUTPUT_LEN = 255; 141b0e7dd80Sopenharmony_ciconst int PAGE_SIZE_KB = 4; // 4 KB 142b0e7dd80Sopenharmony_ciconst int MIN_FILE_SIZE = 51200; // 50 MB 143b0e7dd80Sopenharmony_ciconst int MAX_FILE_SIZE = 512000; // 500 MB 144b0e7dd80Sopenharmony_ci 145b0e7dd80Sopenharmony_cistring g_traceRootPath; 146b0e7dd80Sopenharmony_ci 147b0e7dd80Sopenharmony_cistd::shared_ptr<OHOS::HiviewDFX::UCollectClient::TraceCollector> g_traceCollector; 148b0e7dd80Sopenharmony_ci 149b0e7dd80Sopenharmony_ciTraceArgs g_traceArgs; 150b0e7dd80Sopenharmony_cistd::map<std::string, OHOS::HiviewDFX::Hitrace::TagCategory> g_allTags; 151b0e7dd80Sopenharmony_cistd::map<std::string, std::vector<std::string>> g_allTagGroups; 152b0e7dd80Sopenharmony_ciRunningState g_runningState = STATE_NULL; 153b0e7dd80Sopenharmony_ci} 154b0e7dd80Sopenharmony_ci 155b0e7dd80Sopenharmony_cistatic void ConsoleLog(const std::string& logInfo) 156b0e7dd80Sopenharmony_ci{ 157b0e7dd80Sopenharmony_ci // get localtime 158b0e7dd80Sopenharmony_ci time_t currentTime; 159b0e7dd80Sopenharmony_ci time(¤tTime); 160b0e7dd80Sopenharmony_ci struct tm timeInfo = {}; 161b0e7dd80Sopenharmony_ci const int bufferSize = 20; 162b0e7dd80Sopenharmony_ci char timeStr[bufferSize] = {0}; 163b0e7dd80Sopenharmony_ci localtime_r(¤tTime, &timeInfo); 164b0e7dd80Sopenharmony_ci strftime(timeStr, bufferSize, "%Y/%m/%d %H:%M:%S", &timeInfo); 165b0e7dd80Sopenharmony_ci std::cout << timeStr << " " << logInfo << std::endl; 166b0e7dd80Sopenharmony_ci} 167b0e7dd80Sopenharmony_ci 168b0e7dd80Sopenharmony_cistatic std::string GetStateInfo(const RunningState state) 169b0e7dd80Sopenharmony_ci{ 170b0e7dd80Sopenharmony_ci if (STATE_INFO.find(state) == STATE_INFO.end()) { 171b0e7dd80Sopenharmony_ci ConsoleLog("error: running_state is invalid."); 172b0e7dd80Sopenharmony_ci return ""; 173b0e7dd80Sopenharmony_ci } 174b0e7dd80Sopenharmony_ci return STATE_INFO.at(state); 175b0e7dd80Sopenharmony_ci} 176b0e7dd80Sopenharmony_ci 177b0e7dd80Sopenharmony_cistatic bool IsTraceMounted() 178b0e7dd80Sopenharmony_ci{ 179b0e7dd80Sopenharmony_ci const string debugfsPath = "/sys/kernel/debug/tracing/"; 180b0e7dd80Sopenharmony_ci const string tracefsPath = "/sys/kernel/tracing/"; 181b0e7dd80Sopenharmony_ci 182b0e7dd80Sopenharmony_ci if (access((debugfsPath + TRACE_MARKER_PATH).c_str(), F_OK) != -1) { 183b0e7dd80Sopenharmony_ci g_traceRootPath = debugfsPath; 184b0e7dd80Sopenharmony_ci return true; 185b0e7dd80Sopenharmony_ci } 186b0e7dd80Sopenharmony_ci if (access((tracefsPath + TRACE_MARKER_PATH).c_str(), F_OK) != -1) { 187b0e7dd80Sopenharmony_ci g_traceRootPath = tracefsPath; 188b0e7dd80Sopenharmony_ci return true; 189b0e7dd80Sopenharmony_ci } 190b0e7dd80Sopenharmony_ci return false; 191b0e7dd80Sopenharmony_ci} 192b0e7dd80Sopenharmony_ci 193b0e7dd80Sopenharmony_cistatic bool WriteStrToFile(const string& filename, const std::string& str) 194b0e7dd80Sopenharmony_ci{ 195b0e7dd80Sopenharmony_ci ofstream out; 196b0e7dd80Sopenharmony_ci std::string inSpecPath = 197b0e7dd80Sopenharmony_ci OHOS::HiviewDFX::Hitrace::CanonicalizeSpecPath((g_traceRootPath + filename).c_str()); 198b0e7dd80Sopenharmony_ci out.open(inSpecPath, ios::out); 199b0e7dd80Sopenharmony_ci if (out.fail()) { 200b0e7dd80Sopenharmony_ci ConsoleLog("error: open " + inSpecPath + " failed."); 201b0e7dd80Sopenharmony_ci return false; 202b0e7dd80Sopenharmony_ci } 203b0e7dd80Sopenharmony_ci out << str; 204b0e7dd80Sopenharmony_ci if (out.bad()) { 205b0e7dd80Sopenharmony_ci ConsoleLog("error: can not write " + inSpecPath); 206b0e7dd80Sopenharmony_ci out.close(); 207b0e7dd80Sopenharmony_ci return false; 208b0e7dd80Sopenharmony_ci } 209b0e7dd80Sopenharmony_ci out.flush(); 210b0e7dd80Sopenharmony_ci out.close(); 211b0e7dd80Sopenharmony_ci return true; 212b0e7dd80Sopenharmony_ci} 213b0e7dd80Sopenharmony_ci 214b0e7dd80Sopenharmony_cistatic bool SetFtraceEnabled(const string& path, bool enabled) 215b0e7dd80Sopenharmony_ci{ 216b0e7dd80Sopenharmony_ci return WriteStrToFile(path, enabled ? "1" : "0"); 217b0e7dd80Sopenharmony_ci} 218b0e7dd80Sopenharmony_ci 219b0e7dd80Sopenharmony_cistatic bool SetProperty(const string& property, const string& value) 220b0e7dd80Sopenharmony_ci{ 221b0e7dd80Sopenharmony_ci return SetPropertyInner(property, value); 222b0e7dd80Sopenharmony_ci} 223b0e7dd80Sopenharmony_ci 224b0e7dd80Sopenharmony_cistatic bool SetTraceTagsEnabled(uint64_t tags) 225b0e7dd80Sopenharmony_ci{ 226b0e7dd80Sopenharmony_ci string value = std::to_string(tags); 227b0e7dd80Sopenharmony_ci return SetProperty(TRACE_TAG_PROPERTY, value); 228b0e7dd80Sopenharmony_ci} 229b0e7dd80Sopenharmony_ci 230b0e7dd80Sopenharmony_cistatic void ShowListCategory() 231b0e7dd80Sopenharmony_ci{ 232b0e7dd80Sopenharmony_ci printf(" %18s description:\n", "tagName:"); 233b0e7dd80Sopenharmony_ci for (auto it = g_allTags.begin(); it != g_allTags.end(); ++it) { 234b0e7dd80Sopenharmony_ci printf(" %18s - %s\n", it->first.c_str(), it->second.description.c_str()); 235b0e7dd80Sopenharmony_ci } 236b0e7dd80Sopenharmony_ci} 237b0e7dd80Sopenharmony_ci 238b0e7dd80Sopenharmony_cistatic void ShowHelp(const string& cmd) 239b0e7dd80Sopenharmony_ci{ 240b0e7dd80Sopenharmony_ci printf("usage: %s [options] [categories...]\n", cmd.c_str()); 241b0e7dd80Sopenharmony_ci printf("options include:\n" 242b0e7dd80Sopenharmony_ci " -b N Sets the size of the buffer (KB) for storing and reading traces. The default \n" 243b0e7dd80Sopenharmony_ci " buffer size is 18432 KB.\n" 244b0e7dd80Sopenharmony_ci " --buffer_size N Like \"-b N\".\n" 245b0e7dd80Sopenharmony_ci " -l Lists available hitrace categories.\n" 246b0e7dd80Sopenharmony_ci " --list_categories Like \"-l\".\n" 247b0e7dd80Sopenharmony_ci " -t N Sets the hitrace running duration in seconds (5s by default), which depends on \n" 248b0e7dd80Sopenharmony_ci " the time required for analysis.\n" 249b0e7dd80Sopenharmony_ci " --time N Like \"-t N\".\n" 250b0e7dd80Sopenharmony_ci " --trace_clock clock\n" 251b0e7dd80Sopenharmony_ci " Sets the type of the clock for adding a timestamp to a trace, which can be\n" 252b0e7dd80Sopenharmony_ci " boot (default), global, mono, uptime, or perf.\n" 253b0e7dd80Sopenharmony_ci " --trace_begin Starts capturing traces.\n" 254b0e7dd80Sopenharmony_ci " --trace_dump Dumps traces to a specified path (stdout by default).\n" 255b0e7dd80Sopenharmony_ci " --trace_finish Stops capturing traces and dumps traces to a specified path (stdout by default).\n" 256b0e7dd80Sopenharmony_ci " --trace_finish_nodump\n" 257b0e7dd80Sopenharmony_ci " Stops capturing traces and not dumps traces.\n" 258b0e7dd80Sopenharmony_ci " --record Enable or disable long-term trace collection tasks in conjunction with\n" 259b0e7dd80Sopenharmony_ci " \"--trace_begin\" and \"--trace_finish\".\n" 260b0e7dd80Sopenharmony_ci " --overwrite Sets the action to take when the buffer is full. If this option is used,\n" 261b0e7dd80Sopenharmony_ci " the latest traces are discarded; if this option is not used (default setting),\n" 262b0e7dd80Sopenharmony_ci " the earliest traces are discarded.\n" 263b0e7dd80Sopenharmony_ci " -o filename Specifies the name of the target file (stdout by default).\n" 264b0e7dd80Sopenharmony_ci " --output filename\n" 265b0e7dd80Sopenharmony_ci " Like \"-o filename\".\n" 266b0e7dd80Sopenharmony_ci " -z Compresses a captured trace.\n" 267b0e7dd80Sopenharmony_ci " --text Specify the output format of trace as text.\n" 268b0e7dd80Sopenharmony_ci " --raw Specify the output format of trace as raw trace, the default format is text.\n" 269b0e7dd80Sopenharmony_ci " --start_bgsrv Enable trace_service in snapshot mode.\n" 270b0e7dd80Sopenharmony_ci " --dump_bgsrv Trigger the dump trace task of the trace_service.\n" 271b0e7dd80Sopenharmony_ci " --stop_bgsrv Disable trace_service in snapshot mode.\n" 272b0e7dd80Sopenharmony_ci " --file_size Sets the size of the raw trace (KB). The default file size is 102400 KB.\n" 273b0e7dd80Sopenharmony_ci " Only effective in raw trace mode\n" 274b0e7dd80Sopenharmony_ci ); 275b0e7dd80Sopenharmony_ci} 276b0e7dd80Sopenharmony_ci 277b0e7dd80Sopenharmony_citemplate <typename T> 278b0e7dd80Sopenharmony_ciinline bool StrToNum(const std::string& sString, T &tX) 279b0e7dd80Sopenharmony_ci{ 280b0e7dd80Sopenharmony_ci std::istringstream iStream(sString); 281b0e7dd80Sopenharmony_ci return (iStream >> tX) ? true : false; 282b0e7dd80Sopenharmony_ci} 283b0e7dd80Sopenharmony_ci 284b0e7dd80Sopenharmony_cistatic bool SetRunningState(const RunningState& setValue) 285b0e7dd80Sopenharmony_ci{ 286b0e7dd80Sopenharmony_ci if (g_runningState != STATE_NULL) { 287b0e7dd80Sopenharmony_ci ConsoleLog("error: the parameter is set incorrectly, " + GetStateInfo(g_runningState) + 288b0e7dd80Sopenharmony_ci " and " + GetStateInfo(setValue) + " cannot coexist."); 289b0e7dd80Sopenharmony_ci return false; 290b0e7dd80Sopenharmony_ci } 291b0e7dd80Sopenharmony_ci g_runningState = setValue; 292b0e7dd80Sopenharmony_ci return true; 293b0e7dd80Sopenharmony_ci} 294b0e7dd80Sopenharmony_ci 295b0e7dd80Sopenharmony_cistatic bool CheckOutputFile(const char* path) 296b0e7dd80Sopenharmony_ci{ 297b0e7dd80Sopenharmony_ci struct stat buf; 298b0e7dd80Sopenharmony_ci size_t len = strnlen(path, MAX_OUTPUT_LEN); 299b0e7dd80Sopenharmony_ci if (len == MAX_OUTPUT_LEN || len < 1 || (stat(path, &buf) == 0 && (buf.st_mode & S_IFDIR))) { 300b0e7dd80Sopenharmony_ci ConsoleLog("error: output file is illegal"); 301b0e7dd80Sopenharmony_ci return false; 302b0e7dd80Sopenharmony_ci } 303b0e7dd80Sopenharmony_ci g_traceArgs.output = path; 304b0e7dd80Sopenharmony_ci return true; 305b0e7dd80Sopenharmony_ci} 306b0e7dd80Sopenharmony_ci 307b0e7dd80Sopenharmony_cistatic bool ParseLongOpt(const string& cmd, int optionIndex) 308b0e7dd80Sopenharmony_ci{ 309b0e7dd80Sopenharmony_ci bool isTrue = true; 310b0e7dd80Sopenharmony_ci if (!strcmp(LONG_OPTIONS[optionIndex].name, "buffer_size")) { 311b0e7dd80Sopenharmony_ci int bufferSizeKB = 0; 312b0e7dd80Sopenharmony_ci int maxBufferSizeKB = MAX_BUFFER_SIZE; 313b0e7dd80Sopenharmony_ci if (IsHmKernel()) { 314b0e7dd80Sopenharmony_ci maxBufferSizeKB = HM_MAX_BUFFER_SIZE; 315b0e7dd80Sopenharmony_ci } 316b0e7dd80Sopenharmony_ci if (!StrToNum(optarg, bufferSizeKB)) { 317b0e7dd80Sopenharmony_ci ConsoleLog("error: buffer size is illegal input. eg: \"--buffer_size 18432\"."); 318b0e7dd80Sopenharmony_ci isTrue = false; 319b0e7dd80Sopenharmony_ci } else if (bufferSizeKB < MIN_BUFFER_SIZE || bufferSizeKB > maxBufferSizeKB) { 320b0e7dd80Sopenharmony_ci ConsoleLog("error: buffer size must be from 256 KB to " + std::to_string(maxBufferSizeKB / KB_PER_MB) + 321b0e7dd80Sopenharmony_ci " MB. eg: \"--buffer_size 18432\"."); 322b0e7dd80Sopenharmony_ci isTrue = false; 323b0e7dd80Sopenharmony_ci } 324b0e7dd80Sopenharmony_ci g_traceArgs.bufferSize = bufferSizeKB / PAGE_SIZE_KB * PAGE_SIZE_KB; 325b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "trace_clock")) { 326b0e7dd80Sopenharmony_ci regex re("[a-zA-Z]{4,6}"); 327b0e7dd80Sopenharmony_ci if (regex_match(optarg, re)) { 328b0e7dd80Sopenharmony_ci g_traceArgs.clockType = optarg; 329b0e7dd80Sopenharmony_ci } else { 330b0e7dd80Sopenharmony_ci ConsoleLog("error: \"--trace_clock\" is illegal input. eg: \"--trace_clock boot\"."); 331b0e7dd80Sopenharmony_ci isTrue = false; 332b0e7dd80Sopenharmony_ci } 333b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "help")) { 334b0e7dd80Sopenharmony_ci isTrue = SetRunningState(SHOW_HELP); 335b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "time")) { 336b0e7dd80Sopenharmony_ci if (!StrToNum(optarg, g_traceArgs.duration)) { 337b0e7dd80Sopenharmony_ci ConsoleLog("error: the time is illegal input. eg: \"--time 5\"."); 338b0e7dd80Sopenharmony_ci isTrue = false; 339b0e7dd80Sopenharmony_ci } else if (g_traceArgs.duration < 1) { 340b0e7dd80Sopenharmony_ci ConsoleLog("error: \"-t " + std::string(optarg) + "\" to be greater than zero. eg: \"--time 5\"."); 341b0e7dd80Sopenharmony_ci isTrue = false; 342b0e7dd80Sopenharmony_ci } 343b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "list_categories")) { 344b0e7dd80Sopenharmony_ci isTrue = SetRunningState(SHOW_LIST_CATEGORY); 345b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "output")) { 346b0e7dd80Sopenharmony_ci isTrue = CheckOutputFile(optarg); 347b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "overwrite")) { 348b0e7dd80Sopenharmony_ci g_traceArgs.overwrite = false; 349b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "trace_begin")) { 350b0e7dd80Sopenharmony_ci isTrue = SetRunningState(RECORDING_LONG_BEGIN); 351b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "trace_finish")) { 352b0e7dd80Sopenharmony_ci isTrue = SetRunningState(RECORDING_LONG_FINISH); 353b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "trace_finish_nodump")) { 354b0e7dd80Sopenharmony_ci isTrue = SetRunningState(RECORDING_LONG_FINISH_NODUMP); 355b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "trace_dump")) { 356b0e7dd80Sopenharmony_ci isTrue = SetRunningState(RECORDING_LONG_DUMP); 357b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "record")) { 358b0e7dd80Sopenharmony_ci if (g_runningState == RECORDING_LONG_BEGIN) { 359b0e7dd80Sopenharmony_ci g_runningState = RECORDING_LONG_BEGIN_RECORD; 360b0e7dd80Sopenharmony_ci } else if (g_runningState == RECORDING_LONG_FINISH) { 361b0e7dd80Sopenharmony_ci g_runningState = RECORDING_LONG_FINISH_RECORD; 362b0e7dd80Sopenharmony_ci } else { 363b0e7dd80Sopenharmony_ci ConsoleLog("error: \"--record\" is set incorrectly. eg: \"--trace_begin --record\"," 364b0e7dd80Sopenharmony_ci " \"--trace_finish --record\"."); 365b0e7dd80Sopenharmony_ci isTrue = false; 366b0e7dd80Sopenharmony_ci } 367b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "start_bgsrv")) { 368b0e7dd80Sopenharmony_ci isTrue = SetRunningState(SNAPSHOT_START); 369b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "dump_bgsrv")) { 370b0e7dd80Sopenharmony_ci isTrue = SetRunningState(SNAPSHOT_DUMP); 371b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "stop_bgsrv")) { 372b0e7dd80Sopenharmony_ci isTrue = SetRunningState(SNAPSHOT_STOP); 373b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "text")) { 374b0e7dd80Sopenharmony_ci isTrue = SetRunningState(RECORDING_SHORT_TEXT); 375b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "raw")) { 376b0e7dd80Sopenharmony_ci isTrue = SetRunningState(RECORDING_SHORT_RAW); 377b0e7dd80Sopenharmony_ci } else if (!strcmp(LONG_OPTIONS[optionIndex].name, "file_size")) { 378b0e7dd80Sopenharmony_ci int fileSizeKB = 0; 379b0e7dd80Sopenharmony_ci if (!StrToNum(optarg, fileSizeKB)) { 380b0e7dd80Sopenharmony_ci ConsoleLog("error: file size is illegal input. eg: \"--file_size 102400\"."); 381b0e7dd80Sopenharmony_ci isTrue = false; 382b0e7dd80Sopenharmony_ci } else if (fileSizeKB < MIN_FILE_SIZE || fileSizeKB > MAX_FILE_SIZE) { 383b0e7dd80Sopenharmony_ci ConsoleLog("error: file size must be from 50 MB to 500 MB. eg: \"--file_size 102400\"."); 384b0e7dd80Sopenharmony_ci isTrue = false; 385b0e7dd80Sopenharmony_ci } 386b0e7dd80Sopenharmony_ci g_traceArgs.fileSize = fileSizeKB; 387b0e7dd80Sopenharmony_ci } 388b0e7dd80Sopenharmony_ci 389b0e7dd80Sopenharmony_ci return isTrue; 390b0e7dd80Sopenharmony_ci} 391b0e7dd80Sopenharmony_ci 392b0e7dd80Sopenharmony_cistatic bool ParseOpt(int opt, char** argv, int optIndex) 393b0e7dd80Sopenharmony_ci{ 394b0e7dd80Sopenharmony_ci bool isTrue = true; 395b0e7dd80Sopenharmony_ci switch (opt) { 396b0e7dd80Sopenharmony_ci case 'b': { 397b0e7dd80Sopenharmony_ci int bufferSizeKB = 0; 398b0e7dd80Sopenharmony_ci int maxBufferSizeKB = MAX_BUFFER_SIZE; 399b0e7dd80Sopenharmony_ci if (IsHmKernel()) { 400b0e7dd80Sopenharmony_ci maxBufferSizeKB = HM_MAX_BUFFER_SIZE; 401b0e7dd80Sopenharmony_ci } 402b0e7dd80Sopenharmony_ci if (!StrToNum(optarg, bufferSizeKB)) { 403b0e7dd80Sopenharmony_ci ConsoleLog("error: buffer size is illegal input. eg: \"--buffer_size 18432\"."); 404b0e7dd80Sopenharmony_ci isTrue = false; 405b0e7dd80Sopenharmony_ci } else if (bufferSizeKB < MIN_BUFFER_SIZE || bufferSizeKB > maxBufferSizeKB) { 406b0e7dd80Sopenharmony_ci ConsoleLog("error: buffer size must be from 256 KB to " + std::to_string(maxBufferSizeKB / KB_PER_MB) + 407b0e7dd80Sopenharmony_ci " MB. eg: \"--buffer_size 18432\"."); 408b0e7dd80Sopenharmony_ci isTrue = false; 409b0e7dd80Sopenharmony_ci } 410b0e7dd80Sopenharmony_ci g_traceArgs.bufferSize = bufferSizeKB / PAGE_SIZE_KB * PAGE_SIZE_KB; 411b0e7dd80Sopenharmony_ci break; 412b0e7dd80Sopenharmony_ci } 413b0e7dd80Sopenharmony_ci case 'h': 414b0e7dd80Sopenharmony_ci isTrue = SetRunningState(SHOW_HELP); 415b0e7dd80Sopenharmony_ci break; 416b0e7dd80Sopenharmony_ci case 'l': 417b0e7dd80Sopenharmony_ci isTrue = SetRunningState(SHOW_LIST_CATEGORY); 418b0e7dd80Sopenharmony_ci break; 419b0e7dd80Sopenharmony_ci case 't': { 420b0e7dd80Sopenharmony_ci if (!StrToNum(optarg, g_traceArgs.duration)) { 421b0e7dd80Sopenharmony_ci ConsoleLog("error: the time is illegal input. eg: \"--time 5\"."); 422b0e7dd80Sopenharmony_ci isTrue = false; 423b0e7dd80Sopenharmony_ci } else if (g_traceArgs.duration < 1) { 424b0e7dd80Sopenharmony_ci ConsoleLog("error: \"-t " + std::string(optarg) + "\" to be greater than zero. eg: \"--time 5\"."); 425b0e7dd80Sopenharmony_ci isTrue = false; 426b0e7dd80Sopenharmony_ci } 427b0e7dd80Sopenharmony_ci break; 428b0e7dd80Sopenharmony_ci } 429b0e7dd80Sopenharmony_ci case 'o': { 430b0e7dd80Sopenharmony_ci isTrue = CheckOutputFile(optarg); 431b0e7dd80Sopenharmony_ci break; 432b0e7dd80Sopenharmony_ci } 433b0e7dd80Sopenharmony_ci case 'z': 434b0e7dd80Sopenharmony_ci g_traceArgs.isCompress = true; 435b0e7dd80Sopenharmony_ci break; 436b0e7dd80Sopenharmony_ci case 0: // long options 437b0e7dd80Sopenharmony_ci isTrue = ParseLongOpt(argv[0], optIndex); 438b0e7dd80Sopenharmony_ci break; 439b0e7dd80Sopenharmony_ci case '?': 440b0e7dd80Sopenharmony_ci isTrue = false; 441b0e7dd80Sopenharmony_ci break; 442b0e7dd80Sopenharmony_ci default: 443b0e7dd80Sopenharmony_ci break; 444b0e7dd80Sopenharmony_ci } 445b0e7dd80Sopenharmony_ci return isTrue; 446b0e7dd80Sopenharmony_ci} 447b0e7dd80Sopenharmony_ci 448b0e7dd80Sopenharmony_cistatic bool AddTagItems(int argc, char** argv) 449b0e7dd80Sopenharmony_ci{ 450b0e7dd80Sopenharmony_ci for (int i = optind; i < argc; i++) { 451b0e7dd80Sopenharmony_ci std::string tag = std::string(argv[i]); 452b0e7dd80Sopenharmony_ci if (g_allTags.find(tag) == g_allTags.end()) { 453b0e7dd80Sopenharmony_ci std::string errorInfo = "error: " + tag + " is not support category on this device."; 454b0e7dd80Sopenharmony_ci ConsoleLog(errorInfo); 455b0e7dd80Sopenharmony_ci return false; 456b0e7dd80Sopenharmony_ci } 457b0e7dd80Sopenharmony_ci 458b0e7dd80Sopenharmony_ci if (i == optind) { 459b0e7dd80Sopenharmony_ci g_traceArgs.tags = tag; 460b0e7dd80Sopenharmony_ci } else { 461b0e7dd80Sopenharmony_ci g_traceArgs.tags += ("," + tag); 462b0e7dd80Sopenharmony_ci } 463b0e7dd80Sopenharmony_ci } 464b0e7dd80Sopenharmony_ci return true; 465b0e7dd80Sopenharmony_ci} 466b0e7dd80Sopenharmony_ci 467b0e7dd80Sopenharmony_cistatic bool HandleOpt(int argc, char** argv) 468b0e7dd80Sopenharmony_ci{ 469b0e7dd80Sopenharmony_ci bool isTrue = true; 470b0e7dd80Sopenharmony_ci int opt = 0; 471b0e7dd80Sopenharmony_ci int optionIndex = 0; 472b0e7dd80Sopenharmony_ci string shortOption = "b:c:hlo:t:z"; 473b0e7dd80Sopenharmony_ci int argcSize = argc; 474b0e7dd80Sopenharmony_ci while (isTrue && argcSize-- > 0) { 475b0e7dd80Sopenharmony_ci opt = getopt_long(argc, argv, shortOption.c_str(), LONG_OPTIONS, &optionIndex); 476b0e7dd80Sopenharmony_ci if (opt < 0 && (!AddTagItems(argc, argv))) { 477b0e7dd80Sopenharmony_ci isTrue = false; 478b0e7dd80Sopenharmony_ci break; 479b0e7dd80Sopenharmony_ci } 480b0e7dd80Sopenharmony_ci isTrue = ParseOpt(opt, argv, optionIndex); 481b0e7dd80Sopenharmony_ci } 482b0e7dd80Sopenharmony_ci 483b0e7dd80Sopenharmony_ci return isTrue; 484b0e7dd80Sopenharmony_ci} 485b0e7dd80Sopenharmony_ci 486b0e7dd80Sopenharmony_cistatic void StopTrace() 487b0e7dd80Sopenharmony_ci{ 488b0e7dd80Sopenharmony_ci const int napTime = 10000; 489b0e7dd80Sopenharmony_ci usleep(napTime); 490b0e7dd80Sopenharmony_ci SetTraceTagsEnabled(0); 491b0e7dd80Sopenharmony_ci SetFtraceEnabled(TRACING_ON_PATH, false); 492b0e7dd80Sopenharmony_ci} 493b0e7dd80Sopenharmony_ci 494b0e7dd80Sopenharmony_cistatic void DumpCompressedTrace(int traceFd, int outFd) 495b0e7dd80Sopenharmony_ci{ 496b0e7dd80Sopenharmony_ci z_stream zs { nullptr }; 497b0e7dd80Sopenharmony_ci int flush = Z_NO_FLUSH; 498b0e7dd80Sopenharmony_ci ssize_t bytesWritten; 499b0e7dd80Sopenharmony_ci ssize_t bytesRead; 500b0e7dd80Sopenharmony_ci if (memset_s(&zs, sizeof(zs), 0, sizeof(zs)) != 0) { 501b0e7dd80Sopenharmony_ci ConsoleLog("error: zip stream buffer init failed."); 502b0e7dd80Sopenharmony_ci return; 503b0e7dd80Sopenharmony_ci } 504b0e7dd80Sopenharmony_ci int ret = deflateInit(&zs, Z_DEFAULT_COMPRESSION); 505b0e7dd80Sopenharmony_ci if (ret != Z_OK) { 506b0e7dd80Sopenharmony_ci ConsoleLog("error: initializing zlib failed ret " + std::to_string(ret)); 507b0e7dd80Sopenharmony_ci return; 508b0e7dd80Sopenharmony_ci } 509b0e7dd80Sopenharmony_ci std::unique_ptr<uint8_t[]> in = std::make_unique<uint8_t[]>(CHUNK_SIZE); 510b0e7dd80Sopenharmony_ci std::unique_ptr<uint8_t[]> out = std::make_unique<uint8_t[]>(CHUNK_SIZE); 511b0e7dd80Sopenharmony_ci if (!in || !out) { 512b0e7dd80Sopenharmony_ci ConsoleLog("error: couldn't allocate buffers."); 513b0e7dd80Sopenharmony_ci return; 514b0e7dd80Sopenharmony_ci } 515b0e7dd80Sopenharmony_ci zs.next_out = reinterpret_cast<Bytef*>(out.get()); 516b0e7dd80Sopenharmony_ci zs.avail_out = CHUNK_SIZE; 517b0e7dd80Sopenharmony_ci 518b0e7dd80Sopenharmony_ci do { 519b0e7dd80Sopenharmony_ci if (zs.avail_in == 0 && flush == Z_NO_FLUSH) { 520b0e7dd80Sopenharmony_ci bytesRead = TEMP_FAILURE_RETRY(read(traceFd, in.get(), CHUNK_SIZE)); 521b0e7dd80Sopenharmony_ci if (bytesRead == 0) { 522b0e7dd80Sopenharmony_ci flush = Z_FINISH; 523b0e7dd80Sopenharmony_ci } else if (bytesRead == -1) { 524b0e7dd80Sopenharmony_ci ConsoleLog("error: reading trace, errno " + std::to_string(errno)); 525b0e7dd80Sopenharmony_ci break; 526b0e7dd80Sopenharmony_ci } else { 527b0e7dd80Sopenharmony_ci zs.next_in = reinterpret_cast<Bytef*>(in.get()); 528b0e7dd80Sopenharmony_ci zs.avail_in = bytesRead; 529b0e7dd80Sopenharmony_ci } 530b0e7dd80Sopenharmony_ci } 531b0e7dd80Sopenharmony_ci if (zs.avail_out == 0) { 532b0e7dd80Sopenharmony_ci bytesWritten = TEMP_FAILURE_RETRY(write(outFd, out.get(), CHUNK_SIZE)); 533b0e7dd80Sopenharmony_ci if (bytesWritten < static_cast<ssize_t>(CHUNK_SIZE)) { 534b0e7dd80Sopenharmony_ci ConsoleLog("error: writing deflated trace, errno " + std::to_string(errno)); 535b0e7dd80Sopenharmony_ci break; 536b0e7dd80Sopenharmony_ci } 537b0e7dd80Sopenharmony_ci zs.next_out = reinterpret_cast<Bytef*>(out.get()); 538b0e7dd80Sopenharmony_ci zs.avail_out = CHUNK_SIZE; 539b0e7dd80Sopenharmony_ci } 540b0e7dd80Sopenharmony_ci ret = deflate(&zs, flush); 541b0e7dd80Sopenharmony_ci if (flush == Z_FINISH && ret == Z_STREAM_END) { 542b0e7dd80Sopenharmony_ci size_t have = CHUNK_SIZE - zs.avail_out; 543b0e7dd80Sopenharmony_ci bytesWritten = TEMP_FAILURE_RETRY(write(outFd, out.get(), have)); 544b0e7dd80Sopenharmony_ci if (static_cast<size_t>(bytesWritten) < have) { 545b0e7dd80Sopenharmony_ci ConsoleLog("error: writing deflated trace, errno " + std::to_string(errno)); 546b0e7dd80Sopenharmony_ci } 547b0e7dd80Sopenharmony_ci break; 548b0e7dd80Sopenharmony_ci } else if (ret != Z_OK) { 549b0e7dd80Sopenharmony_ci if (ret == Z_ERRNO) { 550b0e7dd80Sopenharmony_ci ConsoleLog("error: deflate failed with errno " + std::to_string(errno)); 551b0e7dd80Sopenharmony_ci } else { 552b0e7dd80Sopenharmony_ci ConsoleLog("error: deflate failed return " + std::to_string(ret)); 553b0e7dd80Sopenharmony_ci } 554b0e7dd80Sopenharmony_ci break; 555b0e7dd80Sopenharmony_ci } 556b0e7dd80Sopenharmony_ci } while (ret == Z_OK); 557b0e7dd80Sopenharmony_ci 558b0e7dd80Sopenharmony_ci ret = deflateEnd(&zs); 559b0e7dd80Sopenharmony_ci if (ret != Z_OK) { 560b0e7dd80Sopenharmony_ci ConsoleLog("error: cleaning up zlib return " + std::to_string(ret)); 561b0e7dd80Sopenharmony_ci } 562b0e7dd80Sopenharmony_ci} 563b0e7dd80Sopenharmony_ci 564b0e7dd80Sopenharmony_cistatic void DumpTrace() 565b0e7dd80Sopenharmony_ci{ 566b0e7dd80Sopenharmony_ci std::string tracePath = g_traceRootPath + TRACE_PATH; 567b0e7dd80Sopenharmony_ci string traceSpecPath = OHOS::HiviewDFX::Hitrace::CanonicalizeSpecPath(tracePath.c_str()); 568b0e7dd80Sopenharmony_ci int traceFd = open(traceSpecPath.c_str(), O_RDONLY); 569b0e7dd80Sopenharmony_ci if (traceFd == -1) { 570b0e7dd80Sopenharmony_ci ConsoleLog("error: opening " + tracePath + ", errno: " + std::to_string(errno)); 571b0e7dd80Sopenharmony_ci return; 572b0e7dd80Sopenharmony_ci } 573b0e7dd80Sopenharmony_ci 574b0e7dd80Sopenharmony_ci int outFd = STDOUT_FILENO; 575b0e7dd80Sopenharmony_ci if (g_traceArgs.output.size() > 0) { 576b0e7dd80Sopenharmony_ci string outSpecPath = OHOS::HiviewDFX::Hitrace::CanonicalizeSpecPath(g_traceArgs.output.c_str()); 577b0e7dd80Sopenharmony_ci outFd = open(outSpecPath.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 578b0e7dd80Sopenharmony_ci } 579b0e7dd80Sopenharmony_ci 580b0e7dd80Sopenharmony_ci if (outFd == -1) { 581b0e7dd80Sopenharmony_ci ConsoleLog("error: opening " + g_traceArgs.output + ", errno: " + std::to_string(errno)); 582b0e7dd80Sopenharmony_ci close(traceFd); 583b0e7dd80Sopenharmony_ci return; 584b0e7dd80Sopenharmony_ci } 585b0e7dd80Sopenharmony_ci 586b0e7dd80Sopenharmony_ci ssize_t bytesWritten; 587b0e7dd80Sopenharmony_ci ssize_t bytesRead; 588b0e7dd80Sopenharmony_ci if (g_traceArgs.isCompress) { 589b0e7dd80Sopenharmony_ci DumpCompressedTrace(traceFd, outFd); 590b0e7dd80Sopenharmony_ci } else { 591b0e7dd80Sopenharmony_ci const int blockSize = 4096; 592b0e7dd80Sopenharmony_ci char buffer[blockSize]; 593b0e7dd80Sopenharmony_ci do { 594b0e7dd80Sopenharmony_ci bytesRead = TEMP_FAILURE_RETRY(read(traceFd, buffer, blockSize)); 595b0e7dd80Sopenharmony_ci if ((bytesRead == 0) || (bytesRead == -1)) { 596b0e7dd80Sopenharmony_ci break; 597b0e7dd80Sopenharmony_ci } 598b0e7dd80Sopenharmony_ci bytesWritten = TEMP_FAILURE_RETRY(write(outFd, buffer, bytesRead)); 599b0e7dd80Sopenharmony_ci } while (bytesWritten > 0); 600b0e7dd80Sopenharmony_ci } 601b0e7dd80Sopenharmony_ci 602b0e7dd80Sopenharmony_ci if (outFd != STDOUT_FILENO) { 603b0e7dd80Sopenharmony_ci ConsoleLog("trace read done, output: " + g_traceArgs.output); 604b0e7dd80Sopenharmony_ci close(outFd); 605b0e7dd80Sopenharmony_ci } 606b0e7dd80Sopenharmony_ci close(traceFd); 607b0e7dd80Sopenharmony_ci} 608b0e7dd80Sopenharmony_ci 609b0e7dd80Sopenharmony_cistatic bool InitAllSupportTags() 610b0e7dd80Sopenharmony_ci{ 611b0e7dd80Sopenharmony_ci if (!OHOS::HiviewDFX::Hitrace::ParseTagInfo(g_allTags, g_allTagGroups)) { 612b0e7dd80Sopenharmony_ci ConsoleLog("error: hitrace_utils.json file is damaged."); 613b0e7dd80Sopenharmony_ci return false; 614b0e7dd80Sopenharmony_ci } 615b0e7dd80Sopenharmony_ci return true; 616b0e7dd80Sopenharmony_ci} 617b0e7dd80Sopenharmony_ci 618b0e7dd80Sopenharmony_cistatic std::string ReloadTraceArgs() 619b0e7dd80Sopenharmony_ci{ 620b0e7dd80Sopenharmony_ci if (g_traceArgs.tags.size() == 0) { 621b0e7dd80Sopenharmony_ci ConsoleLog("error: tag is empty, please add."); 622b0e7dd80Sopenharmony_ci return ""; 623b0e7dd80Sopenharmony_ci } 624b0e7dd80Sopenharmony_ci std::string args = "tags:" + g_traceArgs.tags; 625b0e7dd80Sopenharmony_ci 626b0e7dd80Sopenharmony_ci if (g_traceArgs.bufferSize > 0) { 627b0e7dd80Sopenharmony_ci args += (" bufferSize:" + std::to_string(g_traceArgs.bufferSize)); 628b0e7dd80Sopenharmony_ci } else { 629b0e7dd80Sopenharmony_ci args += (" bufferSize:" + std::to_string(DEFAULT_BUFFER_SIZE)); 630b0e7dd80Sopenharmony_ci } 631b0e7dd80Sopenharmony_ci 632b0e7dd80Sopenharmony_ci if (g_traceArgs.clockType.size() > 0) { 633b0e7dd80Sopenharmony_ci args += (" clockType:" + g_traceArgs.clockType); 634b0e7dd80Sopenharmony_ci } 635b0e7dd80Sopenharmony_ci 636b0e7dd80Sopenharmony_ci if (g_traceArgs.overwrite) { 637b0e7dd80Sopenharmony_ci args += " overwrite:"; 638b0e7dd80Sopenharmony_ci args += "1"; 639b0e7dd80Sopenharmony_ci } else { 640b0e7dd80Sopenharmony_ci args += " overwrite:"; 641b0e7dd80Sopenharmony_ci args += "0"; 642b0e7dd80Sopenharmony_ci } 643b0e7dd80Sopenharmony_ci 644b0e7dd80Sopenharmony_ci if (g_traceArgs.fileSize > 0) { 645b0e7dd80Sopenharmony_ci if (g_runningState == RECORDING_SHORT_RAW || g_runningState == RECORDING_LONG_BEGIN_RECORD) { 646b0e7dd80Sopenharmony_ci args += (" fileSize:" + std::to_string(g_traceArgs.fileSize)); 647b0e7dd80Sopenharmony_ci } else { 648b0e7dd80Sopenharmony_ci ConsoleLog("warning: The current state does not support specifying the file size, file size: " + 649b0e7dd80Sopenharmony_ci std::to_string(g_traceArgs.fileSize) + " is invalid."); 650b0e7dd80Sopenharmony_ci } 651b0e7dd80Sopenharmony_ci } 652b0e7dd80Sopenharmony_ci 653b0e7dd80Sopenharmony_ci if (g_runningState != RECORDING_SHORT_TEXT) { 654b0e7dd80Sopenharmony_ci ConsoleLog("args: " + args); 655b0e7dd80Sopenharmony_ci } 656b0e7dd80Sopenharmony_ci return args; 657b0e7dd80Sopenharmony_ci} 658b0e7dd80Sopenharmony_ci 659b0e7dd80Sopenharmony_cistatic bool HandleRecordingShortRaw() 660b0e7dd80Sopenharmony_ci{ 661b0e7dd80Sopenharmony_ci std::string args = ReloadTraceArgs(); 662b0e7dd80Sopenharmony_ci if (g_traceArgs.output.size() > 0) { 663b0e7dd80Sopenharmony_ci ConsoleLog("warning: The current state does not support specifying the output file path, " + 664b0e7dd80Sopenharmony_ci g_traceArgs.output + " is invalid."); 665b0e7dd80Sopenharmony_ci } 666b0e7dd80Sopenharmony_ci auto openRet = g_traceCollector->OpenRecording(args); 667b0e7dd80Sopenharmony_ci if (openRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 668b0e7dd80Sopenharmony_ci ConsoleLog("error: OpenRecording failed, errorCode(" + std::to_string(openRet.retCode) +")"); 669b0e7dd80Sopenharmony_ci if (openRet.retCode == OHOS::HiviewDFX::UCollect::UcError::TRACE_IS_OCCUPIED || 670b0e7dd80Sopenharmony_ci openRet.retCode == OHOS::HiviewDFX::UCollect::UcError::TRACE_CALL_ERROR) { 671b0e7dd80Sopenharmony_ci return false; 672b0e7dd80Sopenharmony_ci } else { 673b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 674b0e7dd80Sopenharmony_ci return false; 675b0e7dd80Sopenharmony_ci } 676b0e7dd80Sopenharmony_ci } 677b0e7dd80Sopenharmony_ci 678b0e7dd80Sopenharmony_ci auto recOnRet = g_traceCollector->RecordingOn(); 679b0e7dd80Sopenharmony_ci if (recOnRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 680b0e7dd80Sopenharmony_ci ConsoleLog("error: RecordingOn failed, errorCode(" + std::to_string(recOnRet.retCode) +")"); 681b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 682b0e7dd80Sopenharmony_ci return false; 683b0e7dd80Sopenharmony_ci } 684b0e7dd80Sopenharmony_ci ConsoleLog("start capture, please wait " + std::to_string(g_traceArgs.duration) +"s ..."); 685b0e7dd80Sopenharmony_ci sleep(g_traceArgs.duration); 686b0e7dd80Sopenharmony_ci 687b0e7dd80Sopenharmony_ci auto recOffRet = g_traceCollector->RecordingOff(); 688b0e7dd80Sopenharmony_ci if (recOffRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 689b0e7dd80Sopenharmony_ci ConsoleLog("error: RecordingOff failed, errorCode(" + std::to_string(recOffRet.retCode) +")"); 690b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 691b0e7dd80Sopenharmony_ci return false; 692b0e7dd80Sopenharmony_ci } 693b0e7dd80Sopenharmony_ci ConsoleLog("capture done, output files:"); 694b0e7dd80Sopenharmony_ci for (std::string item : recOffRet.data) { 695b0e7dd80Sopenharmony_ci std::cout << " " << item << std::endl; 696b0e7dd80Sopenharmony_ci } 697b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 698b0e7dd80Sopenharmony_ci return true; 699b0e7dd80Sopenharmony_ci} 700b0e7dd80Sopenharmony_ci 701b0e7dd80Sopenharmony_cistatic bool HandleRecordingShortText() 702b0e7dd80Sopenharmony_ci{ 703b0e7dd80Sopenharmony_ci std::string args = ReloadTraceArgs(); 704b0e7dd80Sopenharmony_ci auto openRet = g_traceCollector->OpenRecording(args); 705b0e7dd80Sopenharmony_ci if (openRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 706b0e7dd80Sopenharmony_ci ConsoleLog("error: OpenRecording failed, errorCode(" + std::to_string(openRet.retCode) +")"); 707b0e7dd80Sopenharmony_ci if (openRet.retCode == OHOS::HiviewDFX::UCollect::UcError::TRACE_IS_OCCUPIED || 708b0e7dd80Sopenharmony_ci openRet.retCode == OHOS::HiviewDFX::UCollect::UcError::TRACE_CALL_ERROR) { 709b0e7dd80Sopenharmony_ci return false; 710b0e7dd80Sopenharmony_ci } else { 711b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 712b0e7dd80Sopenharmony_ci return false; 713b0e7dd80Sopenharmony_ci } 714b0e7dd80Sopenharmony_ci } 715b0e7dd80Sopenharmony_ci ConsoleLog("start capture, please wait " + std::to_string(g_traceArgs.duration) +"s ..."); 716b0e7dd80Sopenharmony_ci sleep(g_traceArgs.duration); 717b0e7dd80Sopenharmony_ci 718b0e7dd80Sopenharmony_ci OHOS::HiviewDFX::Hitrace::MarkClockSync(g_traceRootPath); 719b0e7dd80Sopenharmony_ci StopTrace(); 720b0e7dd80Sopenharmony_ci 721b0e7dd80Sopenharmony_ci if (g_traceArgs.output.size() > 0) { 722b0e7dd80Sopenharmony_ci ConsoleLog("capture done, start to read trace."); 723b0e7dd80Sopenharmony_ci } 724b0e7dd80Sopenharmony_ci DumpTrace(); 725b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 726b0e7dd80Sopenharmony_ci return true; 727b0e7dd80Sopenharmony_ci} 728b0e7dd80Sopenharmony_ci 729b0e7dd80Sopenharmony_cistatic bool HandleRecordingLongBegin() 730b0e7dd80Sopenharmony_ci{ 731b0e7dd80Sopenharmony_ci std::string args = ReloadTraceArgs(); 732b0e7dd80Sopenharmony_ci if (g_traceArgs.output.size() > 0) { 733b0e7dd80Sopenharmony_ci ConsoleLog("warning: The current state does not support specifying the output file path, " + 734b0e7dd80Sopenharmony_ci g_traceArgs.output + " is invalid."); 735b0e7dd80Sopenharmony_ci } 736b0e7dd80Sopenharmony_ci auto openRet = g_traceCollector->OpenRecording(args); 737b0e7dd80Sopenharmony_ci if (openRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 738b0e7dd80Sopenharmony_ci ConsoleLog("error: OpenRecording failed, errorCode(" + std::to_string(openRet.retCode) +")"); 739b0e7dd80Sopenharmony_ci if (openRet.retCode == OHOS::HiviewDFX::UCollect::UcError::TRACE_IS_OCCUPIED || 740b0e7dd80Sopenharmony_ci openRet.retCode == OHOS::HiviewDFX::UCollect::UcError::TRACE_CALL_ERROR) { 741b0e7dd80Sopenharmony_ci return false; 742b0e7dd80Sopenharmony_ci } else { 743b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 744b0e7dd80Sopenharmony_ci return false; 745b0e7dd80Sopenharmony_ci } 746b0e7dd80Sopenharmony_ci } 747b0e7dd80Sopenharmony_ci ConsoleLog("OpenRecording done."); 748b0e7dd80Sopenharmony_ci return true; 749b0e7dd80Sopenharmony_ci} 750b0e7dd80Sopenharmony_ci 751b0e7dd80Sopenharmony_cistatic bool HandleRecordingLongDump() 752b0e7dd80Sopenharmony_ci{ 753b0e7dd80Sopenharmony_ci OHOS::HiviewDFX::Hitrace::MarkClockSync(g_traceRootPath); 754b0e7dd80Sopenharmony_ci ConsoleLog("start to read trace."); 755b0e7dd80Sopenharmony_ci DumpTrace(); 756b0e7dd80Sopenharmony_ci return true; 757b0e7dd80Sopenharmony_ci} 758b0e7dd80Sopenharmony_ci 759b0e7dd80Sopenharmony_cistatic bool HandleRecordingLongFinish() 760b0e7dd80Sopenharmony_ci{ 761b0e7dd80Sopenharmony_ci OHOS::HiviewDFX::Hitrace::MarkClockSync(g_traceRootPath); 762b0e7dd80Sopenharmony_ci StopTrace(); 763b0e7dd80Sopenharmony_ci ConsoleLog("start to read trace."); 764b0e7dd80Sopenharmony_ci DumpTrace(); 765b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 766b0e7dd80Sopenharmony_ci return true; 767b0e7dd80Sopenharmony_ci} 768b0e7dd80Sopenharmony_ci 769b0e7dd80Sopenharmony_cistatic bool HandleRecordingLongFinishNodump() 770b0e7dd80Sopenharmony_ci{ 771b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 772b0e7dd80Sopenharmony_ci ConsoleLog("end capture trace."); 773b0e7dd80Sopenharmony_ci return true; 774b0e7dd80Sopenharmony_ci} 775b0e7dd80Sopenharmony_ci 776b0e7dd80Sopenharmony_cistatic bool HandleRecordingLongBeginRecord() 777b0e7dd80Sopenharmony_ci{ 778b0e7dd80Sopenharmony_ci std::string args = ReloadTraceArgs(); 779b0e7dd80Sopenharmony_ci if (g_traceArgs.output.size() > 0) { 780b0e7dd80Sopenharmony_ci ConsoleLog("warning: The current state does not support specifying the output file path, " + 781b0e7dd80Sopenharmony_ci g_traceArgs.output + " is invalid."); 782b0e7dd80Sopenharmony_ci } 783b0e7dd80Sopenharmony_ci auto openRet = g_traceCollector->OpenRecording(args); 784b0e7dd80Sopenharmony_ci if (openRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 785b0e7dd80Sopenharmony_ci ConsoleLog("error: OpenRecording failed, errorCode(" + std::to_string(openRet.retCode) +")"); 786b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 787b0e7dd80Sopenharmony_ci return false; 788b0e7dd80Sopenharmony_ci } 789b0e7dd80Sopenharmony_ci 790b0e7dd80Sopenharmony_ci auto recOnRet = g_traceCollector->RecordingOn(); 791b0e7dd80Sopenharmony_ci if (recOnRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 792b0e7dd80Sopenharmony_ci ConsoleLog("error: RecordingOn failed, errorCode(" + std::to_string(recOnRet.retCode) +")"); 793b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 794b0e7dd80Sopenharmony_ci return false; 795b0e7dd80Sopenharmony_ci } 796b0e7dd80Sopenharmony_ci ConsoleLog("trace capturing. "); 797b0e7dd80Sopenharmony_ci return true; 798b0e7dd80Sopenharmony_ci} 799b0e7dd80Sopenharmony_ci 800b0e7dd80Sopenharmony_cistatic bool HandleRecordingLongFinishRecord() 801b0e7dd80Sopenharmony_ci{ 802b0e7dd80Sopenharmony_ci auto recOffRet = g_traceCollector->RecordingOff(); 803b0e7dd80Sopenharmony_ci if (recOffRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 804b0e7dd80Sopenharmony_ci ConsoleLog("error: RecordingOff failed, errorCode(" + std::to_string(recOffRet.retCode) +")"); 805b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 806b0e7dd80Sopenharmony_ci return false; 807b0e7dd80Sopenharmony_ci } 808b0e7dd80Sopenharmony_ci ConsoleLog("capture done, output files:"); 809b0e7dd80Sopenharmony_ci for (std::string item : recOffRet.data) { 810b0e7dd80Sopenharmony_ci std::cout << " " << item << std::endl; 811b0e7dd80Sopenharmony_ci } 812b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 813b0e7dd80Sopenharmony_ci return true; 814b0e7dd80Sopenharmony_ci} 815b0e7dd80Sopenharmony_ci 816b0e7dd80Sopenharmony_cistatic bool HandleOpenSnapshot() 817b0e7dd80Sopenharmony_ci{ 818b0e7dd80Sopenharmony_ci std::vector<std::string> tagGroups = { "scene_performance" }; 819b0e7dd80Sopenharmony_ci auto openRet = g_traceCollector->OpenSnapshot(tagGroups); 820b0e7dd80Sopenharmony_ci if (openRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 821b0e7dd80Sopenharmony_ci ConsoleLog("error: OpenSnapshot failed, errorCode(" + std::to_string(openRet.retCode) +")"); 822b0e7dd80Sopenharmony_ci if (openRet.retCode == OHOS::HiviewDFX::UCollect::UcError::TRACE_IS_OCCUPIED || 823b0e7dd80Sopenharmony_ci openRet.retCode == OHOS::HiviewDFX::UCollect::UcError::TRACE_CALL_ERROR) { 824b0e7dd80Sopenharmony_ci return false; 825b0e7dd80Sopenharmony_ci } else { 826b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 827b0e7dd80Sopenharmony_ci return false; 828b0e7dd80Sopenharmony_ci } 829b0e7dd80Sopenharmony_ci } 830b0e7dd80Sopenharmony_ci ConsoleLog("OpenSnapshot done."); 831b0e7dd80Sopenharmony_ci return true; 832b0e7dd80Sopenharmony_ci} 833b0e7dd80Sopenharmony_ci 834b0e7dd80Sopenharmony_cistatic bool HandleDumpSnapshot() 835b0e7dd80Sopenharmony_ci{ 836b0e7dd80Sopenharmony_ci bool isSuccess = true; 837b0e7dd80Sopenharmony_ci auto dumpRet = g_traceCollector->DumpSnapshot(OHOS::HiviewDFX::UCollect::TraceCaller::DEVELOP); 838b0e7dd80Sopenharmony_ci if (dumpRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 839b0e7dd80Sopenharmony_ci ConsoleLog("error: DumpSnapshot failed, errorCode(" + std::to_string(dumpRet.retCode) +")"); 840b0e7dd80Sopenharmony_ci isSuccess = false; 841b0e7dd80Sopenharmony_ci } else { 842b0e7dd80Sopenharmony_ci ConsoleLog("DumpSnapshot done, output:"); 843b0e7dd80Sopenharmony_ci for (std::string item : dumpRet.data) { 844b0e7dd80Sopenharmony_ci std::cout << " " << item << std::endl; 845b0e7dd80Sopenharmony_ci } 846b0e7dd80Sopenharmony_ci } 847b0e7dd80Sopenharmony_ci return isSuccess; 848b0e7dd80Sopenharmony_ci} 849b0e7dd80Sopenharmony_ci 850b0e7dd80Sopenharmony_cistatic bool HandleCloseSnapshot() 851b0e7dd80Sopenharmony_ci{ 852b0e7dd80Sopenharmony_ci bool isSuccess = true; 853b0e7dd80Sopenharmony_ci auto closeRet = g_traceCollector->Close(); 854b0e7dd80Sopenharmony_ci if (closeRet.retCode != OHOS::HiviewDFX::UCollect::UcError::SUCCESS) { 855b0e7dd80Sopenharmony_ci ConsoleLog("error: CloseSnapshot failed, errorCode(" + std::to_string(closeRet.retCode) +")"); 856b0e7dd80Sopenharmony_ci isSuccess = false; 857b0e7dd80Sopenharmony_ci } else { 858b0e7dd80Sopenharmony_ci ConsoleLog("CloseSnapshot done."); 859b0e7dd80Sopenharmony_ci } 860b0e7dd80Sopenharmony_ci return isSuccess; 861b0e7dd80Sopenharmony_ci} 862b0e7dd80Sopenharmony_ci 863b0e7dd80Sopenharmony_cistatic void InterruptExit(int signo) 864b0e7dd80Sopenharmony_ci{ 865b0e7dd80Sopenharmony_ci /** 866b0e7dd80Sopenharmony_ci * trace reset. 867b0e7dd80Sopenharmony_ci */ 868b0e7dd80Sopenharmony_ci g_traceCollector->Recover(); 869b0e7dd80Sopenharmony_ci _exit(-1); 870b0e7dd80Sopenharmony_ci} 871b0e7dd80Sopenharmony_ci 872b0e7dd80Sopenharmony_ciint main(int argc, char **argv) 873b0e7dd80Sopenharmony_ci{ 874b0e7dd80Sopenharmony_ci if (!IsDeveloperMode()) { 875b0e7dd80Sopenharmony_ci ConsoleLog("error: not in developermode, exit"); 876b0e7dd80Sopenharmony_ci return -1; 877b0e7dd80Sopenharmony_ci } 878b0e7dd80Sopenharmony_ci 879b0e7dd80Sopenharmony_ci if (argc < 0 || argc > 256) { // 256 : max input argument counts 880b0e7dd80Sopenharmony_ci ConsoleLog("error: the number of input arguments exceeds the upper limit."); 881b0e7dd80Sopenharmony_ci return -1; 882b0e7dd80Sopenharmony_ci } 883b0e7dd80Sopenharmony_ci bool isSuccess = true; 884b0e7dd80Sopenharmony_ci g_traceCollector = OHOS::HiviewDFX::UCollectClient::TraceCollector::Create(); 885b0e7dd80Sopenharmony_ci if (g_traceCollector == nullptr) { 886b0e7dd80Sopenharmony_ci ConsoleLog("error: traceCollector create failed, exit."); 887b0e7dd80Sopenharmony_ci return -1; 888b0e7dd80Sopenharmony_ci } 889b0e7dd80Sopenharmony_ci (void)signal(SIGKILL, InterruptExit); 890b0e7dd80Sopenharmony_ci (void)signal(SIGINT, InterruptExit); 891b0e7dd80Sopenharmony_ci 892b0e7dd80Sopenharmony_ci if (!IsTraceMounted()) { 893b0e7dd80Sopenharmony_ci ConsoleLog("error: trace isn't mounted, exit."); 894b0e7dd80Sopenharmony_ci return -1; 895b0e7dd80Sopenharmony_ci } 896b0e7dd80Sopenharmony_ci 897b0e7dd80Sopenharmony_ci if (!InitAllSupportTags()) { 898b0e7dd80Sopenharmony_ci return -1; 899b0e7dd80Sopenharmony_ci } 900b0e7dd80Sopenharmony_ci 901b0e7dd80Sopenharmony_ci if (!HandleOpt(argc, argv)) { 902b0e7dd80Sopenharmony_ci ConsoleLog("error: parsing args failed, exit."); 903b0e7dd80Sopenharmony_ci return -1; 904b0e7dd80Sopenharmony_ci } 905b0e7dd80Sopenharmony_ci 906b0e7dd80Sopenharmony_ci if (g_runningState == STATE_NULL) { 907b0e7dd80Sopenharmony_ci g_runningState = RECORDING_SHORT_TEXT; 908b0e7dd80Sopenharmony_ci } 909b0e7dd80Sopenharmony_ci 910b0e7dd80Sopenharmony_ci if (g_runningState != RECORDING_SHORT_TEXT && g_runningState != RECORDING_LONG_DUMP && 911b0e7dd80Sopenharmony_ci g_runningState != RECORDING_LONG_FINISH) { 912b0e7dd80Sopenharmony_ci ConsoleLog(std::string(argv[0]) + " enter, running_state is " + GetStateInfo(g_runningState)); 913b0e7dd80Sopenharmony_ci } 914b0e7dd80Sopenharmony_ci 915b0e7dd80Sopenharmony_ci switch (g_runningState) { 916b0e7dd80Sopenharmony_ci case RECORDING_SHORT_RAW: 917b0e7dd80Sopenharmony_ci isSuccess = HandleRecordingShortRaw(); 918b0e7dd80Sopenharmony_ci break; 919b0e7dd80Sopenharmony_ci case RECORDING_SHORT_TEXT: 920b0e7dd80Sopenharmony_ci isSuccess = HandleRecordingShortText(); 921b0e7dd80Sopenharmony_ci break; 922b0e7dd80Sopenharmony_ci case RECORDING_LONG_BEGIN: 923b0e7dd80Sopenharmony_ci isSuccess = HandleRecordingLongBegin(); 924b0e7dd80Sopenharmony_ci break; 925b0e7dd80Sopenharmony_ci case RECORDING_LONG_DUMP: 926b0e7dd80Sopenharmony_ci isSuccess = HandleRecordingLongDump(); 927b0e7dd80Sopenharmony_ci break; 928b0e7dd80Sopenharmony_ci case RECORDING_LONG_FINISH: 929b0e7dd80Sopenharmony_ci isSuccess = HandleRecordingLongFinish(); 930b0e7dd80Sopenharmony_ci break; 931b0e7dd80Sopenharmony_ci case RECORDING_LONG_FINISH_NODUMP: 932b0e7dd80Sopenharmony_ci isSuccess = HandleRecordingLongFinishNodump(); 933b0e7dd80Sopenharmony_ci break; 934b0e7dd80Sopenharmony_ci case RECORDING_LONG_BEGIN_RECORD: 935b0e7dd80Sopenharmony_ci isSuccess = HandleRecordingLongBeginRecord(); 936b0e7dd80Sopenharmony_ci break; 937b0e7dd80Sopenharmony_ci case RECORDING_LONG_FINISH_RECORD: 938b0e7dd80Sopenharmony_ci isSuccess = HandleRecordingLongFinishRecord(); 939b0e7dd80Sopenharmony_ci break; 940b0e7dd80Sopenharmony_ci case SNAPSHOT_START: 941b0e7dd80Sopenharmony_ci isSuccess = HandleOpenSnapshot(); 942b0e7dd80Sopenharmony_ci break; 943b0e7dd80Sopenharmony_ci case SNAPSHOT_DUMP: 944b0e7dd80Sopenharmony_ci isSuccess = HandleDumpSnapshot(); 945b0e7dd80Sopenharmony_ci break; 946b0e7dd80Sopenharmony_ci case SNAPSHOT_STOP: 947b0e7dd80Sopenharmony_ci isSuccess = HandleCloseSnapshot(); 948b0e7dd80Sopenharmony_ci break; 949b0e7dd80Sopenharmony_ci case SHOW_HELP: 950b0e7dd80Sopenharmony_ci ShowHelp(argv[0]); 951b0e7dd80Sopenharmony_ci break; 952b0e7dd80Sopenharmony_ci case SHOW_LIST_CATEGORY: 953b0e7dd80Sopenharmony_ci ShowListCategory(); 954b0e7dd80Sopenharmony_ci break; 955b0e7dd80Sopenharmony_ci default: 956b0e7dd80Sopenharmony_ci ShowHelp(argv[0]); 957b0e7dd80Sopenharmony_ci isSuccess = false; 958b0e7dd80Sopenharmony_ci break; 959b0e7dd80Sopenharmony_ci } 960b0e7dd80Sopenharmony_ci return isSuccess ? 0 : -1; 961b0e7dd80Sopenharmony_ci} 962