1b0e7dd80Sopenharmony_ci/* 2b0e7dd80Sopenharmony_ci * Copyright (C) 2023-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 "hitrace_dump.h" 17b0e7dd80Sopenharmony_ci 18b0e7dd80Sopenharmony_ci#include <atomic> 19b0e7dd80Sopenharmony_ci#include <cinttypes> 20b0e7dd80Sopenharmony_ci#include <csignal> 21b0e7dd80Sopenharmony_ci#include <fstream> 22b0e7dd80Sopenharmony_ci#include <map> 23b0e7dd80Sopenharmony_ci#include <memory> 24b0e7dd80Sopenharmony_ci#include <mutex> 25b0e7dd80Sopenharmony_ci#include <set> 26b0e7dd80Sopenharmony_ci#include <sys/epoll.h> 27b0e7dd80Sopenharmony_ci#include <sys/prctl.h> 28b0e7dd80Sopenharmony_ci#include <sys/sysinfo.h> 29b0e7dd80Sopenharmony_ci#include <sys/wait.h> 30b0e7dd80Sopenharmony_ci#include <thread> 31b0e7dd80Sopenharmony_ci#include <unistd.h> 32b0e7dd80Sopenharmony_ci 33b0e7dd80Sopenharmony_ci#include "common_utils.h" 34b0e7dd80Sopenharmony_ci#include "dynamic_buffer.h" 35b0e7dd80Sopenharmony_ci#include "hitrace_meter.h" 36b0e7dd80Sopenharmony_ci#include "hilog/log.h" 37b0e7dd80Sopenharmony_ci#include "hitrace_osal.h" 38b0e7dd80Sopenharmony_ci#include "parameters.h" 39b0e7dd80Sopenharmony_ci#include "securec.h" 40b0e7dd80Sopenharmony_ci#include "trace_utils.h" 41b0e7dd80Sopenharmony_ci 42b0e7dd80Sopenharmony_ciusing namespace std; 43b0e7dd80Sopenharmony_ciusing namespace OHOS::HiviewDFX::HitraceOsal; 44b0e7dd80Sopenharmony_ciusing OHOS::HiviewDFX::HiLog; 45b0e7dd80Sopenharmony_ci 46b0e7dd80Sopenharmony_cinamespace OHOS { 47b0e7dd80Sopenharmony_cinamespace HiviewDFX { 48b0e7dd80Sopenharmony_cinamespace Hitrace { 49b0e7dd80Sopenharmony_ci 50b0e7dd80Sopenharmony_cinamespace { 51b0e7dd80Sopenharmony_ci 52b0e7dd80Sopenharmony_cistruct TraceParams { 53b0e7dd80Sopenharmony_ci std::vector<std::string> tags; 54b0e7dd80Sopenharmony_ci std::vector<std::string> tagGroups; 55b0e7dd80Sopenharmony_ci std::string bufferSize; 56b0e7dd80Sopenharmony_ci std::string clockType; 57b0e7dd80Sopenharmony_ci std::string isOverWrite; 58b0e7dd80Sopenharmony_ci std::string outputFile; 59b0e7dd80Sopenharmony_ci int fileLimit; 60b0e7dd80Sopenharmony_ci int fileSize; 61b0e7dd80Sopenharmony_ci int appPid; 62b0e7dd80Sopenharmony_ci}; 63b0e7dd80Sopenharmony_ci 64b0e7dd80Sopenharmony_ciconstexpr uint16_t MAGIC_NUMBER = 57161; 65b0e7dd80Sopenharmony_ciconstexpr uint16_t VERSION_NUMBER = 1; 66b0e7dd80Sopenharmony_ciconstexpr uint8_t FILE_RAW_TRACE = 0; 67b0e7dd80Sopenharmony_ciconstexpr uint8_t HM_FILE_RAW_TRACE = 1; 68b0e7dd80Sopenharmony_ciconstexpr int UNIT_TIME = 100000; 69b0e7dd80Sopenharmony_ciconstexpr int ALIGNMENT_COEFFICIENT = 4; 70b0e7dd80Sopenharmony_ci 71b0e7dd80Sopenharmony_ciconst int DEFAULT_BUFFER_SIZE = 12 * 1024; 72b0e7dd80Sopenharmony_ciconst int DEFAULT_FILE_SIZE = 100 * 1024; 73b0e7dd80Sopenharmony_ci#ifdef DOUBLE_TRACEBUFFER_ENABLE 74b0e7dd80Sopenharmony_ciconst int HM_DEFAULT_BUFFER_SIZE = 288 * 1024; 75b0e7dd80Sopenharmony_ci#else 76b0e7dd80Sopenharmony_ciconst int HM_DEFAULT_BUFFER_SIZE = 144 * 1024; 77b0e7dd80Sopenharmony_ci#endif 78b0e7dd80Sopenharmony_ciconst int SAVED_CMDLINES_SIZE = 3072; // 3M 79b0e7dd80Sopenharmony_ciconst int KB_PER_MB = 1024; 80b0e7dd80Sopenharmony_ciconst uint64_t S_TO_NS = 1000000000; 81b0e7dd80Sopenharmony_ciconst int MAX_NEW_TRACE_FILE_LIMIT = 5; 82b0e7dd80Sopenharmony_ciconst int JUDGE_FILE_EXIST = 10; // Check whether the trace file exists every 10 times. 83b0e7dd80Sopenharmony_ciconst int SNAPSHOT_FILE_MAX_COUNT = 20; 84b0e7dd80Sopenharmony_ci 85b0e7dd80Sopenharmony_ciconst std::string DEFAULT_OUTPUT_DIR = "/data/log/hitrace/"; 86b0e7dd80Sopenharmony_ciconst std::string SAVED_EVENTS_FORMAT = "saved_events_format"; 87b0e7dd80Sopenharmony_ci 88b0e7dd80Sopenharmony_cistruct alignas(ALIGNMENT_COEFFICIENT) TraceFileHeader { 89b0e7dd80Sopenharmony_ci uint16_t magicNumber {MAGIC_NUMBER}; 90b0e7dd80Sopenharmony_ci uint8_t fileType {FILE_RAW_TRACE}; 91b0e7dd80Sopenharmony_ci uint16_t versionNumber {VERSION_NUMBER}; 92b0e7dd80Sopenharmony_ci uint32_t reserved {0}; 93b0e7dd80Sopenharmony_ci}; 94b0e7dd80Sopenharmony_ci 95b0e7dd80Sopenharmony_cienum ContentType : uint8_t { 96b0e7dd80Sopenharmony_ci CONTENT_TYPE_DEFAULT = 0, 97b0e7dd80Sopenharmony_ci CONTENT_TYPE_EVENTS_FORMAT = 1, 98b0e7dd80Sopenharmony_ci CONTENT_TYPE_CMDLINES = 2, 99b0e7dd80Sopenharmony_ci CONTENT_TYPE_TGIDS = 3, 100b0e7dd80Sopenharmony_ci CONTENT_TYPE_CPU_RAW = 4, 101b0e7dd80Sopenharmony_ci CONTENT_TYPE_HEADER_PAGE = 30, 102b0e7dd80Sopenharmony_ci CONTENT_TYPE_PRINTK_FORMATS = 31, 103b0e7dd80Sopenharmony_ci CONTENT_TYPE_KALLSYMS = 32 104b0e7dd80Sopenharmony_ci}; 105b0e7dd80Sopenharmony_ci 106b0e7dd80Sopenharmony_cistruct alignas(ALIGNMENT_COEFFICIENT) TraceFileContentHeader { 107b0e7dd80Sopenharmony_ci uint8_t type = CONTENT_TYPE_DEFAULT; 108b0e7dd80Sopenharmony_ci uint32_t length = 0; 109b0e7dd80Sopenharmony_ci}; 110b0e7dd80Sopenharmony_ci 111b0e7dd80Sopenharmony_cistruct PageHeader { 112b0e7dd80Sopenharmony_ci uint64_t timestamp = 0; 113b0e7dd80Sopenharmony_ci uint64_t size = 0; 114b0e7dd80Sopenharmony_ci uint8_t overwrite = 0; 115b0e7dd80Sopenharmony_ci uint8_t *startPos = nullptr; 116b0e7dd80Sopenharmony_ci uint8_t *endPos = nullptr; 117b0e7dd80Sopenharmony_ci}; 118b0e7dd80Sopenharmony_ci 119b0e7dd80Sopenharmony_ci#ifndef PAGE_SIZE 120b0e7dd80Sopenharmony_ciconstexpr size_t PAGE_SIZE = 4096; 121b0e7dd80Sopenharmony_ci#endif 122b0e7dd80Sopenharmony_ci 123b0e7dd80Sopenharmony_ciconst int BUFFER_SIZE = 256 * PAGE_SIZE; // 1M 124b0e7dd80Sopenharmony_ci 125b0e7dd80Sopenharmony_cistd::atomic<bool> g_dumpFlag(false); 126b0e7dd80Sopenharmony_cistd::atomic<bool> g_dumpEnd(true); 127b0e7dd80Sopenharmony_cistd::mutex g_traceMutex; 128b0e7dd80Sopenharmony_ci 129b0e7dd80Sopenharmony_cibool g_serviceThreadIsStart = false; 130b0e7dd80Sopenharmony_ciuint64_t g_sysInitParamTags = 0; 131b0e7dd80Sopenharmony_ciTraceMode g_traceMode = TraceMode::CLOSE; 132b0e7dd80Sopenharmony_cistd::string g_traceRootPath; 133b0e7dd80Sopenharmony_ciuint8_t g_buffer[BUFFER_SIZE] = {0}; 134b0e7dd80Sopenharmony_cistd::vector<std::pair<std::string, int>> g_traceFilesTable; 135b0e7dd80Sopenharmony_cistd::vector<std::string> g_outputFilesForCmd; 136b0e7dd80Sopenharmony_ciint g_outputFileSize = 0; 137b0e7dd80Sopenharmony_ciint g_inputMaxDuration = 0; 138b0e7dd80Sopenharmony_ciuint64_t g_inputTraceEndTime = 0; // in nano seconds 139b0e7dd80Sopenharmony_ciint g_newTraceFileLimit = 0; 140b0e7dd80Sopenharmony_ciint g_writeFileLimit = 0; 141b0e7dd80Sopenharmony_cibool g_needGenerateNewTraceFile = false; 142b0e7dd80Sopenharmony_ciuint64_t g_traceStartTime = 0; 143b0e7dd80Sopenharmony_ciuint64_t g_traceEndTime = std::numeric_limits<uint64_t>::max(); // in nano seconds 144b0e7dd80Sopenharmony_cistd::atomic<uint8_t> g_dumpStatus(TraceErrorCode::UNSET); 145b0e7dd80Sopenharmony_ci 146b0e7dd80Sopenharmony_ciTraceParams g_currentTraceParams = {}; 147b0e7dd80Sopenharmony_ci 148b0e7dd80Sopenharmony_cistd::string GetFilePath(const std::string &fileName) 149b0e7dd80Sopenharmony_ci{ 150b0e7dd80Sopenharmony_ci return g_traceRootPath + fileName; 151b0e7dd80Sopenharmony_ci} 152b0e7dd80Sopenharmony_ci 153b0e7dd80Sopenharmony_cistd::vector<std::string> Split(const std::string &str, char delimiter) 154b0e7dd80Sopenharmony_ci{ 155b0e7dd80Sopenharmony_ci std::vector<std::string> res; 156b0e7dd80Sopenharmony_ci size_t startPos = 0; 157b0e7dd80Sopenharmony_ci for (size_t i = 0; i < str.size(); i++) { 158b0e7dd80Sopenharmony_ci if (str[i] == delimiter) { 159b0e7dd80Sopenharmony_ci res.push_back(str.substr(startPos, i - startPos)); 160b0e7dd80Sopenharmony_ci startPos = i + 1; 161b0e7dd80Sopenharmony_ci } 162b0e7dd80Sopenharmony_ci } 163b0e7dd80Sopenharmony_ci if (startPos < str.size()) { 164b0e7dd80Sopenharmony_ci res.push_back(str.substr(startPos)); 165b0e7dd80Sopenharmony_ci } 166b0e7dd80Sopenharmony_ci return res; 167b0e7dd80Sopenharmony_ci} 168b0e7dd80Sopenharmony_ci 169b0e7dd80Sopenharmony_cibool IsTraceMounted() 170b0e7dd80Sopenharmony_ci{ 171b0e7dd80Sopenharmony_ci const std::string debugfsPath = "/sys/kernel/debug/tracing/"; 172b0e7dd80Sopenharmony_ci const std::string tracefsPath = "/sys/kernel/tracing/"; 173b0e7dd80Sopenharmony_ci if (access((debugfsPath + "trace_marker").c_str(), F_OK) != -1) { 174b0e7dd80Sopenharmony_ci g_traceRootPath = debugfsPath; 175b0e7dd80Sopenharmony_ci return true; 176b0e7dd80Sopenharmony_ci } 177b0e7dd80Sopenharmony_ci if (access((tracefsPath + "trace_marker").c_str(), F_OK) != -1) { 178b0e7dd80Sopenharmony_ci g_traceRootPath = tracefsPath; 179b0e7dd80Sopenharmony_ci return true; 180b0e7dd80Sopenharmony_ci } 181b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "IsTraceMounted: Did not find trace folder"); 182b0e7dd80Sopenharmony_ci return false; 183b0e7dd80Sopenharmony_ci} 184b0e7dd80Sopenharmony_ci 185b0e7dd80Sopenharmony_ci// Arch is 64bit when reserved = 0; Arch is 32bit when reserved = 1. 186b0e7dd80Sopenharmony_civoid GetArchWordSize(TraceFileHeader& header) 187b0e7dd80Sopenharmony_ci{ 188b0e7dd80Sopenharmony_ci if (sizeof(void*) == sizeof(uint64_t)) { 189b0e7dd80Sopenharmony_ci header.reserved |= 0; 190b0e7dd80Sopenharmony_ci } else if (sizeof(void*) == sizeof(uint32_t)) { 191b0e7dd80Sopenharmony_ci header.reserved |= 1; 192b0e7dd80Sopenharmony_ci } 193b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "reserved with arch word info is %{public}d.", header.reserved); 194b0e7dd80Sopenharmony_ci} 195b0e7dd80Sopenharmony_ci 196b0e7dd80Sopenharmony_civoid GetCpuNums(TraceFileHeader& header) 197b0e7dd80Sopenharmony_ci{ 198b0e7dd80Sopenharmony_ci const int maxCpuNums = 24; 199b0e7dd80Sopenharmony_ci int cpuNums = GetCpuProcessors(); 200b0e7dd80Sopenharmony_ci if (cpuNums > maxCpuNums || cpuNums <= 0) { 201b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "error: cpu_number is %{public}d.", cpuNums); 202b0e7dd80Sopenharmony_ci return; 203b0e7dd80Sopenharmony_ci } 204b0e7dd80Sopenharmony_ci header.reserved |= (static_cast<uint64_t>(cpuNums) << 1); 205b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "reserved with cpu number info is %{public}d.", header.reserved); 206b0e7dd80Sopenharmony_ci} 207b0e7dd80Sopenharmony_ci 208b0e7dd80Sopenharmony_cibool CheckTags(const std::vector<std::string> &tags, const std::map<std::string, TagCategory> &allTags) 209b0e7dd80Sopenharmony_ci{ 210b0e7dd80Sopenharmony_ci for (const auto &tag : tags) { 211b0e7dd80Sopenharmony_ci if (allTags.find(tag) == allTags.end()) { 212b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "CheckTags: %{public}s is not provided.", tag.c_str()); 213b0e7dd80Sopenharmony_ci return false; 214b0e7dd80Sopenharmony_ci } 215b0e7dd80Sopenharmony_ci } 216b0e7dd80Sopenharmony_ci return true; 217b0e7dd80Sopenharmony_ci} 218b0e7dd80Sopenharmony_ci 219b0e7dd80Sopenharmony_cibool CheckTagGroup(const std::vector<std::string> &tagGroups, 220b0e7dd80Sopenharmony_ci const std::map<std::string, std::vector<std::string>> &tagGroupTable) 221b0e7dd80Sopenharmony_ci{ 222b0e7dd80Sopenharmony_ci for (auto groupName : tagGroups) { 223b0e7dd80Sopenharmony_ci if (tagGroupTable.find(groupName) == tagGroupTable.end()) { 224b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "CheckTagGroup: %{public}s is not provided.", groupName.c_str()); 225b0e7dd80Sopenharmony_ci return false; 226b0e7dd80Sopenharmony_ci } 227b0e7dd80Sopenharmony_ci } 228b0e7dd80Sopenharmony_ci return true; 229b0e7dd80Sopenharmony_ci} 230b0e7dd80Sopenharmony_ci 231b0e7dd80Sopenharmony_cibool WriteStrToFileInner(const std::string& filename, const std::string& str) 232b0e7dd80Sopenharmony_ci{ 233b0e7dd80Sopenharmony_ci std::ofstream out; 234b0e7dd80Sopenharmony_ci out.open(filename, std::ios::out); 235b0e7dd80Sopenharmony_ci if (out.fail()) { 236b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "WriteStrToFile: %{public}s open failed.", filename.c_str()); 237b0e7dd80Sopenharmony_ci return false; 238b0e7dd80Sopenharmony_ci } 239b0e7dd80Sopenharmony_ci out << str; 240b0e7dd80Sopenharmony_ci if (out.bad()) { 241b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "WriteStrToFile: %{public}s write failed.", filename.c_str()); 242b0e7dd80Sopenharmony_ci out.close(); 243b0e7dd80Sopenharmony_ci return false; 244b0e7dd80Sopenharmony_ci } 245b0e7dd80Sopenharmony_ci out.flush(); 246b0e7dd80Sopenharmony_ci out.close(); 247b0e7dd80Sopenharmony_ci return true; 248b0e7dd80Sopenharmony_ci} 249b0e7dd80Sopenharmony_ci 250b0e7dd80Sopenharmony_cibool WriteStrToFile(const std::string& filename, const std::string& str) 251b0e7dd80Sopenharmony_ci{ 252b0e7dd80Sopenharmony_ci if (access((g_traceRootPath + filename).c_str(), W_OK) < 0) { 253b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "WriteStrToFile: Failed to access %{public}s, errno(%{public}d).", 254b0e7dd80Sopenharmony_ci (g_traceRootPath + filename).c_str(), errno); 255b0e7dd80Sopenharmony_ci return false; 256b0e7dd80Sopenharmony_ci } 257b0e7dd80Sopenharmony_ci return WriteStrToFileInner(g_traceRootPath + filename, str); 258b0e7dd80Sopenharmony_ci} 259b0e7dd80Sopenharmony_ci 260b0e7dd80Sopenharmony_civoid SetTraceNodeStatus(const std::string &path, bool enabled) 261b0e7dd80Sopenharmony_ci{ 262b0e7dd80Sopenharmony_ci WriteStrToFile(path, enabled ? "1" : "0"); 263b0e7dd80Sopenharmony_ci} 264b0e7dd80Sopenharmony_ci 265b0e7dd80Sopenharmony_civoid TruncateFile() 266b0e7dd80Sopenharmony_ci{ 267b0e7dd80Sopenharmony_ci int fd = creat((g_traceRootPath + "trace").c_str(), 0); 268b0e7dd80Sopenharmony_ci if (fd == -1) { 269b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "TruncateFile: clear old trace failed."); 270b0e7dd80Sopenharmony_ci return; 271b0e7dd80Sopenharmony_ci } 272b0e7dd80Sopenharmony_ci close(fd); 273b0e7dd80Sopenharmony_ci return; 274b0e7dd80Sopenharmony_ci} 275b0e7dd80Sopenharmony_ci 276b0e7dd80Sopenharmony_cibool SetProperty(const std::string& property, const std::string& value) 277b0e7dd80Sopenharmony_ci{ 278b0e7dd80Sopenharmony_ci bool result = OHOS::system::SetParameter(property, value); 279b0e7dd80Sopenharmony_ci if (!result) { 280b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "SetProperty: set %{public}s failed.", value.c_str()); 281b0e7dd80Sopenharmony_ci } else { 282b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "SetProperty: set %{public}s success.", value.c_str()); 283b0e7dd80Sopenharmony_ci } 284b0e7dd80Sopenharmony_ci return result; 285b0e7dd80Sopenharmony_ci} 286b0e7dd80Sopenharmony_ci 287b0e7dd80Sopenharmony_ci// close all trace node 288b0e7dd80Sopenharmony_civoid TraceInit(const std::map<std::string, TagCategory> &allTags) 289b0e7dd80Sopenharmony_ci{ 290b0e7dd80Sopenharmony_ci // close all ftrace events 291b0e7dd80Sopenharmony_ci for (auto it = allTags.begin(); it != allTags.end(); it++) { 292b0e7dd80Sopenharmony_ci if (it->second.type != 1) { 293b0e7dd80Sopenharmony_ci continue; 294b0e7dd80Sopenharmony_ci } 295b0e7dd80Sopenharmony_ci for (size_t i = 0; i < it->second.sysFiles.size(); i++) { 296b0e7dd80Sopenharmony_ci SetTraceNodeStatus(it->second.sysFiles[i], false); 297b0e7dd80Sopenharmony_ci } 298b0e7dd80Sopenharmony_ci } 299b0e7dd80Sopenharmony_ci // close all user tags 300b0e7dd80Sopenharmony_ci SetProperty("debug.hitrace.tags.enableflags", std::to_string(0)); 301b0e7dd80Sopenharmony_ci 302b0e7dd80Sopenharmony_ci // set buffer_size_kb 1 303b0e7dd80Sopenharmony_ci WriteStrToFile("buffer_size_kb", "1"); 304b0e7dd80Sopenharmony_ci 305b0e7dd80Sopenharmony_ci // close tracing_on 306b0e7dd80Sopenharmony_ci SetTraceNodeStatus("tracing_on", false); 307b0e7dd80Sopenharmony_ci} 308b0e7dd80Sopenharmony_ci 309b0e7dd80Sopenharmony_ci// Open specific trace node 310b0e7dd80Sopenharmony_civoid SetAllTags(const TraceParams &traceParams, const std::map<std::string, TagCategory> &allTags, 311b0e7dd80Sopenharmony_ci const std::map<std::string, std::vector<std::string>> &tagGroupTable) 312b0e7dd80Sopenharmony_ci{ 313b0e7dd80Sopenharmony_ci std::set<std::string> readyEnableTagList; 314b0e7dd80Sopenharmony_ci for (std::string tagName : traceParams.tags) { 315b0e7dd80Sopenharmony_ci readyEnableTagList.insert(tagName); 316b0e7dd80Sopenharmony_ci } 317b0e7dd80Sopenharmony_ci 318b0e7dd80Sopenharmony_ci // if set tagGroup, need to append default group 319b0e7dd80Sopenharmony_ci if (traceParams.tagGroups.size() > 0) { 320b0e7dd80Sopenharmony_ci auto iter = tagGroupTable.find("default"); 321b0e7dd80Sopenharmony_ci if (iter == tagGroupTable.end()) { 322b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "SetAllTags: default group is wrong."); 323b0e7dd80Sopenharmony_ci } else { 324b0e7dd80Sopenharmony_ci for (auto defaultTag : iter->second) { 325b0e7dd80Sopenharmony_ci readyEnableTagList.insert(defaultTag); 326b0e7dd80Sopenharmony_ci } 327b0e7dd80Sopenharmony_ci } 328b0e7dd80Sopenharmony_ci } 329b0e7dd80Sopenharmony_ci 330b0e7dd80Sopenharmony_ci for (std::string groupName : traceParams.tagGroups) { 331b0e7dd80Sopenharmony_ci auto iter = tagGroupTable.find(groupName); 332b0e7dd80Sopenharmony_ci if (iter == tagGroupTable.end()) { 333b0e7dd80Sopenharmony_ci continue; 334b0e7dd80Sopenharmony_ci } 335b0e7dd80Sopenharmony_ci for (std::string tag : iter->second) { 336b0e7dd80Sopenharmony_ci readyEnableTagList.insert(tag); 337b0e7dd80Sopenharmony_ci } 338b0e7dd80Sopenharmony_ci } 339b0e7dd80Sopenharmony_ci 340b0e7dd80Sopenharmony_ci uint64_t enabledUserTags = 0; 341b0e7dd80Sopenharmony_ci for (std::string tagName : readyEnableTagList) { 342b0e7dd80Sopenharmony_ci auto iter = allTags.find(tagName); 343b0e7dd80Sopenharmony_ci if (iter == allTags.end()) { 344b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "tag<%{public}s> is invalid.", tagName.c_str()); 345b0e7dd80Sopenharmony_ci continue; 346b0e7dd80Sopenharmony_ci } 347b0e7dd80Sopenharmony_ci 348b0e7dd80Sopenharmony_ci if (iter->second.type == 0) { 349b0e7dd80Sopenharmony_ci enabledUserTags |= iter->second.tag; 350b0e7dd80Sopenharmony_ci } 351b0e7dd80Sopenharmony_ci 352b0e7dd80Sopenharmony_ci if (iter->second.type == 1) { 353b0e7dd80Sopenharmony_ci for (const auto& path : iter->second.sysFiles) { 354b0e7dd80Sopenharmony_ci SetTraceNodeStatus(path, true); 355b0e7dd80Sopenharmony_ci } 356b0e7dd80Sopenharmony_ci } 357b0e7dd80Sopenharmony_ci } 358b0e7dd80Sopenharmony_ci SetProperty("debug.hitrace.tags.enableflags", std::to_string(enabledUserTags)); 359b0e7dd80Sopenharmony_ci} 360b0e7dd80Sopenharmony_ci 361b0e7dd80Sopenharmony_cistd::string ReadFileInner(const std::string& filename) 362b0e7dd80Sopenharmony_ci{ 363b0e7dd80Sopenharmony_ci std::string resolvedPath = CanonicalizeSpecPath(filename.c_str()); 364b0e7dd80Sopenharmony_ci std::ifstream fileIn(resolvedPath.c_str()); 365b0e7dd80Sopenharmony_ci if (!fileIn.is_open()) { 366b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "ReadFile: %{public}s open failed.", filename.c_str()); 367b0e7dd80Sopenharmony_ci return ""; 368b0e7dd80Sopenharmony_ci } 369b0e7dd80Sopenharmony_ci 370b0e7dd80Sopenharmony_ci std::string str((std::istreambuf_iterator<char>(fileIn)), std::istreambuf_iterator<char>()); 371b0e7dd80Sopenharmony_ci fileIn.close(); 372b0e7dd80Sopenharmony_ci return str; 373b0e7dd80Sopenharmony_ci} 374b0e7dd80Sopenharmony_ci 375b0e7dd80Sopenharmony_cistd::string ReadFile(const std::string& filename) 376b0e7dd80Sopenharmony_ci{ 377b0e7dd80Sopenharmony_ci std::string filePath = GetFilePath(filename); 378b0e7dd80Sopenharmony_ci return ReadFileInner(filePath); 379b0e7dd80Sopenharmony_ci} 380b0e7dd80Sopenharmony_ci 381b0e7dd80Sopenharmony_civoid SetClock(const std::string& clockType) 382b0e7dd80Sopenharmony_ci{ 383b0e7dd80Sopenharmony_ci const std::string traceClockPath = "trace_clock"; 384b0e7dd80Sopenharmony_ci if (clockType.size() == 0) { 385b0e7dd80Sopenharmony_ci WriteStrToFile(traceClockPath, "boot"); //set default: boot 386b0e7dd80Sopenharmony_ci return; 387b0e7dd80Sopenharmony_ci } 388b0e7dd80Sopenharmony_ci std::string allClocks = ReadFile(traceClockPath); 389b0e7dd80Sopenharmony_ci if (allClocks.find(clockType) == std::string::npos) { 390b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "SetClock: %{public}s is non-existent, set to boot", clockType.c_str()); 391b0e7dd80Sopenharmony_ci WriteStrToFile(traceClockPath, "boot"); // set default: boot 392b0e7dd80Sopenharmony_ci return; 393b0e7dd80Sopenharmony_ci } 394b0e7dd80Sopenharmony_ci 395b0e7dd80Sopenharmony_ci allClocks.erase(allClocks.find_last_not_of(" \n") + 1); 396b0e7dd80Sopenharmony_ci allClocks.push_back(' '); 397b0e7dd80Sopenharmony_ci 398b0e7dd80Sopenharmony_ci std::set<std::string> allClockTypes; 399b0e7dd80Sopenharmony_ci size_t curPos = 0; 400b0e7dd80Sopenharmony_ci for (size_t i = 0; i < allClocks.size(); i++) { 401b0e7dd80Sopenharmony_ci if (allClocks[i] == ' ') { 402b0e7dd80Sopenharmony_ci allClockTypes.insert(allClocks.substr(curPos, i - curPos)); 403b0e7dd80Sopenharmony_ci curPos = i + 1; 404b0e7dd80Sopenharmony_ci } 405b0e7dd80Sopenharmony_ci } 406b0e7dd80Sopenharmony_ci 407b0e7dd80Sopenharmony_ci std::string currentClockType; 408b0e7dd80Sopenharmony_ci for (auto i : allClockTypes) { 409b0e7dd80Sopenharmony_ci if (clockType.compare(i) == 0) { 410b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "SetClock: set clock %{public}s success.", clockType.c_str()); 411b0e7dd80Sopenharmony_ci WriteStrToFile(traceClockPath, clockType); 412b0e7dd80Sopenharmony_ci return; 413b0e7dd80Sopenharmony_ci } 414b0e7dd80Sopenharmony_ci if (i[0] == '[') { 415b0e7dd80Sopenharmony_ci currentClockType = i; 416b0e7dd80Sopenharmony_ci } 417b0e7dd80Sopenharmony_ci } 418b0e7dd80Sopenharmony_ci 419b0e7dd80Sopenharmony_ci const int marks = 2; 420b0e7dd80Sopenharmony_ci if (clockType.compare(currentClockType.substr(1, currentClockType.size() - marks)) == 0) { 421b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "SetClock: set clock %{public}s success.", clockType.c_str()); 422b0e7dd80Sopenharmony_ci return; 423b0e7dd80Sopenharmony_ci } 424b0e7dd80Sopenharmony_ci 425b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "SetClock: unknown %{public}s, change to default clock_type: boot.", clockType.c_str()); 426b0e7dd80Sopenharmony_ci WriteStrToFile(traceClockPath, "boot"); // set default: boot 427b0e7dd80Sopenharmony_ci return; 428b0e7dd80Sopenharmony_ci} 429b0e7dd80Sopenharmony_ci 430b0e7dd80Sopenharmony_cibool SetTraceSetting(const TraceParams &traceParams, const std::map<std::string, TagCategory> &allTags, 431b0e7dd80Sopenharmony_ci const std::map<std::string, std::vector<std::string>> &tagGroupTable) 432b0e7dd80Sopenharmony_ci{ 433b0e7dd80Sopenharmony_ci TraceInit(allTags); 434b0e7dd80Sopenharmony_ci 435b0e7dd80Sopenharmony_ci TruncateFile(); 436b0e7dd80Sopenharmony_ci 437b0e7dd80Sopenharmony_ci SetAllTags(traceParams, allTags, tagGroupTable); 438b0e7dd80Sopenharmony_ci 439b0e7dd80Sopenharmony_ci WriteStrToFile("current_tracer", "nop"); 440b0e7dd80Sopenharmony_ci WriteStrToFile("buffer_size_kb", traceParams.bufferSize); 441b0e7dd80Sopenharmony_ci 442b0e7dd80Sopenharmony_ci SetClock(traceParams.clockType); 443b0e7dd80Sopenharmony_ci 444b0e7dd80Sopenharmony_ci if (traceParams.isOverWrite == "1") { 445b0e7dd80Sopenharmony_ci WriteStrToFile("options/overwrite", "1"); 446b0e7dd80Sopenharmony_ci } else { 447b0e7dd80Sopenharmony_ci WriteStrToFile("options/overwrite", "0"); 448b0e7dd80Sopenharmony_ci } 449b0e7dd80Sopenharmony_ci 450b0e7dd80Sopenharmony_ci WriteStrToFile("saved_cmdlines_size", std::to_string(SAVED_CMDLINES_SIZE)); 451b0e7dd80Sopenharmony_ci WriteStrToFile("options/record-tgid", "1"); 452b0e7dd80Sopenharmony_ci WriteStrToFile("options/record-cmd", "1"); 453b0e7dd80Sopenharmony_ci return true; 454b0e7dd80Sopenharmony_ci} 455b0e7dd80Sopenharmony_ci 456b0e7dd80Sopenharmony_cibool CheckPage(uint8_t contentType, uint8_t *page) 457b0e7dd80Sopenharmony_ci{ 458b0e7dd80Sopenharmony_ci const int pageThreshold = PAGE_SIZE / 2; 459b0e7dd80Sopenharmony_ci 460b0e7dd80Sopenharmony_ci // Check raw_trace page size. 461b0e7dd80Sopenharmony_ci if (contentType >= CONTENT_TYPE_CPU_RAW && !IsHmKernel()) { 462b0e7dd80Sopenharmony_ci PageHeader *pageHeader = reinterpret_cast<PageHeader*>(&page); 463b0e7dd80Sopenharmony_ci if (pageHeader->size < static_cast<uint64_t>(pageThreshold)) { 464b0e7dd80Sopenharmony_ci return false; 465b0e7dd80Sopenharmony_ci } 466b0e7dd80Sopenharmony_ci } 467b0e7dd80Sopenharmony_ci 468b0e7dd80Sopenharmony_ci return true; 469b0e7dd80Sopenharmony_ci} 470b0e7dd80Sopenharmony_ci 471b0e7dd80Sopenharmony_cibool CheckFileExist(const std::string &outputFile) 472b0e7dd80Sopenharmony_ci{ 473b0e7dd80Sopenharmony_ci g_writeFileLimit++; 474b0e7dd80Sopenharmony_ci if (g_writeFileLimit > JUDGE_FILE_EXIST) { 475b0e7dd80Sopenharmony_ci g_writeFileLimit = 0; 476b0e7dd80Sopenharmony_ci if (access(outputFile.c_str(), F_OK) != 0) { 477b0e7dd80Sopenharmony_ci g_needGenerateNewTraceFile = true; 478b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "CheckFileExist access file:%{public}s failed, errno: %{public}d.", 479b0e7dd80Sopenharmony_ci outputFile.c_str(), errno); 480b0e7dd80Sopenharmony_ci return false; 481b0e7dd80Sopenharmony_ci } 482b0e7dd80Sopenharmony_ci } 483b0e7dd80Sopenharmony_ci return true; 484b0e7dd80Sopenharmony_ci} 485b0e7dd80Sopenharmony_ci 486b0e7dd80Sopenharmony_civoid SetTimeIntervalBoundary() 487b0e7dd80Sopenharmony_ci{ 488b0e7dd80Sopenharmony_ci if (g_inputMaxDuration > 0) { 489b0e7dd80Sopenharmony_ci if (g_inputTraceEndTime) { 490b0e7dd80Sopenharmony_ci g_traceStartTime = g_inputTraceEndTime - static_cast<uint64_t>(g_inputMaxDuration) * S_TO_NS; 491b0e7dd80Sopenharmony_ci g_traceEndTime = g_inputTraceEndTime; 492b0e7dd80Sopenharmony_ci } else { 493b0e7dd80Sopenharmony_ci struct timespec bts = {0, 0}; 494b0e7dd80Sopenharmony_ci clock_gettime(CLOCK_BOOTTIME, &bts); 495b0e7dd80Sopenharmony_ci g_traceStartTime = static_cast<uint64_t>(bts.tv_sec * S_TO_NS + bts.tv_nsec) - 496b0e7dd80Sopenharmony_ci static_cast<uint64_t>(g_inputMaxDuration) * S_TO_NS; 497b0e7dd80Sopenharmony_ci g_traceEndTime = std::numeric_limits<uint64_t>::max(); 498b0e7dd80Sopenharmony_ci } 499b0e7dd80Sopenharmony_ci } else { 500b0e7dd80Sopenharmony_ci g_traceStartTime = 0; 501b0e7dd80Sopenharmony_ci g_traceEndTime = g_inputTraceEndTime > 0 ? g_inputTraceEndTime : std::numeric_limits<uint64_t>::max(); 502b0e7dd80Sopenharmony_ci } 503b0e7dd80Sopenharmony_ci return; 504b0e7dd80Sopenharmony_ci} 505b0e7dd80Sopenharmony_ci 506b0e7dd80Sopenharmony_civoid RestoreTimeIntervalBoundary() 507b0e7dd80Sopenharmony_ci{ 508b0e7dd80Sopenharmony_ci g_traceStartTime = 0; 509b0e7dd80Sopenharmony_ci g_traceEndTime = std::numeric_limits<uint64_t>::max(); 510b0e7dd80Sopenharmony_ci} 511b0e7dd80Sopenharmony_ci 512b0e7dd80Sopenharmony_civoid GetFileSizeThresholdAndTraceTime(bool &isCpuRaw, uint8_t contentType, uint64_t &traceStartTime, 513b0e7dd80Sopenharmony_ci uint64_t &traceEndTime, int &fileSizeThreshold) 514b0e7dd80Sopenharmony_ci{ 515b0e7dd80Sopenharmony_ci isCpuRaw = contentType >= CONTENT_TYPE_CPU_RAW && contentType < CONTENT_TYPE_HEADER_PAGE; 516b0e7dd80Sopenharmony_ci if (isCpuRaw) { 517b0e7dd80Sopenharmony_ci traceStartTime = g_traceStartTime; 518b0e7dd80Sopenharmony_ci traceEndTime = g_traceEndTime; 519b0e7dd80Sopenharmony_ci } 520b0e7dd80Sopenharmony_ci if (g_currentTraceParams.fileSize != 0) { 521b0e7dd80Sopenharmony_ci fileSizeThreshold = g_currentTraceParams.fileSize * KB_PER_MB; 522b0e7dd80Sopenharmony_ci } 523b0e7dd80Sopenharmony_ci} 524b0e7dd80Sopenharmony_ci 525b0e7dd80Sopenharmony_cibool IsWriteFileOverflow(const bool isCpuRaw, const int &outputFileSize, const ssize_t &writeLen, 526b0e7dd80Sopenharmony_ci const int &fileSizeThreshold) 527b0e7dd80Sopenharmony_ci{ 528b0e7dd80Sopenharmony_ci // attention: we only check file size threshold in CMD_MODE 529b0e7dd80Sopenharmony_ci if (!isCpuRaw || g_traceMode != TraceMode::CMD_MODE) { 530b0e7dd80Sopenharmony_ci return false; 531b0e7dd80Sopenharmony_ci } 532b0e7dd80Sopenharmony_ci if (outputFileSize + writeLen + static_cast<int>(sizeof(TraceFileContentHeader)) >= fileSizeThreshold) { 533b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "Failed to write, current round write file size exceeds the file size limit."); 534b0e7dd80Sopenharmony_ci return true; 535b0e7dd80Sopenharmony_ci } 536b0e7dd80Sopenharmony_ci if (writeLen > INT_MAX - BUFFER_SIZE) { 537b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "Failed to write, write file length is nearly overflow."); 538b0e7dd80Sopenharmony_ci return true; 539b0e7dd80Sopenharmony_ci } 540b0e7dd80Sopenharmony_ci return false; 541b0e7dd80Sopenharmony_ci} 542b0e7dd80Sopenharmony_ci 543b0e7dd80Sopenharmony_cibool WriteFile(uint8_t contentType, const std::string &src, int outFd, const std::string &outputFile) 544b0e7dd80Sopenharmony_ci{ 545b0e7dd80Sopenharmony_ci std::string srcPath = CanonicalizeSpecPath(src.c_str()); 546b0e7dd80Sopenharmony_ci int srcFd = open(srcPath.c_str(), O_RDONLY | O_NONBLOCK); 547b0e7dd80Sopenharmony_ci if (srcFd < 0) { 548b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "WriteFile: open %{public}s failed.", src.c_str()); 549b0e7dd80Sopenharmony_ci return false; 550b0e7dd80Sopenharmony_ci } 551b0e7dd80Sopenharmony_ci if (!CheckFileExist(outputFile)) { 552b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "need generate new trace file, old file:%{public}s.", outputFile.c_str()); 553b0e7dd80Sopenharmony_ci return false; 554b0e7dd80Sopenharmony_ci } 555b0e7dd80Sopenharmony_ci struct TraceFileContentHeader contentHeader; 556b0e7dd80Sopenharmony_ci contentHeader.type = contentType; 557b0e7dd80Sopenharmony_ci write(outFd, reinterpret_cast<char *>(&contentHeader), sizeof(contentHeader)); 558b0e7dd80Sopenharmony_ci ssize_t writeLen = 0; 559b0e7dd80Sopenharmony_ci int count = 0; 560b0e7dd80Sopenharmony_ci const int maxCount = 2; 561b0e7dd80Sopenharmony_ci 562b0e7dd80Sopenharmony_ci uint64_t traceStartTime = 0; 563b0e7dd80Sopenharmony_ci uint64_t traceEndTime = std::numeric_limits<uint64_t>::max(); 564b0e7dd80Sopenharmony_ci int fileSizeThreshold = DEFAULT_FILE_SIZE * KB_PER_MB; 565b0e7dd80Sopenharmony_ci bool isCpuRaw = false; 566b0e7dd80Sopenharmony_ci GetFileSizeThresholdAndTraceTime(isCpuRaw, contentType, traceStartTime, traceEndTime, fileSizeThreshold); 567b0e7dd80Sopenharmony_ci while (true) { 568b0e7dd80Sopenharmony_ci int bytes = 0; 569b0e7dd80Sopenharmony_ci bool endFlag = false; 570b0e7dd80Sopenharmony_ci /* Write 1M at a time */ 571b0e7dd80Sopenharmony_ci while (bytes < BUFFER_SIZE) { 572b0e7dd80Sopenharmony_ci ssize_t readBytes = TEMP_FAILURE_RETRY(read(srcFd, g_buffer + bytes, PAGE_SIZE)); 573b0e7dd80Sopenharmony_ci if (readBytes == 0) { 574b0e7dd80Sopenharmony_ci endFlag = true; 575b0e7dd80Sopenharmony_ci HILOG_DEBUG(LOG_CORE, "WriteFile: read %{public}s end.", src.c_str()); 576b0e7dd80Sopenharmony_ci break; 577b0e7dd80Sopenharmony_ci } else if (readBytes < 0) { 578b0e7dd80Sopenharmony_ci endFlag = true; 579b0e7dd80Sopenharmony_ci HILOG_DEBUG(LOG_CORE, "WriteFile: read %{public}s, data size: %{public}zd failed, errno: %{public}d.", 580b0e7dd80Sopenharmony_ci src.c_str(), readBytes, errno); 581b0e7dd80Sopenharmony_ci break; 582b0e7dd80Sopenharmony_ci } 583b0e7dd80Sopenharmony_ci 584b0e7dd80Sopenharmony_ci uint64_t pageTraceTime = 0; 585b0e7dd80Sopenharmony_ci if (memcpy_s(&pageTraceTime, sizeof(uint64_t), g_buffer + bytes, sizeof(uint64_t)) != EOK) { 586b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "Failed to memcpy g_buffer to pageTraceTime."); 587b0e7dd80Sopenharmony_ci break; 588b0e7dd80Sopenharmony_ci } 589b0e7dd80Sopenharmony_ci if (traceEndTime < pageTraceTime) { 590b0e7dd80Sopenharmony_ci endFlag = true; 591b0e7dd80Sopenharmony_ci readBytes = 0; 592b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, 593b0e7dd80Sopenharmony_ci "Current pageTraceTime:(%{public}" PRId64 ") is larger than traceEndTime:(%{public}" PRId64 ")", 594b0e7dd80Sopenharmony_ci pageTraceTime, traceEndTime); 595b0e7dd80Sopenharmony_ci break; 596b0e7dd80Sopenharmony_ci } 597b0e7dd80Sopenharmony_ci 598b0e7dd80Sopenharmony_ci if (pageTraceTime < traceStartTime) { 599b0e7dd80Sopenharmony_ci continue; 600b0e7dd80Sopenharmony_ci } 601b0e7dd80Sopenharmony_ci 602b0e7dd80Sopenharmony_ci if (CheckPage(contentType, g_buffer + bytes) == false) { 603b0e7dd80Sopenharmony_ci count++; 604b0e7dd80Sopenharmony_ci } 605b0e7dd80Sopenharmony_ci bytes += readBytes; 606b0e7dd80Sopenharmony_ci if (count >= maxCount) { 607b0e7dd80Sopenharmony_ci endFlag = true; 608b0e7dd80Sopenharmony_ci break; 609b0e7dd80Sopenharmony_ci } 610b0e7dd80Sopenharmony_ci } 611b0e7dd80Sopenharmony_ci 612b0e7dd80Sopenharmony_ci ssize_t writeRet = TEMP_FAILURE_RETRY(write(outFd, g_buffer, bytes)); 613b0e7dd80Sopenharmony_ci if (writeRet < 0) { 614b0e7dd80Sopenharmony_ci HILOG_WARN(LOG_CORE, "WriteFile Fail, errno: %{public}d.", errno); 615b0e7dd80Sopenharmony_ci } else { 616b0e7dd80Sopenharmony_ci if (writeRet != static_cast<ssize_t>(bytes)) { 617b0e7dd80Sopenharmony_ci HILOG_WARN(LOG_CORE, "Failed to write full info, writeLen: %{public}zd, FullLen: %{public}d.", 618b0e7dd80Sopenharmony_ci writeRet, bytes); 619b0e7dd80Sopenharmony_ci } 620b0e7dd80Sopenharmony_ci writeLen += writeRet; 621b0e7dd80Sopenharmony_ci } 622b0e7dd80Sopenharmony_ci 623b0e7dd80Sopenharmony_ci if (IsWriteFileOverflow(isCpuRaw, g_outputFileSize, writeLen, fileSizeThreshold)) { 624b0e7dd80Sopenharmony_ci break; 625b0e7dd80Sopenharmony_ci } 626b0e7dd80Sopenharmony_ci 627b0e7dd80Sopenharmony_ci if (endFlag == true) { 628b0e7dd80Sopenharmony_ci break; 629b0e7dd80Sopenharmony_ci } 630b0e7dd80Sopenharmony_ci } 631b0e7dd80Sopenharmony_ci contentHeader.length = static_cast<uint32_t>(writeLen); 632b0e7dd80Sopenharmony_ci uint32_t offset = contentHeader.length + sizeof(contentHeader); 633b0e7dd80Sopenharmony_ci off_t pos = lseek(outFd, 0, SEEK_CUR); 634b0e7dd80Sopenharmony_ci lseek(outFd, pos - offset, SEEK_SET); 635b0e7dd80Sopenharmony_ci write(outFd, reinterpret_cast<char *>(&contentHeader), sizeof(contentHeader)); 636b0e7dd80Sopenharmony_ci lseek(outFd, pos, SEEK_SET); 637b0e7dd80Sopenharmony_ci close(srcFd); 638b0e7dd80Sopenharmony_ci if (isCpuRaw) { 639b0e7dd80Sopenharmony_ci if (writeLen > 0) { 640b0e7dd80Sopenharmony_ci g_dumpStatus = TraceErrorCode::SUCCESS; 641b0e7dd80Sopenharmony_ci } else if (g_dumpStatus == TraceErrorCode::UNSET) { 642b0e7dd80Sopenharmony_ci g_dumpStatus = TraceErrorCode::OUT_OF_TIME; 643b0e7dd80Sopenharmony_ci } 644b0e7dd80Sopenharmony_ci } 645b0e7dd80Sopenharmony_ci g_outputFileSize += static_cast<int>(offset); 646b0e7dd80Sopenharmony_ci g_needGenerateNewTraceFile = false; 647b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "WriteFile end, path: %{public}s, byte: %{public}zd. g_writeFileLimit: %{public}d", 648b0e7dd80Sopenharmony_ci src.c_str(), writeLen, g_writeFileLimit); 649b0e7dd80Sopenharmony_ci return true; 650b0e7dd80Sopenharmony_ci} 651b0e7dd80Sopenharmony_ci 652b0e7dd80Sopenharmony_civoid WriteEventFile(std::string &srcPath, int outFd) 653b0e7dd80Sopenharmony_ci{ 654b0e7dd80Sopenharmony_ci uint8_t buffer[PAGE_SIZE] = {0}; 655b0e7dd80Sopenharmony_ci std::string srcSpecPath = CanonicalizeSpecPath(srcPath.c_str()); 656b0e7dd80Sopenharmony_ci int srcFd = open(srcSpecPath.c_str(), O_RDONLY); 657b0e7dd80Sopenharmony_ci if (srcFd < 0) { 658b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "WriteEventFile: open %{public}s failed.", srcPath.c_str()); 659b0e7dd80Sopenharmony_ci return; 660b0e7dd80Sopenharmony_ci } 661b0e7dd80Sopenharmony_ci int64_t readLen = 0; 662b0e7dd80Sopenharmony_ci do { 663b0e7dd80Sopenharmony_ci int64_t len = read(srcFd, buffer, PAGE_SIZE); 664b0e7dd80Sopenharmony_ci if (len <= 0) { 665b0e7dd80Sopenharmony_ci break; 666b0e7dd80Sopenharmony_ci } 667b0e7dd80Sopenharmony_ci write(outFd, buffer, len); 668b0e7dd80Sopenharmony_ci readLen += len; 669b0e7dd80Sopenharmony_ci } while (true); 670b0e7dd80Sopenharmony_ci close(srcFd); 671b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "WriteEventFile end, path: %{public}s, data size: (%{public}" PRId64 ").", 672b0e7dd80Sopenharmony_ci srcPath.c_str(), static_cast<uint64_t>(readLen)); 673b0e7dd80Sopenharmony_ci} 674b0e7dd80Sopenharmony_ci 675b0e7dd80Sopenharmony_cibool WriteEventsFormat(int outFd, const std::string &outputFile) 676b0e7dd80Sopenharmony_ci{ 677b0e7dd80Sopenharmony_ci const std::string savedEventsFormatPath = DEFAULT_OUTPUT_DIR + SAVED_EVENTS_FORMAT; 678b0e7dd80Sopenharmony_ci if (access(savedEventsFormatPath.c_str(), F_OK) != -1) { 679b0e7dd80Sopenharmony_ci return WriteFile(CONTENT_TYPE_EVENTS_FORMAT, savedEventsFormatPath, outFd, outputFile); 680b0e7dd80Sopenharmony_ci } 681b0e7dd80Sopenharmony_ci std::string filePath = CanonicalizeSpecPath(savedEventsFormatPath.c_str()); 682b0e7dd80Sopenharmony_ci int fd = open(filePath.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644); // 0644:-rw-r--r-- 683b0e7dd80Sopenharmony_ci if (fd < 0) { 684b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "WriteEventsFormat: open %{public}s failed.", savedEventsFormatPath.c_str()); 685b0e7dd80Sopenharmony_ci return false; 686b0e7dd80Sopenharmony_ci } 687b0e7dd80Sopenharmony_ci const std::vector<std::string> priorityTracingCategory = { 688b0e7dd80Sopenharmony_ci "events/sched/sched_wakeup/format", 689b0e7dd80Sopenharmony_ci "events/sched/sched_switch/format", 690b0e7dd80Sopenharmony_ci "events/sched/sched_blocked_reason/format", 691b0e7dd80Sopenharmony_ci "events/power/cpu_frequency/format", 692b0e7dd80Sopenharmony_ci "events/power/clock_set_rate/format", 693b0e7dd80Sopenharmony_ci "events/power/cpu_frequency_limits/format", 694b0e7dd80Sopenharmony_ci "events/f2fs/f2fs_sync_file_enter/format", 695b0e7dd80Sopenharmony_ci "events/f2fs/f2fs_sync_file_exit/format", 696b0e7dd80Sopenharmony_ci "events/f2fs/f2fs_readpage/format", 697b0e7dd80Sopenharmony_ci "events/f2fs/f2fs_readpages/format", 698b0e7dd80Sopenharmony_ci "events/f2fs/f2fs_sync_fs/format", 699b0e7dd80Sopenharmony_ci "events/hmdfs/hmdfs_syncfs_enter/format", 700b0e7dd80Sopenharmony_ci "events/hmdfs/hmdfs_syncfs_exit/format", 701b0e7dd80Sopenharmony_ci "events/erofs/erofs_readpage/format", 702b0e7dd80Sopenharmony_ci "events/erofs/erofs_readpages/format", 703b0e7dd80Sopenharmony_ci "events/ext4/ext4_da_write_begin/format", 704b0e7dd80Sopenharmony_ci "events/ext4/ext4_da_write_end/format", 705b0e7dd80Sopenharmony_ci "events/ext4/ext4_sync_file_enter/format", 706b0e7dd80Sopenharmony_ci "events/ext4/ext4_sync_file_exit/format", 707b0e7dd80Sopenharmony_ci "events/block/block_bio_remap/format", 708b0e7dd80Sopenharmony_ci "events/block/block_rq_issue/format", 709b0e7dd80Sopenharmony_ci "events/block/block_rq_complete/format", 710b0e7dd80Sopenharmony_ci "events/block/block_rq_insert/format", 711b0e7dd80Sopenharmony_ci "events/dma_fence/dma_fence_emit/format", 712b0e7dd80Sopenharmony_ci "events/dma_fence/dma_fence_destroy/format", 713b0e7dd80Sopenharmony_ci "events/dma_fence/dma_fence_enable_signal/format", 714b0e7dd80Sopenharmony_ci "events/dma_fence/dma_fence_signaled/format", 715b0e7dd80Sopenharmony_ci "events/dma_fence/dma_fence_wait_end/format", 716b0e7dd80Sopenharmony_ci "events/dma_fence/dma_fence_wait_start/format", 717b0e7dd80Sopenharmony_ci "events/dma_fence/dma_fence_init/format", 718b0e7dd80Sopenharmony_ci "events/binder/binder_transaction/format", 719b0e7dd80Sopenharmony_ci "events/binder/binder_transaction_received/format", 720b0e7dd80Sopenharmony_ci "events/mmc/mmc_request_start/format", 721b0e7dd80Sopenharmony_ci "events/mmc/mmc_request_done/format", 722b0e7dd80Sopenharmony_ci "events/memory_bus/format", 723b0e7dd80Sopenharmony_ci "events/cpufreq_interactive/format", 724b0e7dd80Sopenharmony_ci "events/filemap/file_check_and_advance_wb_err/format", 725b0e7dd80Sopenharmony_ci "events/filemap/filemap_set_wb_err/format", 726b0e7dd80Sopenharmony_ci "events/filemap/mm_filemap_add_to_page_cache/format", 727b0e7dd80Sopenharmony_ci "events/filemap/mm_filemap_delete_from_page_cache/format", 728b0e7dd80Sopenharmony_ci "events/workqueue/workqueue_execute_end/format", 729b0e7dd80Sopenharmony_ci "events/workqueue/workqueue_execute_start/format", 730b0e7dd80Sopenharmony_ci "events/thermal_power_allocator/thermal_power_allocator/format", 731b0e7dd80Sopenharmony_ci "events/thermal_power_allocator/thermal_power_allocator_pid/format", 732b0e7dd80Sopenharmony_ci "events/ftrace/print/format", 733b0e7dd80Sopenharmony_ci "events/tracing_mark_write/tracing_mark_write/format", 734b0e7dd80Sopenharmony_ci "events/power/cpu_idle/format", 735b0e7dd80Sopenharmony_ci "events/power_kernel/cpu_idle/format", 736b0e7dd80Sopenharmony_ci "events/xacct/tracing_mark_write/format", 737b0e7dd80Sopenharmony_ci "events/ufs/ufshcd_command/format", 738b0e7dd80Sopenharmony_ci "events/irq/irq_handler_entry/format" 739b0e7dd80Sopenharmony_ci }; 740b0e7dd80Sopenharmony_ci for (size_t i = 0; i < priorityTracingCategory.size(); i++) { 741b0e7dd80Sopenharmony_ci std::string srcPath = g_traceRootPath + priorityTracingCategory[i]; 742b0e7dd80Sopenharmony_ci if (access(srcPath.c_str(), R_OK) != -1) { 743b0e7dd80Sopenharmony_ci WriteEventFile(srcPath, fd); 744b0e7dd80Sopenharmony_ci } 745b0e7dd80Sopenharmony_ci } 746b0e7dd80Sopenharmony_ci close(fd); 747b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "WriteEventsFormat end. path: %{public}s.", filePath.c_str()); 748b0e7dd80Sopenharmony_ci return WriteFile(CONTENT_TYPE_EVENTS_FORMAT, filePath, outFd, outputFile); 749b0e7dd80Sopenharmony_ci} 750b0e7dd80Sopenharmony_ci 751b0e7dd80Sopenharmony_cibool WriteHeaderPage(int outFd, const std::string &outputFile) 752b0e7dd80Sopenharmony_ci{ 753b0e7dd80Sopenharmony_ci if (IsHmKernel()) { 754b0e7dd80Sopenharmony_ci return true; 755b0e7dd80Sopenharmony_ci } 756b0e7dd80Sopenharmony_ci std::string headerPagePath = GetFilePath("events/header_page"); 757b0e7dd80Sopenharmony_ci return WriteFile(CONTENT_TYPE_HEADER_PAGE, headerPagePath, outFd, outputFile); 758b0e7dd80Sopenharmony_ci} 759b0e7dd80Sopenharmony_ci 760b0e7dd80Sopenharmony_cibool WritePrintkFormats(int outFd, const std::string &outputFile) 761b0e7dd80Sopenharmony_ci{ 762b0e7dd80Sopenharmony_ci if (IsHmKernel()) { 763b0e7dd80Sopenharmony_ci return true; 764b0e7dd80Sopenharmony_ci } 765b0e7dd80Sopenharmony_ci std::string printkFormatPath = GetFilePath("printk_formats"); 766b0e7dd80Sopenharmony_ci return WriteFile(CONTENT_TYPE_PRINTK_FORMATS, printkFormatPath, outFd, outputFile); 767b0e7dd80Sopenharmony_ci} 768b0e7dd80Sopenharmony_ci 769b0e7dd80Sopenharmony_cibool WriteKallsyms(int outFd) 770b0e7dd80Sopenharmony_ci{ 771b0e7dd80Sopenharmony_ci /* not implement in hmkernel */ 772b0e7dd80Sopenharmony_ci if (IsHmKernel()) { 773b0e7dd80Sopenharmony_ci return true; 774b0e7dd80Sopenharmony_ci } 775b0e7dd80Sopenharmony_ci /* not implement in linux */ 776b0e7dd80Sopenharmony_ci return true; 777b0e7dd80Sopenharmony_ci} 778b0e7dd80Sopenharmony_ci 779b0e7dd80Sopenharmony_cibool HmWriteCpuRawInner(int outFd, const std::string &outputFile) 780b0e7dd80Sopenharmony_ci{ 781b0e7dd80Sopenharmony_ci uint8_t type = CONTENT_TYPE_CPU_RAW; 782b0e7dd80Sopenharmony_ci std::string src = g_traceRootPath + "/trace_pipe_raw"; 783b0e7dd80Sopenharmony_ci 784b0e7dd80Sopenharmony_ci if (!WriteFile(type, src, outFd, outputFile)) { 785b0e7dd80Sopenharmony_ci return false; 786b0e7dd80Sopenharmony_ci } 787b0e7dd80Sopenharmony_ci 788b0e7dd80Sopenharmony_ci if (g_dumpStatus) { 789b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "HmWriteCpuRawInner failed, errno: %{public}d.", static_cast<int>(g_dumpStatus.load())); 790b0e7dd80Sopenharmony_ci return false; 791b0e7dd80Sopenharmony_ci } 792b0e7dd80Sopenharmony_ci 793b0e7dd80Sopenharmony_ci return true; 794b0e7dd80Sopenharmony_ci} 795b0e7dd80Sopenharmony_ci 796b0e7dd80Sopenharmony_cibool WriteCpuRawInner(int outFd, const std::string &outputFile) 797b0e7dd80Sopenharmony_ci{ 798b0e7dd80Sopenharmony_ci int cpuNums = GetCpuProcessors(); 799b0e7dd80Sopenharmony_ci uint8_t type = CONTENT_TYPE_CPU_RAW; 800b0e7dd80Sopenharmony_ci for (int i = 0; i < cpuNums; i++) { 801b0e7dd80Sopenharmony_ci std::string src = g_traceRootPath + "per_cpu/cpu" + std::to_string(i) + "/trace_pipe_raw"; 802b0e7dd80Sopenharmony_ci if (!WriteFile(static_cast<uint8_t>(type + i), src, outFd, outputFile)) { 803b0e7dd80Sopenharmony_ci return false; 804b0e7dd80Sopenharmony_ci } 805b0e7dd80Sopenharmony_ci } 806b0e7dd80Sopenharmony_ci if (g_dumpStatus) { 807b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "WriteCpuRawInner failed, errno: %{public}d.", static_cast<int>(g_dumpStatus.load())); 808b0e7dd80Sopenharmony_ci return false; 809b0e7dd80Sopenharmony_ci } 810b0e7dd80Sopenharmony_ci return true; 811b0e7dd80Sopenharmony_ci} 812b0e7dd80Sopenharmony_ci 813b0e7dd80Sopenharmony_cibool WriteCpuRaw(int outFd, const std::string &outputFile) 814b0e7dd80Sopenharmony_ci{ 815b0e7dd80Sopenharmony_ci if (!IsHmKernel()) { 816b0e7dd80Sopenharmony_ci return WriteCpuRawInner(outFd, outputFile); 817b0e7dd80Sopenharmony_ci } else { 818b0e7dd80Sopenharmony_ci return HmWriteCpuRawInner(outFd, outputFile); 819b0e7dd80Sopenharmony_ci } 820b0e7dd80Sopenharmony_ci} 821b0e7dd80Sopenharmony_ci 822b0e7dd80Sopenharmony_cibool WriteCmdlines(int outFd, const std::string &outputFile) 823b0e7dd80Sopenharmony_ci{ 824b0e7dd80Sopenharmony_ci std::string cmdlinesPath = GetFilePath("saved_cmdlines"); 825b0e7dd80Sopenharmony_ci return WriteFile(CONTENT_TYPE_CMDLINES, cmdlinesPath, outFd, outputFile); 826b0e7dd80Sopenharmony_ci} 827b0e7dd80Sopenharmony_ci 828b0e7dd80Sopenharmony_cibool WriteTgids(int outFd, const std::string &outputFile) 829b0e7dd80Sopenharmony_ci{ 830b0e7dd80Sopenharmony_ci std::string tgidsPath = GetFilePath("saved_tgids"); 831b0e7dd80Sopenharmony_ci return WriteFile(CONTENT_TYPE_TGIDS, tgidsPath, outFd, outputFile); 832b0e7dd80Sopenharmony_ci} 833b0e7dd80Sopenharmony_ci 834b0e7dd80Sopenharmony_cibool GenerateNewFile(int &outFd, std::string &outPath) 835b0e7dd80Sopenharmony_ci{ 836b0e7dd80Sopenharmony_ci if (access(outPath.c_str(), F_OK) == 0) { 837b0e7dd80Sopenharmony_ci return true; 838b0e7dd80Sopenharmony_ci } 839b0e7dd80Sopenharmony_ci std::string outputFileName = GenerateTraceFileName(false); 840b0e7dd80Sopenharmony_ci outPath = CanonicalizeSpecPath(outputFileName.c_str()); 841b0e7dd80Sopenharmony_ci outFd = open(outPath.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644); // 0644:-rw-r--r-- 842b0e7dd80Sopenharmony_ci if (outFd < 0) { 843b0e7dd80Sopenharmony_ci g_newTraceFileLimit++; 844b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "open %{public}s failed, errno: %{public}d.", outPath.c_str(), errno); 845b0e7dd80Sopenharmony_ci } 846b0e7dd80Sopenharmony_ci if (g_newTraceFileLimit > MAX_NEW_TRACE_FILE_LIMIT) { 847b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "create new trace file %{public}s limited.", outPath.c_str()); 848b0e7dd80Sopenharmony_ci return false; 849b0e7dd80Sopenharmony_ci } 850b0e7dd80Sopenharmony_ci g_needGenerateNewTraceFile = true; 851b0e7dd80Sopenharmony_ci return true; 852b0e7dd80Sopenharmony_ci} 853b0e7dd80Sopenharmony_ci 854b0e7dd80Sopenharmony_cibool DumpTraceLoop(const std::string &outputFileName, bool isLimited) 855b0e7dd80Sopenharmony_ci{ 856b0e7dd80Sopenharmony_ci const int sleepTime = 1; 857b0e7dd80Sopenharmony_ci int fileSizeThreshold = DEFAULT_FILE_SIZE * KB_PER_MB; 858b0e7dd80Sopenharmony_ci if (g_currentTraceParams.fileSize != 0) { 859b0e7dd80Sopenharmony_ci fileSizeThreshold = g_currentTraceParams.fileSize * KB_PER_MB; 860b0e7dd80Sopenharmony_ci } 861b0e7dd80Sopenharmony_ci g_outputFileSize = 0; 862b0e7dd80Sopenharmony_ci std::string outPath = CanonicalizeSpecPath(outputFileName.c_str()); 863b0e7dd80Sopenharmony_ci int outFd = open(outPath.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644); // 0644:-rw-r--r-- 864b0e7dd80Sopenharmony_ci if (outFd < 0) { 865b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "open %{public}s failed, errno: %{public}d.", outPath.c_str(), errno); 866b0e7dd80Sopenharmony_ci return false; 867b0e7dd80Sopenharmony_ci } 868b0e7dd80Sopenharmony_ci MarkClockSync(g_traceRootPath); 869b0e7dd80Sopenharmony_ci struct TraceFileHeader header; 870b0e7dd80Sopenharmony_ci GetArchWordSize(header); 871b0e7dd80Sopenharmony_ci GetCpuNums(header); 872b0e7dd80Sopenharmony_ci if (IsHmKernel()) { 873b0e7dd80Sopenharmony_ci header.fileType = HM_FILE_RAW_TRACE; 874b0e7dd80Sopenharmony_ci } 875b0e7dd80Sopenharmony_ci do { 876b0e7dd80Sopenharmony_ci g_needGenerateNewTraceFile = false; 877b0e7dd80Sopenharmony_ci write(outFd, reinterpret_cast<char *>(&header), sizeof(header)); 878b0e7dd80Sopenharmony_ci WriteEventsFormat(outFd, outPath); 879b0e7dd80Sopenharmony_ci while (g_dumpFlag) { 880b0e7dd80Sopenharmony_ci if (isLimited && g_outputFileSize > fileSizeThreshold) { 881b0e7dd80Sopenharmony_ci break; 882b0e7dd80Sopenharmony_ci } 883b0e7dd80Sopenharmony_ci sleep(sleepTime); 884b0e7dd80Sopenharmony_ci if (!WriteCpuRaw(outFd, outPath)) { 885b0e7dd80Sopenharmony_ci break; 886b0e7dd80Sopenharmony_ci } 887b0e7dd80Sopenharmony_ci } 888b0e7dd80Sopenharmony_ci WriteCmdlines(outFd, outPath); 889b0e7dd80Sopenharmony_ci WriteTgids(outFd, outPath); 890b0e7dd80Sopenharmony_ci WriteHeaderPage(outFd, outPath); 891b0e7dd80Sopenharmony_ci WritePrintkFormats(outFd, outPath); 892b0e7dd80Sopenharmony_ci WriteKallsyms(outFd); 893b0e7dd80Sopenharmony_ci if (!GenerateNewFile(outFd, outPath)) { 894b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "DumpTraceLoop access file:%{public}s failed, errno: %{public}d.", 895b0e7dd80Sopenharmony_ci outPath.c_str(), errno); 896b0e7dd80Sopenharmony_ci return false; 897b0e7dd80Sopenharmony_ci } 898b0e7dd80Sopenharmony_ci } while (g_needGenerateNewTraceFile); 899b0e7dd80Sopenharmony_ci close(outFd); 900b0e7dd80Sopenharmony_ci return true; 901b0e7dd80Sopenharmony_ci} 902b0e7dd80Sopenharmony_ci 903b0e7dd80Sopenharmony_ci/** 904b0e7dd80Sopenharmony_ci * read trace data loop 905b0e7dd80Sopenharmony_ci * g_dumpFlag: true = open,false = close 906b0e7dd80Sopenharmony_ci * g_dumpEnd: true = end,false = not end 907b0e7dd80Sopenharmony_ci * if user has own output file, Output all data to the file specified by the user; 908b0e7dd80Sopenharmony_ci * if not, Then place all the result files in /data/log/hitrace/ and package them once in 96M. 909b0e7dd80Sopenharmony_ci*/ 910b0e7dd80Sopenharmony_civoid ProcessDumpTask() 911b0e7dd80Sopenharmony_ci{ 912b0e7dd80Sopenharmony_ci g_dumpFlag = true; 913b0e7dd80Sopenharmony_ci g_dumpEnd = false; 914b0e7dd80Sopenharmony_ci g_outputFilesForCmd = {}; 915b0e7dd80Sopenharmony_ci const std::string threadName = "TraceDumpTask"; 916b0e7dd80Sopenharmony_ci prctl(PR_SET_NAME, threadName.c_str()); 917b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "ProcessDumpTask: trace dump thread start."); 918b0e7dd80Sopenharmony_ci 919b0e7dd80Sopenharmony_ci // clear old record file before record tracing start. 920b0e7dd80Sopenharmony_ci DelSavedEventsFormat(); 921b0e7dd80Sopenharmony_ci DelOldRecordTraceFile(g_currentTraceParams.fileLimit); 922b0e7dd80Sopenharmony_ci 923b0e7dd80Sopenharmony_ci if (g_currentTraceParams.fileSize == 0) { 924b0e7dd80Sopenharmony_ci std::string outputFileName = g_currentTraceParams.outputFile.empty() ? 925b0e7dd80Sopenharmony_ci GenerateTraceFileName(false) : g_currentTraceParams.outputFile; 926b0e7dd80Sopenharmony_ci if (DumpTraceLoop(outputFileName, false)) { 927b0e7dd80Sopenharmony_ci g_outputFilesForCmd.push_back(outputFileName); 928b0e7dd80Sopenharmony_ci } 929b0e7dd80Sopenharmony_ci g_dumpEnd = true; 930b0e7dd80Sopenharmony_ci return; 931b0e7dd80Sopenharmony_ci } 932b0e7dd80Sopenharmony_ci 933b0e7dd80Sopenharmony_ci while (g_dumpFlag) { 934b0e7dd80Sopenharmony_ci if (!IsRootVersion()) { 935b0e7dd80Sopenharmony_ci ClearOldTraceFile(g_outputFilesForCmd, g_currentTraceParams.fileLimit); 936b0e7dd80Sopenharmony_ci } 937b0e7dd80Sopenharmony_ci // Generate file name 938b0e7dd80Sopenharmony_ci std::string outputFileName = GenerateTraceFileName(false); 939b0e7dd80Sopenharmony_ci if (DumpTraceLoop(outputFileName, true)) { 940b0e7dd80Sopenharmony_ci g_outputFilesForCmd.push_back(outputFileName); 941b0e7dd80Sopenharmony_ci } else { 942b0e7dd80Sopenharmony_ci break; 943b0e7dd80Sopenharmony_ci } 944b0e7dd80Sopenharmony_ci } 945b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "ProcessDumpTask: trace dump thread exit."); 946b0e7dd80Sopenharmony_ci g_dumpEnd = true; 947b0e7dd80Sopenharmony_ci} 948b0e7dd80Sopenharmony_ci 949b0e7dd80Sopenharmony_civoid SearchFromTable(std::vector<std::string> &outputFiles, int nowSec) 950b0e7dd80Sopenharmony_ci{ 951b0e7dd80Sopenharmony_ci const int maxInterval = 30; 952b0e7dd80Sopenharmony_ci const int agingTime = 30 * 60; 953b0e7dd80Sopenharmony_ci 954b0e7dd80Sopenharmony_ci for (auto iter = g_traceFilesTable.begin(); iter != g_traceFilesTable.end();) { 955b0e7dd80Sopenharmony_ci if (nowSec - iter->second >= agingTime) { 956b0e7dd80Sopenharmony_ci // delete outdated trace file 957b0e7dd80Sopenharmony_ci if (access(iter->first.c_str(), F_OK) == 0) { 958b0e7dd80Sopenharmony_ci remove(iter->first.c_str()); 959b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "delete old %{public}s file success.", iter->first.c_str()); 960b0e7dd80Sopenharmony_ci } 961b0e7dd80Sopenharmony_ci iter = g_traceFilesTable.erase(iter); 962b0e7dd80Sopenharmony_ci continue; 963b0e7dd80Sopenharmony_ci } 964b0e7dd80Sopenharmony_ci 965b0e7dd80Sopenharmony_ci if (nowSec - iter->second <= maxInterval) { 966b0e7dd80Sopenharmony_ci outputFiles.push_back(iter->first); 967b0e7dd80Sopenharmony_ci } 968b0e7dd80Sopenharmony_ci iter++; 969b0e7dd80Sopenharmony_ci } 970b0e7dd80Sopenharmony_ci} 971b0e7dd80Sopenharmony_ci 972b0e7dd80Sopenharmony_cibool ReadRawTrace(std::string &outputFileName) 973b0e7dd80Sopenharmony_ci{ 974b0e7dd80Sopenharmony_ci // read trace data from /per_cpu/cpux/trace_pipe_raw 975b0e7dd80Sopenharmony_ci std::string outPath = CanonicalizeSpecPath(outputFileName.c_str()); 976b0e7dd80Sopenharmony_ci int outFd = open(outPath.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 0644); // 0644:-rw-r--r-- 977b0e7dd80Sopenharmony_ci if (outFd < 0) { 978b0e7dd80Sopenharmony_ci return false; 979b0e7dd80Sopenharmony_ci } 980b0e7dd80Sopenharmony_ci struct TraceFileHeader header; 981b0e7dd80Sopenharmony_ci GetArchWordSize(header); 982b0e7dd80Sopenharmony_ci GetCpuNums(header); 983b0e7dd80Sopenharmony_ci if (IsHmKernel()) { 984b0e7dd80Sopenharmony_ci header.fileType = HM_FILE_RAW_TRACE; 985b0e7dd80Sopenharmony_ci } 986b0e7dd80Sopenharmony_ci write(outFd, reinterpret_cast<char*>(&header), sizeof(header)); 987b0e7dd80Sopenharmony_ci 988b0e7dd80Sopenharmony_ci if (WriteEventsFormat(outFd, outPath) && WriteCpuRaw(outFd, outPath) && 989b0e7dd80Sopenharmony_ci WriteCmdlines(outFd, outPath) && WriteTgids(outFd, outPath) && 990b0e7dd80Sopenharmony_ci WriteHeaderPage(outFd, outPath) && WritePrintkFormats(outFd, outPath) && 991b0e7dd80Sopenharmony_ci WriteKallsyms(outFd)) { 992b0e7dd80Sopenharmony_ci fsync(outFd); 993b0e7dd80Sopenharmony_ci close(outFd); 994b0e7dd80Sopenharmony_ci return true; 995b0e7dd80Sopenharmony_ci } 996b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "ReadRawTrace failed."); 997b0e7dd80Sopenharmony_ci fsync(outFd); 998b0e7dd80Sopenharmony_ci close(outFd); 999b0e7dd80Sopenharmony_ci return false; 1000b0e7dd80Sopenharmony_ci} 1001b0e7dd80Sopenharmony_ci 1002b0e7dd80Sopenharmony_civoid SetProcessName(std::string& processName) 1003b0e7dd80Sopenharmony_ci{ 1004b0e7dd80Sopenharmony_ci if (processName.size() <= 0) { 1005b0e7dd80Sopenharmony_ci return; 1006b0e7dd80Sopenharmony_ci } 1007b0e7dd80Sopenharmony_ci 1008b0e7dd80Sopenharmony_ci const int maxNameLen = 16; 1009b0e7dd80Sopenharmony_ci std::string setName; 1010b0e7dd80Sopenharmony_ci if (processName.size() > maxNameLen) { 1011b0e7dd80Sopenharmony_ci setName = processName.substr(0, maxNameLen); 1012b0e7dd80Sopenharmony_ci } else { 1013b0e7dd80Sopenharmony_ci setName = processName; 1014b0e7dd80Sopenharmony_ci } 1015b0e7dd80Sopenharmony_ci 1016b0e7dd80Sopenharmony_ci prctl(PR_SET_NAME, setName.c_str(), nullptr, nullptr, nullptr); 1017b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "New process: %{public}s.", setName.c_str()); 1018b0e7dd80Sopenharmony_ci} 1019b0e7dd80Sopenharmony_ci 1020b0e7dd80Sopenharmony_civoid TimeoutSignalHandler(int signum) 1021b0e7dd80Sopenharmony_ci{ 1022b0e7dd80Sopenharmony_ci if (signum == SIGUSR1) { 1023b0e7dd80Sopenharmony_ci _exit(EXIT_SUCCESS); 1024b0e7dd80Sopenharmony_ci } 1025b0e7dd80Sopenharmony_ci} 1026b0e7dd80Sopenharmony_ci 1027b0e7dd80Sopenharmony_cibool EpollWaitforChildProcess(pid_t &pid, int &pipefd) 1028b0e7dd80Sopenharmony_ci{ 1029b0e7dd80Sopenharmony_ci int epollfd = epoll_create1(0); 1030b0e7dd80Sopenharmony_ci if (epollfd == -1) { 1031b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "epoll_create1 error."); 1032b0e7dd80Sopenharmony_ci return false; 1033b0e7dd80Sopenharmony_ci } 1034b0e7dd80Sopenharmony_ci 1035b0e7dd80Sopenharmony_ci struct epoll_event event; 1036b0e7dd80Sopenharmony_ci event.events = EPOLLIN; 1037b0e7dd80Sopenharmony_ci event.data.fd = pipefd; 1038b0e7dd80Sopenharmony_ci if (epoll_ctl(epollfd, EPOLL_CTL_ADD, pipefd, &event) == -1) { 1039b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "epoll_ctl error."); 1040b0e7dd80Sopenharmony_ci return false; 1041b0e7dd80Sopenharmony_ci } 1042b0e7dd80Sopenharmony_ci 1043b0e7dd80Sopenharmony_ci struct epoll_event events[1]; 1044b0e7dd80Sopenharmony_ci constexpr int waitTimeoutMs = 10000; // 10000ms = 10s 1045b0e7dd80Sopenharmony_ci int numEvents = 0; 1046b0e7dd80Sopenharmony_ci do { 1047b0e7dd80Sopenharmony_ci numEvents = epoll_wait(epollfd, events, 1, waitTimeoutMs); 1048b0e7dd80Sopenharmony_ci } while (numEvents == -1 && errno == EINTR); 1049b0e7dd80Sopenharmony_ci if (numEvents == -1) { 1050b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "epoll_wait error, error: (%{public}s).", strerror(errno)); 1051b0e7dd80Sopenharmony_ci close(pipefd); 1052b0e7dd80Sopenharmony_ci close(epollfd); 1053b0e7dd80Sopenharmony_ci return false; 1054b0e7dd80Sopenharmony_ci } else if (numEvents == 0) { 1055b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "epoll_wait timeout."); 1056b0e7dd80Sopenharmony_ci if (waitpid(pid, nullptr, WNOHANG) <= 0) { 1057b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "kill timeout child process."); 1058b0e7dd80Sopenharmony_ci kill(pid, SIGUSR1); 1059b0e7dd80Sopenharmony_ci } 1060b0e7dd80Sopenharmony_ci close(pipefd); 1061b0e7dd80Sopenharmony_ci close(epollfd); 1062b0e7dd80Sopenharmony_ci return false; 1063b0e7dd80Sopenharmony_ci } 1064b0e7dd80Sopenharmony_ci read(pipefd, &g_dumpStatus, sizeof(g_dumpStatus)); 1065b0e7dd80Sopenharmony_ci close(pipefd); 1066b0e7dd80Sopenharmony_ci close(epollfd); 1067b0e7dd80Sopenharmony_ci if (waitpid(pid, nullptr, 0) <= 0) { 1068b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "wait HitraceDump(%{public}d) exit failed, errno: (%{public}d)", pid, errno); 1069b0e7dd80Sopenharmony_ci } 1070b0e7dd80Sopenharmony_ci return true; 1071b0e7dd80Sopenharmony_ci} 1072b0e7dd80Sopenharmony_ci 1073b0e7dd80Sopenharmony_ciTraceErrorCode DumpTraceInner(std::vector<std::string> &outputFiles) 1074b0e7dd80Sopenharmony_ci{ 1075b0e7dd80Sopenharmony_ci int pipefd[2]; 1076b0e7dd80Sopenharmony_ci if (pipe(pipefd) == -1) { 1077b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "pipe creation error."); 1078b0e7dd80Sopenharmony_ci return TraceErrorCode::SYSTEM_ERROR; 1079b0e7dd80Sopenharmony_ci } 1080b0e7dd80Sopenharmony_ci 1081b0e7dd80Sopenharmony_ci std::string outputFileName = GenerateTraceFileName(); 1082b0e7dd80Sopenharmony_ci std::string reOutPath = CanonicalizeSpecPath(outputFileName.c_str()); 1083b0e7dd80Sopenharmony_ci /*Child process handles task, Father process wait.*/ 1084b0e7dd80Sopenharmony_ci pid_t pid = fork(); 1085b0e7dd80Sopenharmony_ci if (pid < 0) { 1086b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "fork error."); 1087b0e7dd80Sopenharmony_ci return TraceErrorCode::WRITE_TRACE_INFO_ERROR; 1088b0e7dd80Sopenharmony_ci } else if (pid == 0) { 1089b0e7dd80Sopenharmony_ci signal(SIGUSR1, TimeoutSignalHandler); 1090b0e7dd80Sopenharmony_ci close(pipefd[0]); 1091b0e7dd80Sopenharmony_ci std::string processName = "HitraceDump"; 1092b0e7dd80Sopenharmony_ci SetProcessName(processName); 1093b0e7dd80Sopenharmony_ci MarkClockSync(g_traceRootPath); 1094b0e7dd80Sopenharmony_ci constexpr int waitTime = 10000; // 10ms 1095b0e7dd80Sopenharmony_ci usleep(waitTime); 1096b0e7dd80Sopenharmony_ci if (ReadRawTrace(reOutPath)) { 1097b0e7dd80Sopenharmony_ci g_dumpStatus = TraceErrorCode::SUCCESS; 1098b0e7dd80Sopenharmony_ci } 1099b0e7dd80Sopenharmony_ci if (!IsRootVersion()) { 1100b0e7dd80Sopenharmony_ci DelSnapshotTraceFile(false, SNAPSHOT_FILE_MAX_COUNT); 1101b0e7dd80Sopenharmony_ci } 1102b0e7dd80Sopenharmony_ci HILOG_DEBUG(LOG_CORE, "%{public}s exit.", processName.c_str()); 1103b0e7dd80Sopenharmony_ci write(pipefd[1], &g_dumpStatus, sizeof(g_dumpStatus)); 1104b0e7dd80Sopenharmony_ci _exit(EXIT_SUCCESS); 1105b0e7dd80Sopenharmony_ci } else { 1106b0e7dd80Sopenharmony_ci close(pipefd[1]); 1107b0e7dd80Sopenharmony_ci } 1108b0e7dd80Sopenharmony_ci 1109b0e7dd80Sopenharmony_ci if (!EpollWaitforChildProcess(pid, pipefd[0])) { 1110b0e7dd80Sopenharmony_ci return TraceErrorCode::SYSTEM_ERROR; 1111b0e7dd80Sopenharmony_ci } 1112b0e7dd80Sopenharmony_ci 1113b0e7dd80Sopenharmony_ci if (g_dumpStatus) { 1114b0e7dd80Sopenharmony_ci if (remove(reOutPath.c_str()) == 0) { 1115b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "Delete outpath:%{public}s success.", reOutPath.c_str()); 1116b0e7dd80Sopenharmony_ci } else { 1117b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "Delete outpath:%{public}s failed.", reOutPath.c_str()); 1118b0e7dd80Sopenharmony_ci } 1119b0e7dd80Sopenharmony_ci return static_cast<TraceErrorCode>(g_dumpStatus.load()); 1120b0e7dd80Sopenharmony_ci } 1121b0e7dd80Sopenharmony_ci 1122b0e7dd80Sopenharmony_ci if (access(reOutPath.c_str(), F_OK) != 0) { 1123b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "DumpTraceInner: write %{public}s failed.", outputFileName.c_str()); 1124b0e7dd80Sopenharmony_ci return TraceErrorCode::WRITE_TRACE_INFO_ERROR; 1125b0e7dd80Sopenharmony_ci } 1126b0e7dd80Sopenharmony_ci 1127b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "Output: %{public}s.", reOutPath.c_str()); 1128b0e7dd80Sopenharmony_ci struct timeval now = {0, 0}; 1129b0e7dd80Sopenharmony_ci gettimeofday(&now, nullptr); 1130b0e7dd80Sopenharmony_ci int nowSec = now.tv_sec; 1131b0e7dd80Sopenharmony_ci SearchFromTable(outputFiles, nowSec); 1132b0e7dd80Sopenharmony_ci outputFiles.push_back(outputFileName); 1133b0e7dd80Sopenharmony_ci g_traceFilesTable.push_back({outputFileName, nowSec}); 1134b0e7dd80Sopenharmony_ci return TraceErrorCode::SUCCESS; 1135b0e7dd80Sopenharmony_ci} 1136b0e7dd80Sopenharmony_ci 1137b0e7dd80Sopenharmony_ciuint64_t GetSysParamTags() 1138b0e7dd80Sopenharmony_ci{ 1139b0e7dd80Sopenharmony_ci return OHOS::system::GetUintParameter<uint64_t>("debug.hitrace.tags.enableflags", 0); 1140b0e7dd80Sopenharmony_ci} 1141b0e7dd80Sopenharmony_ci 1142b0e7dd80Sopenharmony_civoid RestartService() 1143b0e7dd80Sopenharmony_ci{ 1144b0e7dd80Sopenharmony_ci CloseTrace(); 1145b0e7dd80Sopenharmony_ci const std::vector<std::string> tagGroups = {"scene_performance"}; 1146b0e7dd80Sopenharmony_ci OpenTrace(tagGroups); 1147b0e7dd80Sopenharmony_ci} 1148b0e7dd80Sopenharmony_ci 1149b0e7dd80Sopenharmony_cibool CheckParam() 1150b0e7dd80Sopenharmony_ci{ 1151b0e7dd80Sopenharmony_ci uint64_t currentTags = GetSysParamTags(); 1152b0e7dd80Sopenharmony_ci if (currentTags == g_sysInitParamTags) { 1153b0e7dd80Sopenharmony_ci return true; 1154b0e7dd80Sopenharmony_ci } 1155b0e7dd80Sopenharmony_ci 1156b0e7dd80Sopenharmony_ci if (currentTags == 0) { 1157b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "tag is 0, restart it."); 1158b0e7dd80Sopenharmony_ci RestartService(); 1159b0e7dd80Sopenharmony_ci return false; 1160b0e7dd80Sopenharmony_ci } 1161b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "trace is being used, restart later."); 1162b0e7dd80Sopenharmony_ci return false; 1163b0e7dd80Sopenharmony_ci} 1164b0e7dd80Sopenharmony_ci 1165b0e7dd80Sopenharmony_cibool CheckTraceFile() 1166b0e7dd80Sopenharmony_ci{ 1167b0e7dd80Sopenharmony_ci const std::string enable = "1"; 1168b0e7dd80Sopenharmony_ci if (ReadFile("tracing_on").substr(0, enable.size()) == enable) { 1169b0e7dd80Sopenharmony_ci return true; 1170b0e7dd80Sopenharmony_ci } 1171b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "tracing_on is 0, restart it."); 1172b0e7dd80Sopenharmony_ci RestartService(); 1173b0e7dd80Sopenharmony_ci return false; 1174b0e7dd80Sopenharmony_ci} 1175b0e7dd80Sopenharmony_ci 1176b0e7dd80Sopenharmony_ci/** 1177b0e7dd80Sopenharmony_ci * SERVICE_MODE is running, check param and tracing_on. 1178b0e7dd80Sopenharmony_ci*/ 1179b0e7dd80Sopenharmony_cibool CheckServiceRunning() 1180b0e7dd80Sopenharmony_ci{ 1181b0e7dd80Sopenharmony_ci if (CheckParam() && CheckTraceFile()) { 1182b0e7dd80Sopenharmony_ci return true; 1183b0e7dd80Sopenharmony_ci } 1184b0e7dd80Sopenharmony_ci return false; 1185b0e7dd80Sopenharmony_ci} 1186b0e7dd80Sopenharmony_ci 1187b0e7dd80Sopenharmony_civoid MonitorServiceTask() 1188b0e7dd80Sopenharmony_ci{ 1189b0e7dd80Sopenharmony_ci g_serviceThreadIsStart = true; 1190b0e7dd80Sopenharmony_ci const std::string threadName = "TraceMonitor"; 1191b0e7dd80Sopenharmony_ci prctl(PR_SET_NAME, threadName.c_str()); 1192b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "MonitorServiceTask: monitor thread start."); 1193b0e7dd80Sopenharmony_ci const int intervalTime = 15; 1194b0e7dd80Sopenharmony_ci while (true) { 1195b0e7dd80Sopenharmony_ci sleep(intervalTime); 1196b0e7dd80Sopenharmony_ci if (g_traceMode != TraceMode::SERVICE_MODE) { 1197b0e7dd80Sopenharmony_ci break; 1198b0e7dd80Sopenharmony_ci } 1199b0e7dd80Sopenharmony_ci 1200b0e7dd80Sopenharmony_ci if (!CheckServiceRunning()) { 1201b0e7dd80Sopenharmony_ci continue; 1202b0e7dd80Sopenharmony_ci } 1203b0e7dd80Sopenharmony_ci 1204b0e7dd80Sopenharmony_ci const int cpuNums = GetCpuProcessors(); 1205b0e7dd80Sopenharmony_ci std::vector<int> result; 1206b0e7dd80Sopenharmony_ci std::unique_ptr<DynamicBuffer> dynamicBuffer = std::make_unique<DynamicBuffer>(g_traceRootPath, cpuNums); 1207b0e7dd80Sopenharmony_ci dynamicBuffer->CalculateBufferSize(result); 1208b0e7dd80Sopenharmony_ci 1209b0e7dd80Sopenharmony_ci if (static_cast<int>(result.size()) != cpuNums) { 1210b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "CalculateAllNewBufferSize failed."); 1211b0e7dd80Sopenharmony_ci break; 1212b0e7dd80Sopenharmony_ci } 1213b0e7dd80Sopenharmony_ci 1214b0e7dd80Sopenharmony_ci for (size_t i = 0; i < result.size(); i++) { 1215b0e7dd80Sopenharmony_ci HILOG_DEBUG(LOG_CORE, "cpu%{public}zu set size %{public}d.", i, result[i]); 1216b0e7dd80Sopenharmony_ci std::string path = "per_cpu/cpu" + std::to_string(i) + "/buffer_size_kb"; 1217b0e7dd80Sopenharmony_ci WriteStrToFile(path, std::to_string(result[i])); 1218b0e7dd80Sopenharmony_ci } 1219b0e7dd80Sopenharmony_ci } 1220b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "MonitorServiceTask: monitor thread exit."); 1221b0e7dd80Sopenharmony_ci g_serviceThreadIsStart = false; 1222b0e7dd80Sopenharmony_ci} 1223b0e7dd80Sopenharmony_ci 1224b0e7dd80Sopenharmony_ciTraceErrorCode HandleTraceOpen(const TraceParams &traceParams, 1225b0e7dd80Sopenharmony_ci const std::map<std::string, TagCategory> &allTags, 1226b0e7dd80Sopenharmony_ci const std::map<std::string, std::vector<std::string>> &tagGroupTable) 1227b0e7dd80Sopenharmony_ci{ 1228b0e7dd80Sopenharmony_ci if (!SetTraceSetting(traceParams, allTags, tagGroupTable)) { 1229b0e7dd80Sopenharmony_ci return TraceErrorCode::FILE_ERROR; 1230b0e7dd80Sopenharmony_ci } 1231b0e7dd80Sopenharmony_ci SetTraceNodeStatus("tracing_on", true); 1232b0e7dd80Sopenharmony_ci g_currentTraceParams = traceParams; 1233b0e7dd80Sopenharmony_ci return TraceErrorCode::SUCCESS; 1234b0e7dd80Sopenharmony_ci} 1235b0e7dd80Sopenharmony_ci 1236b0e7dd80Sopenharmony_ciTraceErrorCode HandleServiceTraceOpen(const std::vector<std::string> &tagGroups, 1237b0e7dd80Sopenharmony_ci const std::map<std::string, TagCategory> &allTags, 1238b0e7dd80Sopenharmony_ci const std::map<std::string, std::vector<std::string>> &tagGroupTable) 1239b0e7dd80Sopenharmony_ci{ 1240b0e7dd80Sopenharmony_ci TraceParams serviceTraceParams; 1241b0e7dd80Sopenharmony_ci serviceTraceParams.tagGroups = tagGroups; 1242b0e7dd80Sopenharmony_ci serviceTraceParams.bufferSize = std::to_string(DEFAULT_BUFFER_SIZE); 1243b0e7dd80Sopenharmony_ci if (IsHmKernel()) { 1244b0e7dd80Sopenharmony_ci serviceTraceParams.bufferSize = std::to_string(HM_DEFAULT_BUFFER_SIZE); 1245b0e7dd80Sopenharmony_ci } 1246b0e7dd80Sopenharmony_ci serviceTraceParams.clockType = "boot"; 1247b0e7dd80Sopenharmony_ci serviceTraceParams.isOverWrite = "1"; 1248b0e7dd80Sopenharmony_ci serviceTraceParams.fileSize = DEFAULT_FILE_SIZE; 1249b0e7dd80Sopenharmony_ci return HandleTraceOpen(serviceTraceParams, allTags, tagGroupTable); 1250b0e7dd80Sopenharmony_ci} 1251b0e7dd80Sopenharmony_ci 1252b0e7dd80Sopenharmony_civoid RemoveUnSpace(std::string str, std::string& args) 1253b0e7dd80Sopenharmony_ci{ 1254b0e7dd80Sopenharmony_ci int maxCircleTimes = 30; 1255b0e7dd80Sopenharmony_ci int curTimes = 0; 1256b0e7dd80Sopenharmony_ci const size_t symbolAndSpaceLen = 2; 1257b0e7dd80Sopenharmony_ci std::string strSpace = str + " "; 1258b0e7dd80Sopenharmony_ci while (curTimes < maxCircleTimes) { 1259b0e7dd80Sopenharmony_ci curTimes++; 1260b0e7dd80Sopenharmony_ci std::string::size_type index = args.find(strSpace); 1261b0e7dd80Sopenharmony_ci if (index != std::string::npos) { 1262b0e7dd80Sopenharmony_ci args.replace(index, symbolAndSpaceLen, str); 1263b0e7dd80Sopenharmony_ci } else { 1264b0e7dd80Sopenharmony_ci break; 1265b0e7dd80Sopenharmony_ci } 1266b0e7dd80Sopenharmony_ci } 1267b0e7dd80Sopenharmony_ci} 1268b0e7dd80Sopenharmony_ci 1269b0e7dd80Sopenharmony_civoid SetCmdTraceIntParams(const std::string &traceParamsStr, int &traceParams) 1270b0e7dd80Sopenharmony_ci{ 1271b0e7dd80Sopenharmony_ci if (traceParamsStr.empty() || !IsNumber(traceParamsStr)) { 1272b0e7dd80Sopenharmony_ci HILOG_WARN(LOG_CORE, "Illegal input, traceParams initialized to null."); 1273b0e7dd80Sopenharmony_ci traceParams = 0; 1274b0e7dd80Sopenharmony_ci return; 1275b0e7dd80Sopenharmony_ci } 1276b0e7dd80Sopenharmony_ci traceParams = std::stoi(traceParamsStr); 1277b0e7dd80Sopenharmony_ci if (traceParams <= 0) { 1278b0e7dd80Sopenharmony_ci HILOG_WARN(LOG_CORE, "Illegal input, traceParams initialized to null."); 1279b0e7dd80Sopenharmony_ci traceParams = 0; 1280b0e7dd80Sopenharmony_ci } 1281b0e7dd80Sopenharmony_ci} 1282b0e7dd80Sopenharmony_ci 1283b0e7dd80Sopenharmony_ci/** 1284b0e7dd80Sopenharmony_ci * args: tags:tag1,tags2... tagGroups:group1,group2... clockType:boot bufferSize:1024 overwrite:1 output:filename 1285b0e7dd80Sopenharmony_ci * cmdTraceParams: Save the above parameters 1286b0e7dd80Sopenharmony_ci*/ 1287b0e7dd80Sopenharmony_cibool ParseArgs(const std::string &args, TraceParams &cmdTraceParams, const std::map<std::string, TagCategory> &allTags, 1288b0e7dd80Sopenharmony_ci const std::map<std::string, std::vector<std::string>> &tagGroupTable) 1289b0e7dd80Sopenharmony_ci{ 1290b0e7dd80Sopenharmony_ci std::string userArgs = args; 1291b0e7dd80Sopenharmony_ci std::string str = ":"; 1292b0e7dd80Sopenharmony_ci RemoveUnSpace(str, userArgs); 1293b0e7dd80Sopenharmony_ci str = ","; 1294b0e7dd80Sopenharmony_ci RemoveUnSpace(str, userArgs); 1295b0e7dd80Sopenharmony_ci std::vector<std::string> argList = Split(userArgs, ' '); 1296b0e7dd80Sopenharmony_ci for (std::string item : argList) { 1297b0e7dd80Sopenharmony_ci size_t pos = item.find(":"); 1298b0e7dd80Sopenharmony_ci if (pos == std::string::npos) { 1299b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "trace command line without colon appears: %{public}s, continue.", item.c_str()); 1300b0e7dd80Sopenharmony_ci continue; 1301b0e7dd80Sopenharmony_ci } 1302b0e7dd80Sopenharmony_ci std::string itemName = item.substr(0, pos); 1303b0e7dd80Sopenharmony_ci if (itemName == "tags") { 1304b0e7dd80Sopenharmony_ci cmdTraceParams.tags = Split(item.substr(pos + 1), ','); 1305b0e7dd80Sopenharmony_ci } else if (itemName == "tagGroups") { 1306b0e7dd80Sopenharmony_ci cmdTraceParams.tagGroups = Split(item.substr(pos + 1), ','); 1307b0e7dd80Sopenharmony_ci } else if (itemName == "clockType") { 1308b0e7dd80Sopenharmony_ci cmdTraceParams.clockType = item.substr(pos + 1); 1309b0e7dd80Sopenharmony_ci } else if (itemName == "bufferSize") { 1310b0e7dd80Sopenharmony_ci cmdTraceParams.bufferSize = item.substr(pos + 1); 1311b0e7dd80Sopenharmony_ci } else if (itemName == "overwrite") { 1312b0e7dd80Sopenharmony_ci cmdTraceParams.isOverWrite = item.substr(pos + 1); 1313b0e7dd80Sopenharmony_ci } else if (itemName == "output") { 1314b0e7dd80Sopenharmony_ci cmdTraceParams.outputFile = item.substr(pos + 1); 1315b0e7dd80Sopenharmony_ci } else if (itemName == "fileSize") { 1316b0e7dd80Sopenharmony_ci std::string fileSizeStr = item.substr(pos + 1); 1317b0e7dd80Sopenharmony_ci SetCmdTraceIntParams(fileSizeStr, cmdTraceParams.fileSize); 1318b0e7dd80Sopenharmony_ci } else if (itemName == "fileLimit") { 1319b0e7dd80Sopenharmony_ci std::string fileLimitStr = item.substr(pos + 1); 1320b0e7dd80Sopenharmony_ci SetCmdTraceIntParams(fileLimitStr, cmdTraceParams.fileLimit); 1321b0e7dd80Sopenharmony_ci } else if (itemName == "appPid") { 1322b0e7dd80Sopenharmony_ci std::string pidStr = item.substr(pos + 1); 1323b0e7dd80Sopenharmony_ci SetCmdTraceIntParams(pidStr, cmdTraceParams.appPid); 1324b0e7dd80Sopenharmony_ci if (cmdTraceParams.appPid == 0) { 1325b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "Illegal input, appPid(%{public}s) must be number and greater than 0.", 1326b0e7dd80Sopenharmony_ci pidStr.c_str()); 1327b0e7dd80Sopenharmony_ci return false; 1328b0e7dd80Sopenharmony_ci } 1329b0e7dd80Sopenharmony_ci OHOS::system::SetParameter("debug.hitrace.app_pid", pidStr); 1330b0e7dd80Sopenharmony_ci } else { 1331b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "Extra trace command line options appear when ParseArgs: %{public}s, return false.", 1332b0e7dd80Sopenharmony_ci itemName.c_str()); 1333b0e7dd80Sopenharmony_ci return false; 1334b0e7dd80Sopenharmony_ci } 1335b0e7dd80Sopenharmony_ci } 1336b0e7dd80Sopenharmony_ci if (CheckTags(cmdTraceParams.tags, allTags) && CheckTagGroup(cmdTraceParams.tagGroups, tagGroupTable)) { 1337b0e7dd80Sopenharmony_ci return true; 1338b0e7dd80Sopenharmony_ci } 1339b0e7dd80Sopenharmony_ci return false; 1340b0e7dd80Sopenharmony_ci} 1341b0e7dd80Sopenharmony_ci 1342b0e7dd80Sopenharmony_civoid WriteCpuFreqTrace() 1343b0e7dd80Sopenharmony_ci{ 1344b0e7dd80Sopenharmony_ci std::string freqsfmt = "cpu frequency: "; 1345b0e7dd80Sopenharmony_ci ReadCurrentCpuFrequencies(freqsfmt); 1346b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "hitracedump write trace(%{public}s)", freqsfmt.c_str()); 1347b0e7dd80Sopenharmony_ci HITRACE_METER_NAME(HITRACE_TAG_OHOS, freqsfmt); 1348b0e7dd80Sopenharmony_ci} 1349b0e7dd80Sopenharmony_ci} // namespace 1350b0e7dd80Sopenharmony_ci 1351b0e7dd80Sopenharmony_ci#ifdef HITRACE_UNITTEST 1352b0e7dd80Sopenharmony_civoid SetSysInitParamTags(uint64_t sysInitParamTags) 1353b0e7dd80Sopenharmony_ci{ 1354b0e7dd80Sopenharmony_ci g_sysInitParamTags = sysInitParamTags; 1355b0e7dd80Sopenharmony_ci} 1356b0e7dd80Sopenharmony_ci 1357b0e7dd80Sopenharmony_cibool SetCheckParam() 1358b0e7dd80Sopenharmony_ci{ 1359b0e7dd80Sopenharmony_ci int ret = CheckParam(); 1360b0e7dd80Sopenharmony_ci return ret; 1361b0e7dd80Sopenharmony_ci} 1362b0e7dd80Sopenharmony_ci#endif 1363b0e7dd80Sopenharmony_ci 1364b0e7dd80Sopenharmony_ciTraceMode GetTraceMode() 1365b0e7dd80Sopenharmony_ci{ 1366b0e7dd80Sopenharmony_ci return g_traceMode; 1367b0e7dd80Sopenharmony_ci} 1368b0e7dd80Sopenharmony_ci 1369b0e7dd80Sopenharmony_ciTraceErrorCode OpenTrace(const std::vector<std::string> &tagGroups) 1370b0e7dd80Sopenharmony_ci{ 1371b0e7dd80Sopenharmony_ci if (g_traceMode != CLOSE) { 1372b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "OpenTrace: CALL_ERROR, g_traceMode:%{public}d.", static_cast<int>(g_traceMode)); 1373b0e7dd80Sopenharmony_ci return CALL_ERROR; 1374b0e7dd80Sopenharmony_ci } 1375b0e7dd80Sopenharmony_ci std::lock_guard<std::mutex> lock(g_traceMutex); 1376b0e7dd80Sopenharmony_ci if (!IsTraceMounted()) { 1377b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "OpenTrace: TRACE_NOT_SUPPORTED."); 1378b0e7dd80Sopenharmony_ci return TRACE_NOT_SUPPORTED; 1379b0e7dd80Sopenharmony_ci } 1380b0e7dd80Sopenharmony_ci 1381b0e7dd80Sopenharmony_ci std::map<std::string, TagCategory> allTags; 1382b0e7dd80Sopenharmony_ci std::map<std::string, std::vector<std::string>> tagGroupTable; 1383b0e7dd80Sopenharmony_ci if (!ParseTagInfo(allTags, tagGroupTable)) { 1384b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "OpenTrace: ParseTagInfo TAG_ERROR."); 1385b0e7dd80Sopenharmony_ci return TAG_ERROR; 1386b0e7dd80Sopenharmony_ci } 1387b0e7dd80Sopenharmony_ci 1388b0e7dd80Sopenharmony_ci if (tagGroups.size() == 0 || !CheckTagGroup(tagGroups, tagGroupTable)) { 1389b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "OpenTrace: TAG_ERROR."); 1390b0e7dd80Sopenharmony_ci return TAG_ERROR; 1391b0e7dd80Sopenharmony_ci } 1392b0e7dd80Sopenharmony_ci 1393b0e7dd80Sopenharmony_ci TraceErrorCode ret = HandleServiceTraceOpen(tagGroups, allTags, tagGroupTable); 1394b0e7dd80Sopenharmony_ci if (ret != SUCCESS) { 1395b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "OpenTrace: open fail."); 1396b0e7dd80Sopenharmony_ci return ret; 1397b0e7dd80Sopenharmony_ci } 1398b0e7dd80Sopenharmony_ci g_traceMode = SERVICE_MODE; 1399b0e7dd80Sopenharmony_ci 1400b0e7dd80Sopenharmony_ci DelSnapshotTraceFile(); 1401b0e7dd80Sopenharmony_ci if (!IsHmKernel() && !g_serviceThreadIsStart) { 1402b0e7dd80Sopenharmony_ci // open SERVICE_MODE monitor thread 1403b0e7dd80Sopenharmony_ci auto it = []() { 1404b0e7dd80Sopenharmony_ci MonitorServiceTask(); 1405b0e7dd80Sopenharmony_ci }; 1406b0e7dd80Sopenharmony_ci std::thread auxiliaryTask(it); 1407b0e7dd80Sopenharmony_ci auxiliaryTask.detach(); 1408b0e7dd80Sopenharmony_ci } 1409b0e7dd80Sopenharmony_ci g_sysInitParamTags = GetSysParamTags(); 1410b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "OpenTrace: SERVICE_MODE open success."); 1411b0e7dd80Sopenharmony_ci return ret; 1412b0e7dd80Sopenharmony_ci} 1413b0e7dd80Sopenharmony_ci 1414b0e7dd80Sopenharmony_ciTraceErrorCode OpenTrace(const std::string &args) 1415b0e7dd80Sopenharmony_ci{ 1416b0e7dd80Sopenharmony_ci std::lock_guard<std::mutex> lock(g_traceMutex); 1417b0e7dd80Sopenharmony_ci if (g_traceMode != CLOSE) { 1418b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "OpenTrace: CALL_ERROR, g_traceMode:%{public}d.", static_cast<int>(g_traceMode)); 1419b0e7dd80Sopenharmony_ci return CALL_ERROR; 1420b0e7dd80Sopenharmony_ci } 1421b0e7dd80Sopenharmony_ci 1422b0e7dd80Sopenharmony_ci if (!IsTraceMounted()) { 1423b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "Hitrace OpenTrace: TRACE_NOT_SUPPORTED."); 1424b0e7dd80Sopenharmony_ci return TRACE_NOT_SUPPORTED; 1425b0e7dd80Sopenharmony_ci } 1426b0e7dd80Sopenharmony_ci 1427b0e7dd80Sopenharmony_ci std::map<std::string, TagCategory> allTags; 1428b0e7dd80Sopenharmony_ci std::map<std::string, std::vector<std::string>> tagGroupTable; 1429b0e7dd80Sopenharmony_ci if (!ParseTagInfo(allTags, tagGroupTable) || allTags.size() == 0 || tagGroupTable.size() == 0) { 1430b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "Hitrace OpenTrace: ParseTagInfo TAG_ERROR."); 1431b0e7dd80Sopenharmony_ci return TAG_ERROR; 1432b0e7dd80Sopenharmony_ci } 1433b0e7dd80Sopenharmony_ci // parse args 1434b0e7dd80Sopenharmony_ci TraceParams cmdTraceParams; 1435b0e7dd80Sopenharmony_ci if (!ParseArgs(args, cmdTraceParams, allTags, tagGroupTable)) { 1436b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "Hitrace OpenTrace: TAG_ERROR."); 1437b0e7dd80Sopenharmony_ci return TAG_ERROR; 1438b0e7dd80Sopenharmony_ci } 1439b0e7dd80Sopenharmony_ci 1440b0e7dd80Sopenharmony_ci TraceErrorCode ret = HandleTraceOpen(cmdTraceParams, allTags, tagGroupTable); 1441b0e7dd80Sopenharmony_ci if (ret != SUCCESS) { 1442b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "Hitrace OpenTrace: CMD_MODE open failed."); 1443b0e7dd80Sopenharmony_ci return FILE_ERROR; 1444b0e7dd80Sopenharmony_ci } 1445b0e7dd80Sopenharmony_ci g_traceMode = CMD_MODE; 1446b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "Hitrace OpenTrace: CMD_MODE open success, args:%{public}s.", args.c_str()); 1447b0e7dd80Sopenharmony_ci return ret; 1448b0e7dd80Sopenharmony_ci} 1449b0e7dd80Sopenharmony_ci 1450b0e7dd80Sopenharmony_ciTraceRetInfo DumpTrace() 1451b0e7dd80Sopenharmony_ci{ 1452b0e7dd80Sopenharmony_ci TraceRetInfo ret; 1453b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "DumpTrace start."); 1454b0e7dd80Sopenharmony_ci if (g_traceMode != SERVICE_MODE) { 1455b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "DumpTrace: CALL_ERROR, g_traceMode:%{public}d.", static_cast<int>(g_traceMode)); 1456b0e7dd80Sopenharmony_ci ret.errorCode = CALL_ERROR; 1457b0e7dd80Sopenharmony_ci return ret; 1458b0e7dd80Sopenharmony_ci } 1459b0e7dd80Sopenharmony_ci 1460b0e7dd80Sopenharmony_ci if (!CheckServiceRunning()) { 1461b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "DumpTrace: TRACE_IS_OCCUPIED."); 1462b0e7dd80Sopenharmony_ci ret.errorCode = TRACE_IS_OCCUPIED; 1463b0e7dd80Sopenharmony_ci return ret; 1464b0e7dd80Sopenharmony_ci } 1465b0e7dd80Sopenharmony_ci std::lock_guard<std::mutex> lock(g_traceMutex); 1466b0e7dd80Sopenharmony_ci g_dumpStatus = TraceErrorCode::UNSET; 1467b0e7dd80Sopenharmony_ci SetTimeIntervalBoundary(); 1468b0e7dd80Sopenharmony_ci ret.errorCode = DumpTraceInner(ret.outputFiles); 1469b0e7dd80Sopenharmony_ci RestoreTimeIntervalBoundary(); 1470b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "DumpTrace done."); 1471b0e7dd80Sopenharmony_ci return ret; 1472b0e7dd80Sopenharmony_ci} 1473b0e7dd80Sopenharmony_ci 1474b0e7dd80Sopenharmony_ciTraceRetInfo DumpTrace(int maxDuration, uint64_t traceEndTime) 1475b0e7dd80Sopenharmony_ci{ 1476b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "DumpTrace with timelimit start, timelimit is %{public}d, endtime is (%{public}" PRId64 ").", 1477b0e7dd80Sopenharmony_ci maxDuration, traceEndTime); 1478b0e7dd80Sopenharmony_ci TraceRetInfo ret; 1479b0e7dd80Sopenharmony_ci if (maxDuration < 0) { 1480b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "DumpTrace: Illegal input."); 1481b0e7dd80Sopenharmony_ci ret.errorCode = CALL_ERROR; 1482b0e7dd80Sopenharmony_ci return ret; 1483b0e7dd80Sopenharmony_ci } 1484b0e7dd80Sopenharmony_ci { 1485b0e7dd80Sopenharmony_ci std::time_t now = std::time(nullptr); 1486b0e7dd80Sopenharmony_ci if (maxDuration > (now - 1)) { 1487b0e7dd80Sopenharmony_ci maxDuration = 0; 1488b0e7dd80Sopenharmony_ci } 1489b0e7dd80Sopenharmony_ci std::lock_guard<std::mutex> lock(g_traceMutex); 1490b0e7dd80Sopenharmony_ci if (traceEndTime > 0) { 1491b0e7dd80Sopenharmony_ci if (traceEndTime > static_cast<uint64_t>(now)) { 1492b0e7dd80Sopenharmony_ci HILOG_WARN(LOG_CORE, "DumpTrace: Warning: traceEndTime is later than current time."); 1493b0e7dd80Sopenharmony_ci } 1494b0e7dd80Sopenharmony_ci struct sysinfo info; 1495b0e7dd80Sopenharmony_ci if (sysinfo(&info) != 0) { 1496b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "Get system info failed."); 1497b0e7dd80Sopenharmony_ci ret.errorCode = UNKNOWN_ERROR; 1498b0e7dd80Sopenharmony_ci return ret; 1499b0e7dd80Sopenharmony_ci } 1500b0e7dd80Sopenharmony_ci std::time_t boot_time = now - info.uptime; 1501b0e7dd80Sopenharmony_ci if (traceEndTime > static_cast<uint64_t>(boot_time)) { 1502b0e7dd80Sopenharmony_ci // beware of input precision of seconds: add an extra second of tolerance 1503b0e7dd80Sopenharmony_ci g_inputTraceEndTime = (traceEndTime - static_cast<uint64_t>(boot_time) + 1) * S_TO_NS; 1504b0e7dd80Sopenharmony_ci } else { 1505b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, 1506b0e7dd80Sopenharmony_ci "DumpTrace: traceEndTime:(%{public}" PRId64 ") is earlier than boot_time:(%{public}" PRId64 ").", 1507b0e7dd80Sopenharmony_ci traceEndTime, static_cast<uint64_t>(boot_time)); 1508b0e7dd80Sopenharmony_ci ret.errorCode = OUT_OF_TIME; 1509b0e7dd80Sopenharmony_ci return ret; 1510b0e7dd80Sopenharmony_ci } 1511b0e7dd80Sopenharmony_ci g_inputMaxDuration = maxDuration ? maxDuration + 1 : 0; // for precision tolerance 1512b0e7dd80Sopenharmony_ci } else { 1513b0e7dd80Sopenharmony_ci g_inputMaxDuration = maxDuration; 1514b0e7dd80Sopenharmony_ci } 1515b0e7dd80Sopenharmony_ci } 1516b0e7dd80Sopenharmony_ci ret = DumpTrace(); 1517b0e7dd80Sopenharmony_ci { 1518b0e7dd80Sopenharmony_ci std::lock_guard<std::mutex> lock(g_traceMutex); 1519b0e7dd80Sopenharmony_ci g_inputMaxDuration = 0; 1520b0e7dd80Sopenharmony_ci g_inputTraceEndTime = 0; 1521b0e7dd80Sopenharmony_ci } 1522b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "DumpTrace with time limit done."); 1523b0e7dd80Sopenharmony_ci return ret; 1524b0e7dd80Sopenharmony_ci} 1525b0e7dd80Sopenharmony_ci 1526b0e7dd80Sopenharmony_ciTraceErrorCode DumpTraceOn() 1527b0e7dd80Sopenharmony_ci{ 1528b0e7dd80Sopenharmony_ci std::lock_guard<std::mutex> lock(g_traceMutex); 1529b0e7dd80Sopenharmony_ci // check current trace status 1530b0e7dd80Sopenharmony_ci if (g_traceMode != CMD_MODE) { 1531b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "DumpTraceOn: CALL_ERROR, g_traceMode:%{public}d.", static_cast<int>(g_traceMode)); 1532b0e7dd80Sopenharmony_ci return CALL_ERROR; 1533b0e7dd80Sopenharmony_ci } 1534b0e7dd80Sopenharmony_ci 1535b0e7dd80Sopenharmony_ci if (!g_dumpEnd) { 1536b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "DumpTraceOn: CALL_ERROR, record trace is dumping now."); 1537b0e7dd80Sopenharmony_ci return CALL_ERROR; 1538b0e7dd80Sopenharmony_ci } 1539b0e7dd80Sopenharmony_ci 1540b0e7dd80Sopenharmony_ci // start task thread 1541b0e7dd80Sopenharmony_ci auto it = []() { 1542b0e7dd80Sopenharmony_ci ProcessDumpTask(); 1543b0e7dd80Sopenharmony_ci }; 1544b0e7dd80Sopenharmony_ci std::thread task(it); 1545b0e7dd80Sopenharmony_ci task.detach(); 1546b0e7dd80Sopenharmony_ci WriteCpuFreqTrace(); 1547b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "Recording trace on."); 1548b0e7dd80Sopenharmony_ci return SUCCESS; 1549b0e7dd80Sopenharmony_ci} 1550b0e7dd80Sopenharmony_ci 1551b0e7dd80Sopenharmony_ciTraceRetInfo DumpTraceOff() 1552b0e7dd80Sopenharmony_ci{ 1553b0e7dd80Sopenharmony_ci std::lock_guard<std::mutex> lock(g_traceMutex); 1554b0e7dd80Sopenharmony_ci TraceRetInfo ret; 1555b0e7dd80Sopenharmony_ci // check current trace status 1556b0e7dd80Sopenharmony_ci if (g_traceMode != CMD_MODE) { 1557b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "DumpTraceOff: The current state is %{public}d, data exception.", 1558b0e7dd80Sopenharmony_ci static_cast<int>(g_traceMode)); 1559b0e7dd80Sopenharmony_ci ret.errorCode = CALL_ERROR; 1560b0e7dd80Sopenharmony_ci ret.outputFiles = g_outputFilesForCmd; 1561b0e7dd80Sopenharmony_ci return ret; 1562b0e7dd80Sopenharmony_ci } 1563b0e7dd80Sopenharmony_ci 1564b0e7dd80Sopenharmony_ci g_dumpFlag = false; 1565b0e7dd80Sopenharmony_ci while (!g_dumpEnd) { 1566b0e7dd80Sopenharmony_ci usleep(UNIT_TIME); 1567b0e7dd80Sopenharmony_ci g_dumpFlag = false; 1568b0e7dd80Sopenharmony_ci } 1569b0e7dd80Sopenharmony_ci ret.errorCode = SUCCESS; 1570b0e7dd80Sopenharmony_ci ret.outputFiles = g_outputFilesForCmd; 1571b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "Recording trace off."); 1572b0e7dd80Sopenharmony_ci return ret; 1573b0e7dd80Sopenharmony_ci} 1574b0e7dd80Sopenharmony_ci 1575b0e7dd80Sopenharmony_ciTraceErrorCode CloseTrace() 1576b0e7dd80Sopenharmony_ci{ 1577b0e7dd80Sopenharmony_ci std::lock_guard<std::mutex> lock(g_traceMutex); 1578b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "CloseTrace start."); 1579b0e7dd80Sopenharmony_ci if (g_traceMode == CLOSE) { 1580b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "Trace already close."); 1581b0e7dd80Sopenharmony_ci return SUCCESS; 1582b0e7dd80Sopenharmony_ci } 1583b0e7dd80Sopenharmony_ci 1584b0e7dd80Sopenharmony_ci g_traceMode = CLOSE; 1585b0e7dd80Sopenharmony_ci // Waiting for the data drop task to end 1586b0e7dd80Sopenharmony_ci g_dumpFlag = false; 1587b0e7dd80Sopenharmony_ci while (!g_dumpEnd) { 1588b0e7dd80Sopenharmony_ci usleep(UNIT_TIME); 1589b0e7dd80Sopenharmony_ci g_dumpFlag = false; 1590b0e7dd80Sopenharmony_ci } 1591b0e7dd80Sopenharmony_ci OHOS::system::SetParameter("debug.hitrace.app_pid", "-1"); 1592b0e7dd80Sopenharmony_ci std::map<std::string, TagCategory> allTags; 1593b0e7dd80Sopenharmony_ci std::map<std::string, std::vector<std::string>> tagGroupTable; 1594b0e7dd80Sopenharmony_ci if (!ParseTagInfo(allTags, tagGroupTable) || allTags.size() == 0 || tagGroupTable.size() == 0) { 1595b0e7dd80Sopenharmony_ci HILOG_ERROR(LOG_CORE, "CloseTrace: ParseTagInfo TAG_ERROR."); 1596b0e7dd80Sopenharmony_ci return TAG_ERROR; 1597b0e7dd80Sopenharmony_ci } 1598b0e7dd80Sopenharmony_ci TraceInit(allTags); 1599b0e7dd80Sopenharmony_ci TruncateFile(); 1600b0e7dd80Sopenharmony_ci HILOG_INFO(LOG_CORE, "CloseTrace done."); 1601b0e7dd80Sopenharmony_ci return SUCCESS; 1602b0e7dd80Sopenharmony_ci} 1603b0e7dd80Sopenharmony_ci 1604b0e7dd80Sopenharmony_cistd::vector<std::pair<std::string, int>> GetTraceFilesTable() 1605b0e7dd80Sopenharmony_ci{ 1606b0e7dd80Sopenharmony_ci return g_traceFilesTable; 1607b0e7dd80Sopenharmony_ci} 1608b0e7dd80Sopenharmony_ci 1609b0e7dd80Sopenharmony_civoid SetTraceFilesTable(const std::vector<std::pair<std::string, int>>& traceFilesTable) 1610b0e7dd80Sopenharmony_ci{ 1611b0e7dd80Sopenharmony_ci g_traceFilesTable = traceFilesTable; 1612b0e7dd80Sopenharmony_ci} 1613b0e7dd80Sopenharmony_ci} // Hitrace 1614b0e7dd80Sopenharmony_ci} // HiviewDFX 1615b0e7dd80Sopenharmony_ci} // OHOS 1616