148f512ceSopenharmony_ci/* 248f512ceSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 348f512ceSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 448f512ceSopenharmony_ci * you may not use this file except in compliance with the License. 548f512ceSopenharmony_ci * You may obtain a copy of the License at 648f512ceSopenharmony_ci * 748f512ceSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 848f512ceSopenharmony_ci * 948f512ceSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1048f512ceSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1148f512ceSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1248f512ceSopenharmony_ci * See the License for the specific language governing permissions and 1348f512ceSopenharmony_ci * limitations under the License. 1448f512ceSopenharmony_ci */ 1548f512ceSopenharmony_ci#define HILOG_TAG "PerfRecord" 1648f512ceSopenharmony_ci 1748f512ceSopenharmony_ci#include "perf_event_record.h" 1848f512ceSopenharmony_ci#include "spe_decoder.h" 1948f512ceSopenharmony_ci#include <cinttypes> 2048f512ceSopenharmony_ci 2148f512ceSopenharmony_ci#include "utilities.h" 2248f512ceSopenharmony_ci 2348f512ceSopenharmony_ciusing namespace OHOS::HiviewDFX; 2448f512ceSopenharmony_ciusing namespace std; 2548f512ceSopenharmony_cinamespace OHOS { 2648f512ceSopenharmony_cinamespace Developtools { 2748f512ceSopenharmony_cinamespace HiPerf { 2848f512ceSopenharmony_ci 2948f512ceSopenharmony_civoid *g_sampleMemCache = nullptr; // for read record from buf thread 3048f512ceSopenharmony_civoid *g_sampleMemCacheMain = nullptr; // for main thread:collecttionsymbol 3148f512ceSopenharmony_ciconstexpr size_t SAMPLE_CACHE_SIZE = 4 * 1024; 3248f512ceSopenharmony_ci 3348f512ceSopenharmony_cistd::unique_ptr<PerfEventRecord> GetPerfEventRecord(const int type, uint8_t *p, 3448f512ceSopenharmony_ci const perf_event_attr &attr) 3548f512ceSopenharmony_ci{ 3648f512ceSopenharmony_ci HLOG_ASSERT(p); 3748f512ceSopenharmony_ci uint8_t *data = p; 3848f512ceSopenharmony_ci 3948f512ceSopenharmony_ci // check kernel 4048f512ceSopenharmony_ci switch (type) { 4148f512ceSopenharmony_ci case PERF_RECORD_SAMPLE: 4248f512ceSopenharmony_ci return std::make_unique<PerfRecordSample>(data, attr); 4348f512ceSopenharmony_ci case PERF_RECORD_MMAP: 4448f512ceSopenharmony_ci return std::make_unique<PerfRecordMmap>(data); 4548f512ceSopenharmony_ci case PERF_RECORD_MMAP2: 4648f512ceSopenharmony_ci return std::make_unique<PerfRecordMmap2>(data); 4748f512ceSopenharmony_ci case PERF_RECORD_LOST: 4848f512ceSopenharmony_ci return std::make_unique<PerfRecordLost>(data); 4948f512ceSopenharmony_ci case PERF_RECORD_COMM: 5048f512ceSopenharmony_ci return std::make_unique<PerfRecordComm>(data); 5148f512ceSopenharmony_ci case PERF_RECORD_EXIT: 5248f512ceSopenharmony_ci return std::make_unique<PerfRecordExit>(data); 5348f512ceSopenharmony_ci case PERF_RECORD_THROTTLE: 5448f512ceSopenharmony_ci return std::make_unique<PerfRecordThrottle>(data); 5548f512ceSopenharmony_ci case PERF_RECORD_UNTHROTTLE: 5648f512ceSopenharmony_ci return std::make_unique<PerfRecordUnthrottle>(data); 5748f512ceSopenharmony_ci case PERF_RECORD_FORK: 5848f512ceSopenharmony_ci return std::make_unique<PerfRecordFork>(data); 5948f512ceSopenharmony_ci case PERF_RECORD_READ: 6048f512ceSopenharmony_ci return std::make_unique<PerfRecordRead>(data); 6148f512ceSopenharmony_ci case PERF_RECORD_AUX: 6248f512ceSopenharmony_ci return std::make_unique<PerfRecordAux>(data); 6348f512ceSopenharmony_ci case PERF_RECORD_AUXTRACE: 6448f512ceSopenharmony_ci return std::make_unique<PerfRecordAuxtrace>(data); 6548f512ceSopenharmony_ci case PERF_RECORD_ITRACE_START: 6648f512ceSopenharmony_ci return std::make_unique<PerfRecordItraceStart>(data); 6748f512ceSopenharmony_ci case PERF_RECORD_LOST_SAMPLES: 6848f512ceSopenharmony_ci return std::make_unique<PerfRecordLostSamples>(data); 6948f512ceSopenharmony_ci case PERF_RECORD_SWITCH: 7048f512ceSopenharmony_ci return std::make_unique<PerfRecordSwitch>(data); 7148f512ceSopenharmony_ci case PERF_RECORD_SWITCH_CPU_WIDE: 7248f512ceSopenharmony_ci return std::make_unique<PerfRecordSwitchCpuWide>(data); 7348f512ceSopenharmony_ci default: 7448f512ceSopenharmony_ci HLOGE("unknown record type %d\n", type); 7548f512ceSopenharmony_ci return nullptr; 7648f512ceSopenharmony_ci } 7748f512ceSopenharmony_ci} 7848f512ceSopenharmony_ci 7948f512ceSopenharmony_cistd::unique_ptr<PerfEventRecord> GetPerfSampleFromCache(const int type, uint8_t *p, 8048f512ceSopenharmony_ci const perf_event_attr &attr) 8148f512ceSopenharmony_ci{ 8248f512ceSopenharmony_ci HLOG_ASSERT(p); 8348f512ceSopenharmony_ci uint8_t *data = p; 8448f512ceSopenharmony_ci 8548f512ceSopenharmony_ci if (type == PERF_RECORD_SAMPLE) { 8648f512ceSopenharmony_ci if (g_sampleMemCache != nullptr) { 8748f512ceSopenharmony_ci memset_s(g_sampleMemCache, SAMPLE_CACHE_SIZE, 0, SAMPLE_CACHE_SIZE); 8848f512ceSopenharmony_ci return std::unique_ptr<PerfEventRecord>(new (g_sampleMemCache) PerfRecordSample(data, attr)); 8948f512ceSopenharmony_ci } else { 9048f512ceSopenharmony_ci g_sampleMemCache = std::malloc(SAMPLE_CACHE_SIZE); 9148f512ceSopenharmony_ci memset_s(g_sampleMemCache, SAMPLE_CACHE_SIZE, 0, SAMPLE_CACHE_SIZE); 9248f512ceSopenharmony_ci return std::unique_ptr<PerfEventRecord>(new (g_sampleMemCache) PerfRecordSample(data, attr)); 9348f512ceSopenharmony_ci } 9448f512ceSopenharmony_ci } 9548f512ceSopenharmony_ci return GetPerfEventRecord(type, p, attr); 9648f512ceSopenharmony_ci} 9748f512ceSopenharmony_ci 9848f512ceSopenharmony_cistd::unique_ptr<PerfEventRecord> GetPerfSampleFromCacheMain(const int type, uint8_t *p, 9948f512ceSopenharmony_ci const perf_event_attr &attr) 10048f512ceSopenharmony_ci{ 10148f512ceSopenharmony_ci HLOG_ASSERT(p); 10248f512ceSopenharmony_ci uint8_t *data = p; 10348f512ceSopenharmony_ci 10448f512ceSopenharmony_ci if (type == PERF_RECORD_SAMPLE) { 10548f512ceSopenharmony_ci if (g_sampleMemCacheMain != nullptr) { 10648f512ceSopenharmony_ci memset_s(g_sampleMemCacheMain, SAMPLE_CACHE_SIZE, 0, SAMPLE_CACHE_SIZE); 10748f512ceSopenharmony_ci return std::unique_ptr<PerfEventRecord>(new (g_sampleMemCacheMain) PerfRecordSample(data, attr)); 10848f512ceSopenharmony_ci } else { 10948f512ceSopenharmony_ci g_sampleMemCacheMain = std::malloc(SAMPLE_CACHE_SIZE); 11048f512ceSopenharmony_ci memset_s(g_sampleMemCacheMain, SAMPLE_CACHE_SIZE, 0, SAMPLE_CACHE_SIZE); 11148f512ceSopenharmony_ci return std::unique_ptr<PerfEventRecord>(new (g_sampleMemCacheMain) PerfRecordSample(data, attr)); 11248f512ceSopenharmony_ci } 11348f512ceSopenharmony_ci } 11448f512ceSopenharmony_ci return GetPerfEventRecord(type, p, attr); 11548f512ceSopenharmony_ci} 11648f512ceSopenharmony_ci 11748f512ceSopenharmony_citemplate<typename T> 11848f512ceSopenharmony_ciinline void PushToBinary(bool condition, uint8_t *&p, const T &v) 11948f512ceSopenharmony_ci{ 12048f512ceSopenharmony_ci if (condition) { 12148f512ceSopenharmony_ci *(reinterpret_cast<T *>(p)) = v; 12248f512ceSopenharmony_ci p += sizeof(T); 12348f512ceSopenharmony_ci } 12448f512ceSopenharmony_ci} 12548f512ceSopenharmony_ci 12648f512ceSopenharmony_citemplate<typename T1, typename T2> 12748f512ceSopenharmony_ciinline void PushToBinary2(bool condition, uint8_t *&p, const T1 &v1, const T2 &v2) 12848f512ceSopenharmony_ci{ 12948f512ceSopenharmony_ci if (condition) { 13048f512ceSopenharmony_ci *(reinterpret_cast<T1 *>(p)) = v1; 13148f512ceSopenharmony_ci p += sizeof(T1); 13248f512ceSopenharmony_ci *(reinterpret_cast<T2 *>(p)) = v2; 13348f512ceSopenharmony_ci p += sizeof(T2); 13448f512ceSopenharmony_ci } 13548f512ceSopenharmony_ci} 13648f512ceSopenharmony_ci 13748f512ceSopenharmony_citemplate<typename T> 13848f512ceSopenharmony_ciinline void PopFromBinary(bool condition, uint8_t *&p, T &v) 13948f512ceSopenharmony_ci{ 14048f512ceSopenharmony_ci if (condition) { 14148f512ceSopenharmony_ci v = *(reinterpret_cast<const T *>(p)); 14248f512ceSopenharmony_ci p += sizeof(T); 14348f512ceSopenharmony_ci } 14448f512ceSopenharmony_ci} 14548f512ceSopenharmony_ci 14648f512ceSopenharmony_citemplate<typename T1, typename T2> 14748f512ceSopenharmony_ciinline void PopFromBinary2(bool condition, uint8_t *&p, T1 &v1, T2 &v2) 14848f512ceSopenharmony_ci{ 14948f512ceSopenharmony_ci if (condition) { 15048f512ceSopenharmony_ci v1 = *(reinterpret_cast<const T1 *>(p)); 15148f512ceSopenharmony_ci p += sizeof(T1); 15248f512ceSopenharmony_ci v2 = *(reinterpret_cast<const T2 *>(p)); 15348f512ceSopenharmony_ci p += sizeof(T2); 15448f512ceSopenharmony_ci } 15548f512ceSopenharmony_ci} 15648f512ceSopenharmony_ci 15748f512ceSopenharmony_ci// PerfEventRecord 15848f512ceSopenharmony_ciPerfEventRecord::PerfEventRecord(perf_event_type type, bool inKernel, const std::string &name) 15948f512ceSopenharmony_ci : name_(name) 16048f512ceSopenharmony_ci{ 16148f512ceSopenharmony_ci header.type = type; 16248f512ceSopenharmony_ci header.misc = inKernel ? PERF_RECORD_MISC_KERNEL : PERF_RECORD_MISC_USER; 16348f512ceSopenharmony_ci header.size = sizeof(header); 16448f512ceSopenharmony_ci} 16548f512ceSopenharmony_ci 16648f512ceSopenharmony_ciPerfEventRecord::PerfEventRecord(perf_event_hiperf_ext_type type, const std::string &name) 16748f512ceSopenharmony_ci : name_(name) 16848f512ceSopenharmony_ci{ 16948f512ceSopenharmony_ci header.type = type; 17048f512ceSopenharmony_ci header.misc = PERF_RECORD_MISC_USER; 17148f512ceSopenharmony_ci header.size = sizeof(header); 17248f512ceSopenharmony_ci} 17348f512ceSopenharmony_ci 17448f512ceSopenharmony_ciPerfEventRecord::PerfEventRecord(uint8_t *p, const std::string &name) : name_(name) 17548f512ceSopenharmony_ci{ 17648f512ceSopenharmony_ci if (p == nullptr) { 17748f512ceSopenharmony_ci header.type = PERF_RECORD_MMAP; 17848f512ceSopenharmony_ci header.misc = PERF_RECORD_MISC_USER; 17948f512ceSopenharmony_ci header.size = 0; 18048f512ceSopenharmony_ci return; 18148f512ceSopenharmony_ci } 18248f512ceSopenharmony_ci header = *(reinterpret_cast<perf_event_header *>(p)); 18348f512ceSopenharmony_ci} 18448f512ceSopenharmony_ci 18548f512ceSopenharmony_civoid PerfEventRecord::GetHeaderBinary(std::vector<uint8_t> &buf) const 18648f512ceSopenharmony_ci{ 18748f512ceSopenharmony_ci if (buf.size() < GetHeaderSize()) { 18848f512ceSopenharmony_ci buf.resize(GetHeaderSize()); 18948f512ceSopenharmony_ci } 19048f512ceSopenharmony_ci uint8_t *p = buf.data(); 19148f512ceSopenharmony_ci *(reinterpret_cast<perf_event_header *>(p)) = header; 19248f512ceSopenharmony_ci} 19348f512ceSopenharmony_ci 19448f512ceSopenharmony_civoid PerfEventRecord::Dump(int indent, std::string outputFilename, FILE *outputDump) const 19548f512ceSopenharmony_ci{ 19648f512ceSopenharmony_ci if (outputDump != nullptr) { 19748f512ceSopenharmony_ci g_outputDump = outputDump; 19848f512ceSopenharmony_ci } else if (!outputFilename.empty() && g_outputDump == nullptr) { 19948f512ceSopenharmony_ci std::string resolvedPath = CanonicalizeSpecPath(outputFilename.c_str()); 20048f512ceSopenharmony_ci g_outputDump = fopen(resolvedPath.c_str(), "w"); 20148f512ceSopenharmony_ci if (g_outputDump == nullptr) { 20248f512ceSopenharmony_ci printf("unable open file to '%s' because '%d'\n", outputFilename.c_str(), errno); 20348f512ceSopenharmony_ci return; 20448f512ceSopenharmony_ci } 20548f512ceSopenharmony_ci } 20648f512ceSopenharmony_ci PRINT_INDENT(indent, "\n"); 20748f512ceSopenharmony_ci PRINT_INDENT(indent, "record %s: type %u, misc %u, size %zu\n", GetName().c_str(), GetType(), 20848f512ceSopenharmony_ci GetMisc(), GetSize()); 20948f512ceSopenharmony_ci DumpData(indent + 1); 21048f512ceSopenharmony_ci} 21148f512ceSopenharmony_ci 21248f512ceSopenharmony_civoid PerfEventRecord::DumpLog(const std::string &prefix) const 21348f512ceSopenharmony_ci{ 21448f512ceSopenharmony_ci HLOGV("%s: record %s: type %u, misc %u, size %zu\n", prefix.c_str(), GetName().c_str(), 21548f512ceSopenharmony_ci GetType(), GetMisc(), GetSize()); 21648f512ceSopenharmony_ci} 21748f512ceSopenharmony_ci 21848f512ceSopenharmony_cistd::vector<u64> PerfRecordSample::ips_ = {}; 21948f512ceSopenharmony_cistd::vector<DfxFrame> PerfRecordSample::callFrames_ = {}; 22048f512ceSopenharmony_cistd::vector<pid_t> PerfRecordSample::serverPidMap_ = {}; 22148f512ceSopenharmony_ci 22248f512ceSopenharmony_ciPerfRecordAuxtrace::PerfRecordAuxtrace(uint8_t *p) : PerfEventRecord(p, "auxtrace") 22348f512ceSopenharmony_ci{ 22448f512ceSopenharmony_ci if (header.size >= sizeof(header)) { 22548f512ceSopenharmony_ci size_t copySize = header.size - sizeof(header); 22648f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 22748f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 22848f512ceSopenharmony_ci } 22948f512ceSopenharmony_ci } else { 23048f512ceSopenharmony_ci HLOGE("PerfRecordAuxtrace retren failed !!!"); 23148f512ceSopenharmony_ci } 23248f512ceSopenharmony_ci rawData_ = p + header.size; 23348f512ceSopenharmony_ci} 23448f512ceSopenharmony_ci 23548f512ceSopenharmony_ciPerfRecordAuxtrace::PerfRecordAuxtrace(u64 size, u64 offset, u64 reference, u32 idx, u32 tid, u32 cpu, u32 pid) 23648f512ceSopenharmony_ci : PerfEventRecord(PERF_RECORD_AUXTRACE, "auxtrace") 23748f512ceSopenharmony_ci{ 23848f512ceSopenharmony_ci data_.size = size; 23948f512ceSopenharmony_ci data_.offset = offset; 24048f512ceSopenharmony_ci data_.reference = reference; 24148f512ceSopenharmony_ci data_.idx = idx; 24248f512ceSopenharmony_ci data_.tid = tid; 24348f512ceSopenharmony_ci data_.cpu = cpu; 24448f512ceSopenharmony_ci data_.reserved__ = pid; 24548f512ceSopenharmony_ci 24648f512ceSopenharmony_ci header.size = sizeof(header) + sizeof(data_); 24748f512ceSopenharmony_ci} 24848f512ceSopenharmony_ci 24948f512ceSopenharmony_cibool PerfRecordAuxtrace::GetBinary1(std::vector<uint8_t> &buf) const 25048f512ceSopenharmony_ci{ 25148f512ceSopenharmony_ci if (buf.size() < header.size) { 25248f512ceSopenharmony_ci buf.resize(header.size); 25348f512ceSopenharmony_ci } 25448f512ceSopenharmony_ci 25548f512ceSopenharmony_ci GetHeaderBinary(buf); 25648f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 25748f512ceSopenharmony_ci 25848f512ceSopenharmony_ci size_t copySize = header.size - GetHeaderSize(); 25948f512ceSopenharmony_ci if (memcpy_s(p, sizeof(data_), reinterpret_cast<const uint8_t *>(&data_), copySize) != 0) { 26048f512ceSopenharmony_ci HLOGE("memcpy_s return failed"); 26148f512ceSopenharmony_ci return false; 26248f512ceSopenharmony_ci } 26348f512ceSopenharmony_ci return true; 26448f512ceSopenharmony_ci} 26548f512ceSopenharmony_ci 26648f512ceSopenharmony_cibool PerfRecordAuxtrace::GetBinary(std::vector<uint8_t> &buf) const 26748f512ceSopenharmony_ci{ 26848f512ceSopenharmony_ci if (buf.size() < GetSize()) { 26948f512ceSopenharmony_ci buf.resize(GetSize()); 27048f512ceSopenharmony_ci } 27148f512ceSopenharmony_ci 27248f512ceSopenharmony_ci GetHeaderBinary(buf); 27348f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 27448f512ceSopenharmony_ci 27548f512ceSopenharmony_ci size_t copySize = header.size - GetHeaderSize(); 27648f512ceSopenharmony_ci if (memcpy_s(p, sizeof(data_), reinterpret_cast<const uint8_t *>(&data_), copySize) != 0) { 27748f512ceSopenharmony_ci HLOGE("memcpy_s return failed"); 27848f512ceSopenharmony_ci return false; 27948f512ceSopenharmony_ci } 28048f512ceSopenharmony_ci p += header.size - GetHeaderSize(); 28148f512ceSopenharmony_ci if (memcpy_s(p, data_.size, static_cast<uint8_t *>(rawData_), data_.size) != 0) { 28248f512ceSopenharmony_ci HLOGE("memcpy_s return failed"); 28348f512ceSopenharmony_ci return false; 28448f512ceSopenharmony_ci } 28548f512ceSopenharmony_ci return true; 28648f512ceSopenharmony_ci} 28748f512ceSopenharmony_ci 28848f512ceSopenharmony_civoid PerfRecordAuxtrace::DumpData(int indent) const 28948f512ceSopenharmony_ci{ 29048f512ceSopenharmony_ci PRINT_INDENT(indent, "size 0x%llx, offset 0x%llx, reference 0x%llx, idx %u, tid %u, cpu %u, pid %u\n", 29148f512ceSopenharmony_ci data_.size, data_.offset, data_.reference, data_.idx, data_.tid, data_.cpu, data_.reserved__); 29248f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos 29348f512ceSopenharmony_ci if (!SpeDumpRawData(rawData_, data_.size, indent, g_outputDump)) { 29448f512ceSopenharmony_ci HLOGE("SpeDumpRawData failed"); 29548f512ceSopenharmony_ci } 29648f512ceSopenharmony_ci#endif 29748f512ceSopenharmony_ci} 29848f512ceSopenharmony_ci 29948f512ceSopenharmony_civoid PerfRecordAuxtrace::DumpLog(const std::string &prefix) const 30048f512ceSopenharmony_ci{ 30148f512ceSopenharmony_ci HLOGV("size %llu, offset 0x%llx, reference 0x%llx, idx %u, tid %u, cpu %u\n", 30248f512ceSopenharmony_ci data_.size, data_.offset, data_.reference, data_.idx, data_.tid, data_.cpu); 30348f512ceSopenharmony_ci} 30448f512ceSopenharmony_ci 30548f512ceSopenharmony_cisize_t PerfRecordAuxtrace::GetSize() const 30648f512ceSopenharmony_ci{ 30748f512ceSopenharmony_ci return header.size + data_.size; 30848f512ceSopenharmony_ci} 30948f512ceSopenharmony_ci 31048f512ceSopenharmony_civoid PerfRecordSample::DumpLog(const std::string &prefix) const 31148f512ceSopenharmony_ci{ 31248f512ceSopenharmony_ci HLOGV("%s: SAMPLE: id= %llu size %d pid %u tid %u ips %llu regs %llu, stacks %llu time %llu", 31348f512ceSopenharmony_ci prefix.c_str(), data_.sample_id, header.size, data_.pid, data_.tid, data_.nr, 31448f512ceSopenharmony_ci data_.reg_nr, data_.dyn_size, data_.time); 31548f512ceSopenharmony_ci} 31648f512ceSopenharmony_ci 31748f512ceSopenharmony_civoid PerfRecordSample::RecoverCallStack() 31848f512ceSopenharmony_ci{ 31948f512ceSopenharmony_ci data_.ips = ips_.data(); 32048f512ceSopenharmony_ci data_.nr = ips_.size(); 32148f512ceSopenharmony_ci removeStack_ = true; 32248f512ceSopenharmony_ci} 32348f512ceSopenharmony_ci 32448f512ceSopenharmony_civoid PerfRecordSample::ReplaceWithCallStack(size_t originalSize) 32548f512ceSopenharmony_ci{ 32648f512ceSopenharmony_ci // first we check if we have some user unwind stack need to merge ? 32748f512ceSopenharmony_ci if (callFrames_.size() != 0) { 32848f512ceSopenharmony_ci // when we have some kernel ips , we cp it first 32948f512ceSopenharmony_ci // new size is user call frames + kernel call frames 33048f512ceSopenharmony_ci // + PERF_CONTEXT_USER(last + 1) + expand mark(also PERF_CONTEXT_USER) 33148f512ceSopenharmony_ci const unsigned int perfContextSize = 2; 33248f512ceSopenharmony_ci ips_.reserve(data_.nr + callFrames_.size() + perfContextSize); 33348f512ceSopenharmony_ci if (data_.nr > 0) { 33448f512ceSopenharmony_ci ips_.assign(data_.ips, data_.ips + data_.nr); 33548f512ceSopenharmony_ci } 33648f512ceSopenharmony_ci // add user context mark 33748f512ceSopenharmony_ci ips_.emplace_back(PERF_CONTEXT_USER); 33848f512ceSopenharmony_ci // we also need make a expand mark just for debug only 33948f512ceSopenharmony_ci const size_t beginIpsSize = ips_.size(); 34048f512ceSopenharmony_ci bool ret = std::all_of(callFrames_.begin(), callFrames_.end(), [&](const DfxFrame &frame) { 34148f512ceSopenharmony_ci ips_.emplace_back(frame.pc); 34248f512ceSopenharmony_ci if (originalSize != 0 and (originalSize != callFrames_.size()) and 34348f512ceSopenharmony_ci ips_.size() == (originalSize + beginIpsSize)) { 34448f512ceSopenharmony_ci // just for debug 34548f512ceSopenharmony_ci // so we can see which frame begin is expand call frames 34648f512ceSopenharmony_ci ips_.emplace_back(PERF_CONTEXT_USER); 34748f512ceSopenharmony_ci } 34848f512ceSopenharmony_ci return true; 34948f512ceSopenharmony_ci }); 35048f512ceSopenharmony_ci if (ret) { 35148f512ceSopenharmony_ci HLOGV("combed %zu", callFrames_.size()); 35248f512ceSopenharmony_ci } else { 35348f512ceSopenharmony_ci HLOGV("failed to combed %zu", callFrames_.size()); 35448f512ceSopenharmony_ci } 35548f512ceSopenharmony_ci 35648f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_REGS_USER) { 35748f512ceSopenharmony_ci header.size -= data_.reg_nr * sizeof(u64); 35848f512ceSopenharmony_ci data_.reg_nr = 0; 35948f512ceSopenharmony_ci data_.user_abi = 0; 36048f512ceSopenharmony_ci } 36148f512ceSopenharmony_ci 36248f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_STACK_USER) { 36348f512ceSopenharmony_ci // 1. remove the user stack 36448f512ceSopenharmony_ci header.size -= data_.stack_size; 36548f512ceSopenharmony_ci header.size -= sizeof(data_.dyn_size); 36648f512ceSopenharmony_ci 36748f512ceSopenharmony_ci // 2. clean the size 36848f512ceSopenharmony_ci data_.stack_size = 0; 36948f512ceSopenharmony_ci data_.dyn_size = 0; 37048f512ceSopenharmony_ci } 37148f512ceSopenharmony_ci 37248f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_CALLCHAIN) { 37348f512ceSopenharmony_ci HLOGV("ips change from %llu -> %zu", data_.nr, ips_.size()); 37448f512ceSopenharmony_ci 37548f512ceSopenharmony_ci // 3. remove the nr size 37648f512ceSopenharmony_ci header.size -= data_.nr * sizeof(u64); 37748f512ceSopenharmony_ci 37848f512ceSopenharmony_ci // 4. add new nr size 37948f512ceSopenharmony_ci data_.nr = ips_.size(); 38048f512ceSopenharmony_ci header.size += data_.nr * sizeof(u64); 38148f512ceSopenharmony_ci 38248f512ceSopenharmony_ci // 5. change ips potin to our ips array and hold it. 38348f512ceSopenharmony_ci data_.ips = ips_.data(); 38448f512ceSopenharmony_ci } 38548f512ceSopenharmony_ci } else { 38648f512ceSopenharmony_ci // nothing need change 38748f512ceSopenharmony_ci return; 38848f512ceSopenharmony_ci } 38948f512ceSopenharmony_ci} 39048f512ceSopenharmony_ci 39148f512ceSopenharmony_ciPerfRecordSample::PerfRecordSample(uint8_t *p, const perf_event_attr &attr) 39248f512ceSopenharmony_ci : PerfEventRecord(p, "sample") 39348f512ceSopenharmony_ci{ 39448f512ceSopenharmony_ci if (p == nullptr) { 39548f512ceSopenharmony_ci HLOG_ASSERT(p); 39648f512ceSopenharmony_ci return; 39748f512ceSopenharmony_ci } 39848f512ceSopenharmony_ci // clear the static vector data 39948f512ceSopenharmony_ci Clean(); 40048f512ceSopenharmony_ci sampleType_ = attr.sample_type; 40148f512ceSopenharmony_ci 40248f512ceSopenharmony_ci uint8_t *start = p; 40348f512ceSopenharmony_ci 40448f512ceSopenharmony_ci p += sizeof(header); 40548f512ceSopenharmony_ci 40648f512ceSopenharmony_ci // parse record according SAMPLE_TYPE 40748f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_IDENTIFIER, p, data_.sample_id); 40848f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_IP, p, data_.ip); 40948f512ceSopenharmony_ci PopFromBinary2(sampleType_ & PERF_SAMPLE_TID, p, data_.pid, data_.tid); 41048f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_TIME, p, data_.time); 41148f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_ADDR, p, data_.addr); 41248f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_ID, p, data_.id); 41348f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_STREAM_ID, p, data_.stream_id); 41448f512ceSopenharmony_ci PopFromBinary2(sampleType_ & PERF_SAMPLE_CPU, p, data_.cpu, data_.res); 41548f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_PERIOD, p, data_.period); 41648f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_CALLCHAIN, p, data_.nr); 41748f512ceSopenharmony_ci if (data_.nr > 0) { 41848f512ceSopenharmony_ci // the pointer is from input(p), require caller keep input(p) with *this together 41948f512ceSopenharmony_ci // think it in next time 42048f512ceSopenharmony_ci data_.ips = reinterpret_cast<u64 *>(p); 42148f512ceSopenharmony_ci p += data_.nr * sizeof(u64); 42248f512ceSopenharmony_ci } 42348f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_RAW, p, data_.raw_size); 42448f512ceSopenharmony_ci if (data_.raw_size > 0) { 42548f512ceSopenharmony_ci data_.raw_data = p; 42648f512ceSopenharmony_ci p += data_.raw_size * sizeof(u8); 42748f512ceSopenharmony_ci } 42848f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_BRANCH_STACK, p, data_.bnr); 42948f512ceSopenharmony_ci if (data_.bnr > 0) { 43048f512ceSopenharmony_ci data_.lbr = reinterpret_cast<PerfBranchEntry *>(p); 43148f512ceSopenharmony_ci p += data_.bnr * sizeof(PerfBranchEntry); 43248f512ceSopenharmony_ci } 43348f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_REGS_USER, p, data_.user_abi); 43448f512ceSopenharmony_ci if (data_.user_abi > 0) { 43548f512ceSopenharmony_ci data_.reg_mask = attr.sample_regs_user; 43648f512ceSopenharmony_ci data_.reg_nr = __builtin_popcountll(data_.reg_mask); 43748f512ceSopenharmony_ci data_.user_regs = reinterpret_cast<u64 *>(p); 43848f512ceSopenharmony_ci p += data_.reg_nr * sizeof(u64); 43948f512ceSopenharmony_ci } 44048f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_SERVER_PID, p, data_.server_nr); 44148f512ceSopenharmony_ci if (data_.server_nr > 0) { 44248f512ceSopenharmony_ci data_.server_pids = reinterpret_cast<u64 *>(p); 44348f512ceSopenharmony_ci p += data_.server_nr * sizeof(u64); 44448f512ceSopenharmony_ci } 44548f512ceSopenharmony_ci PopFromBinary(sampleType_ & PERF_SAMPLE_STACK_USER, p, data_.stack_size); 44648f512ceSopenharmony_ci if (data_.stack_size > 0) { 44748f512ceSopenharmony_ci data_.stack_data = p; 44848f512ceSopenharmony_ci p += data_.stack_size; 44948f512ceSopenharmony_ci PopFromBinary(true, p, data_.dyn_size); 45048f512ceSopenharmony_ci } 45148f512ceSopenharmony_ci uint32_t remain = header.size - (p - start); 45248f512ceSopenharmony_ci if (data_.nr == 0 && dumpRemoveStack_ && remain == sizeof(stackId_)) { 45348f512ceSopenharmony_ci PopFromBinary(true, p, stackId_.value); 45448f512ceSopenharmony_ci } 45548f512ceSopenharmony_ci} 45648f512ceSopenharmony_ci 45748f512ceSopenharmony_cibool PerfRecordSample::GetBinary(std::vector<uint8_t> &buf) const 45848f512ceSopenharmony_ci{ 45948f512ceSopenharmony_ci if (buf.size() < GetSize()) { 46048f512ceSopenharmony_ci buf.resize(GetSize()); 46148f512ceSopenharmony_ci } 46248f512ceSopenharmony_ci 46348f512ceSopenharmony_ci GetHeaderBinary(buf); 46448f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 46548f512ceSopenharmony_ci 46648f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_IDENTIFIER, p, data_.sample_id); 46748f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_IP, p, data_.ip); 46848f512ceSopenharmony_ci PushToBinary2(sampleType_ & PERF_SAMPLE_TID, p, data_.pid, data_.tid); 46948f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_TIME, p, data_.time); 47048f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_ADDR, p, data_.addr); 47148f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_ID, p, data_.id); 47248f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_STREAM_ID, p, data_.stream_id); 47348f512ceSopenharmony_ci PushToBinary2(sampleType_ & PERF_SAMPLE_CPU, p, data_.cpu, data_.res); 47448f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_PERIOD, p, data_.period); 47548f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_CALLCHAIN, p, data_.nr); 47648f512ceSopenharmony_ci if (data_.nr > 0 && !removeStack_) { 47748f512ceSopenharmony_ci std::copy(data_.ips + skipKernel_, data_.ips + data_.nr + skipKernel_, 47848f512ceSopenharmony_ci reinterpret_cast<u64 *>(p)); 47948f512ceSopenharmony_ci p += data_.nr * sizeof(u64); 48048f512ceSopenharmony_ci } 48148f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_RAW, p, data_.raw_size); 48248f512ceSopenharmony_ci if (data_.raw_size > 0) { 48348f512ceSopenharmony_ci std::copy(data_.raw_data, data_.raw_data + data_.raw_size, p); 48448f512ceSopenharmony_ci p += data_.raw_size * sizeof(u8); 48548f512ceSopenharmony_ci } 48648f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_BRANCH_STACK, p, data_.bnr); 48748f512ceSopenharmony_ci if (data_.bnr > 0) { 48848f512ceSopenharmony_ci std::copy(data_.lbr, data_.lbr + data_.bnr, reinterpret_cast<PerfBranchEntry *>(p)); 48948f512ceSopenharmony_ci p += data_.bnr * sizeof(PerfBranchEntry); 49048f512ceSopenharmony_ci } 49148f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_REGS_USER, p, data_.user_abi); 49248f512ceSopenharmony_ci if (data_.user_abi > 0 && data_.reg_nr > 0) { 49348f512ceSopenharmony_ci std::copy(data_.user_regs, data_.user_regs + data_.reg_nr, reinterpret_cast<u64 *>(p)); 49448f512ceSopenharmony_ci p += data_.reg_nr * sizeof(u64); 49548f512ceSopenharmony_ci } 49648f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_SERVER_PID, p, data_.server_nr); 49748f512ceSopenharmony_ci if (data_.server_nr > 0) { 49848f512ceSopenharmony_ci std::copy(data_.server_pids + skipPid_, data_.server_pids + data_.server_nr + skipPid_, 49948f512ceSopenharmony_ci reinterpret_cast<u64 *>(p)); 50048f512ceSopenharmony_ci p += data_.server_nr * sizeof(u64); 50148f512ceSopenharmony_ci } 50248f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_STACK_USER, p, data_.stack_size); 50348f512ceSopenharmony_ci if (data_.stack_size > 0) { 50448f512ceSopenharmony_ci std::copy(data_.stack_data, data_.stack_data + data_.stack_size, p); 50548f512ceSopenharmony_ci p += data_.stack_size * sizeof(u8); 50648f512ceSopenharmony_ci PushToBinary(true, p, data_.dyn_size); 50748f512ceSopenharmony_ci } 50848f512ceSopenharmony_ci PushToBinary(removeStack_, p, stackId_.value); 50948f512ceSopenharmony_ci return true; 51048f512ceSopenharmony_ci} 51148f512ceSopenharmony_ci 51248f512ceSopenharmony_civoid PerfRecordSample::DumpData(int indent) const 51348f512ceSopenharmony_ci{ 51448f512ceSopenharmony_ci PRINT_INDENT(indent, "sample_type: 0x%" PRIx64 "\n", sampleType_); 51548f512ceSopenharmony_ci 51648f512ceSopenharmony_ci // dump record according sampleType 51748f512ceSopenharmony_ci if (sampleType_ & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER)) { 51848f512ceSopenharmony_ci PRINT_INDENT(indent, "ID %" PRIu64 "\n", static_cast<uint64_t>(data_.sample_id)); 51948f512ceSopenharmony_ci } 52048f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_IP) { 52148f512ceSopenharmony_ci PRINT_INDENT(indent, "ip %llx\n", data_.ip); 52248f512ceSopenharmony_ci } 52348f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_TID) { 52448f512ceSopenharmony_ci PRINT_INDENT(indent, "pid %u, tid %u\n", data_.pid, data_.tid); 52548f512ceSopenharmony_ci } 52648f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_TIME) { 52748f512ceSopenharmony_ci PRINT_INDENT(indent, "time %llu\n", data_.time); 52848f512ceSopenharmony_ci } 52948f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_ADDR) { 53048f512ceSopenharmony_ci PRINT_INDENT(indent, "addr %p\n", reinterpret_cast<void *>(data_.addr)); 53148f512ceSopenharmony_ci } 53248f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_STREAM_ID) { 53348f512ceSopenharmony_ci PRINT_INDENT(indent, "stream_id %" PRIu64 "\n", static_cast<uint64_t>(data_.stream_id)); 53448f512ceSopenharmony_ci } 53548f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_CPU) { 53648f512ceSopenharmony_ci PRINT_INDENT(indent, "cpu %u, res %u\n", data_.cpu, data_.res); 53748f512ceSopenharmony_ci } 53848f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_PERIOD) { 53948f512ceSopenharmony_ci PRINT_INDENT(indent, "period %" PRIu64 "\n", static_cast<uint64_t>(data_.period)); 54048f512ceSopenharmony_ci } 54148f512ceSopenharmony_ci if (stackId_.section.id > 0) { 54248f512ceSopenharmony_ci PRINT_INDENT(indent, "stackid %" PRIu64 "\n", static_cast<uint64_t>(stackId_.section.id)); 54348f512ceSopenharmony_ci } 54448f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_CALLCHAIN) { 54548f512ceSopenharmony_ci bool userContext = false; 54648f512ceSopenharmony_ci PRINT_INDENT(indent, "callchain nr=%lld\n", data_.nr); 54748f512ceSopenharmony_ci for (uint64_t i = 0; i < data_.nr; ++i) { 54848f512ceSopenharmony_ci std::string_view supplement = ""; 54948f512ceSopenharmony_ci if ((sampleType_ & PERF_SAMPLE_STACK_USER) == 0 || data_.ips[i] != PERF_CONTEXT_USER) { 55048f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "0x%llx%s\n", data_.ips[i], supplement.data()); 55148f512ceSopenharmony_ci continue; 55248f512ceSopenharmony_ci } 55348f512ceSopenharmony_ci // is PERF_SAMPLE_STACK_USER type and is PERF_CONTEXT_USER 55448f512ceSopenharmony_ci if (!userContext) { 55548f512ceSopenharmony_ci userContext = true; 55648f512ceSopenharmony_ci supplement = " <unwind callstack>"; 55748f512ceSopenharmony_ci } else { 55848f512ceSopenharmony_ci supplement = " <expand callstack>"; 55948f512ceSopenharmony_ci } 56048f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "0x%llx%s\n", data_.ips[i], supplement.data()); 56148f512ceSopenharmony_ci } 56248f512ceSopenharmony_ci } 56348f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_RAW) { 56448f512ceSopenharmony_ci PRINT_INDENT(indent, "raw size=%u\n", data_.raw_size); 56548f512ceSopenharmony_ci const uint32_t *data = reinterpret_cast<const uint32_t *>(data_.raw_data); 56648f512ceSopenharmony_ci size_t size = data_.raw_size / sizeof(uint32_t); 56748f512ceSopenharmony_ci for (size_t i = 0; i < size; ++i) { 56848f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "0x%08x (%x)\n", data[i], data[i]); 56948f512ceSopenharmony_ci } 57048f512ceSopenharmony_ci } 57148f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_BRANCH_STACK) { 57248f512ceSopenharmony_ci PRINT_INDENT(indent, "branch_stack nr=%lld\n", data_.bnr); 57348f512ceSopenharmony_ci for (uint64_t i = 0; i < data_.bnr; ++i) { 57448f512ceSopenharmony_ci auto &item = data_.lbr[i]; 57548f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "from 0x%llx, to 0x%llx, flags 0x%llx\n", item.from, item.to, item.flags); 57648f512ceSopenharmony_ci } 57748f512ceSopenharmony_ci } 57848f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_REGS_USER) { 57948f512ceSopenharmony_ci PRINT_INDENT(indent, "user regs: abi=%lld, reg_nr=%lld\n", data_.user_abi, data_.reg_nr); 58048f512ceSopenharmony_ci for (uint64_t i = 0; i < data_.reg_nr; ++i) { 58148f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "0x%llx\n", data_.user_regs[i]); 58248f512ceSopenharmony_ci } 58348f512ceSopenharmony_ci } 58448f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_SERVER_PID) { 58548f512ceSopenharmony_ci PRINT_INDENT(indent, "server nr=%lld\n", data_.server_nr); 58648f512ceSopenharmony_ci for (uint64_t i = 0; i < data_.server_nr; ++i) { 58748f512ceSopenharmony_ci PRINT_INDENT(indent + 1, "pid: %llu\n", data_.server_pids[i]); 58848f512ceSopenharmony_ci } 58948f512ceSopenharmony_ci } 59048f512ceSopenharmony_ci if (sampleType_ & PERF_SAMPLE_STACK_USER) { 59148f512ceSopenharmony_ci PRINT_INDENT(indent, "user stack: size %llu dyn_size %lld\n", data_.stack_size, 59248f512ceSopenharmony_ci data_.dyn_size); 59348f512ceSopenharmony_ci } 59448f512ceSopenharmony_ci} 59548f512ceSopenharmony_ci 59648f512ceSopenharmony_ciinline pid_t PerfRecordSample::GetPid() const 59748f512ceSopenharmony_ci{ 59848f512ceSopenharmony_ci return data_.pid; 59948f512ceSopenharmony_ci} 60048f512ceSopenharmony_ci 60148f512ceSopenharmony_civoid PerfRecordSample::Clean() 60248f512ceSopenharmony_ci{ 60348f512ceSopenharmony_ci ips_.clear(); 60448f512ceSopenharmony_ci callFrames_.clear(); 60548f512ceSopenharmony_ci serverPidMap_.clear(); 60648f512ceSopenharmony_ci} 60748f512ceSopenharmony_ci 60848f512ceSopenharmony_ciPerfRecordMmap::PerfRecordMmap(uint8_t *p) : PerfEventRecord(p, "mmap") 60948f512ceSopenharmony_ci{ 61048f512ceSopenharmony_ci size_t dataSize = GetSize(); 61148f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 61248f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 61348f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 61448f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 61548f512ceSopenharmony_ci } 61648f512ceSopenharmony_ci } else { 61748f512ceSopenharmony_ci HLOGE("PerfRecordMmap retren failed !!!"); 61848f512ceSopenharmony_ci } 61948f512ceSopenharmony_ci} 62048f512ceSopenharmony_ci 62148f512ceSopenharmony_ciPerfRecordMmap::PerfRecordMmap(bool inKernel, u32 pid, u32 tid, u64 addr, u64 len, u64 pgoff, 62248f512ceSopenharmony_ci const std::string &filename) 62348f512ceSopenharmony_ci : PerfEventRecord(PERF_RECORD_MMAP, inKernel, "mmap") 62448f512ceSopenharmony_ci{ 62548f512ceSopenharmony_ci data_.pid = pid; 62648f512ceSopenharmony_ci data_.tid = tid; 62748f512ceSopenharmony_ci data_.addr = addr; 62848f512ceSopenharmony_ci data_.len = len; 62948f512ceSopenharmony_ci data_.pgoff = pgoff; 63048f512ceSopenharmony_ci if (strncpy_s(data_.filename, KILO, filename.c_str(), filename.size()) != 0) { 63148f512ceSopenharmony_ci HLOGE("strncpy_s failed"); 63248f512ceSopenharmony_ci } 63348f512ceSopenharmony_ci 63448f512ceSopenharmony_ci header.size = sizeof(header) + sizeof(data_) - KILO + filename.size() + 1; 63548f512ceSopenharmony_ci} 63648f512ceSopenharmony_ci 63748f512ceSopenharmony_cibool PerfRecordMmap::GetBinary(std::vector<uint8_t> &buf) const 63848f512ceSopenharmony_ci{ 63948f512ceSopenharmony_ci if (buf.size() < GetSize()) { 64048f512ceSopenharmony_ci buf.resize(GetSize()); 64148f512ceSopenharmony_ci } 64248f512ceSopenharmony_ci 64348f512ceSopenharmony_ci GetHeaderBinary(buf); 64448f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 64548f512ceSopenharmony_ci 64648f512ceSopenharmony_ci // data_.filename[] is variable-length 64748f512ceSopenharmony_ci std::copy(reinterpret_cast<const uint8_t *>(&data_), 64848f512ceSopenharmony_ci reinterpret_cast<const uint8_t *>(&data_) + GetSize() - GetHeaderSize(), p); 64948f512ceSopenharmony_ci return true; 65048f512ceSopenharmony_ci} 65148f512ceSopenharmony_ci 65248f512ceSopenharmony_civoid PerfRecordMmap::DumpData(int indent) const 65348f512ceSopenharmony_ci{ 65448f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos 65548f512ceSopenharmony_ci if (IsRoot()) { 65648f512ceSopenharmony_ci PRINT_INDENT(indent, "pid %u, tid %u, addr 0x%llx, len 0x%llx\n", data_.pid, data_.tid, 65748f512ceSopenharmony_ci data_.addr, data_.len); 65848f512ceSopenharmony_ci PRINT_INDENT(indent, "pgoff 0x%llx, filename %s\n", data_.pgoff, data_.filename); 65948f512ceSopenharmony_ci } 66048f512ceSopenharmony_ci#endif 66148f512ceSopenharmony_ci} 66248f512ceSopenharmony_ci 66348f512ceSopenharmony_civoid PerfRecordMmap::DumpLog(const std::string &prefix) const 66448f512ceSopenharmony_ci{ 66548f512ceSopenharmony_ci HLOGV("%s: MMAP: size %d pid %u tid %u dso '%s' (0x%llx-0x%llx)@0x%llx", prefix.c_str(), 66648f512ceSopenharmony_ci header.size, data_.pid, data_.tid, data_.filename, data_.addr, data_.addr + data_.len, data_.pgoff); 66748f512ceSopenharmony_ci} 66848f512ceSopenharmony_ci 66948f512ceSopenharmony_ciPerfRecordMmap2::PerfRecordMmap2(uint8_t *p) : PerfEventRecord(p, "mmap2") 67048f512ceSopenharmony_ci{ 67148f512ceSopenharmony_ci size_t dataSize = GetSize(); 67248f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 67348f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 67448f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 67548f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 67648f512ceSopenharmony_ci } 67748f512ceSopenharmony_ci } else { 67848f512ceSopenharmony_ci HLOGE("PerfRecordMmap2 retren failed !!!"); 67948f512ceSopenharmony_ci } 68048f512ceSopenharmony_ci} 68148f512ceSopenharmony_ci 68248f512ceSopenharmony_ciPerfRecordMmap2::PerfRecordMmap2(bool inKernel, u32 pid, u32 tid, u64 addr, u64 len, u64 pgoff, 68348f512ceSopenharmony_ci u32 maj, u32 min, u64 ino, u32 prot, u32 flags, 68448f512ceSopenharmony_ci const std::string &filename) 68548f512ceSopenharmony_ci : PerfEventRecord(PERF_RECORD_MMAP2, inKernel, "mmap2") 68648f512ceSopenharmony_ci{ 68748f512ceSopenharmony_ci data_.pid = pid; 68848f512ceSopenharmony_ci data_.tid = tid; 68948f512ceSopenharmony_ci data_.addr = addr; 69048f512ceSopenharmony_ci data_.len = len; 69148f512ceSopenharmony_ci data_.pgoff = pgoff; 69248f512ceSopenharmony_ci data_.maj = maj; 69348f512ceSopenharmony_ci data_.min = min; 69448f512ceSopenharmony_ci data_.ino = ino; 69548f512ceSopenharmony_ci data_.ino_generation = 0; 69648f512ceSopenharmony_ci data_.prot = prot; 69748f512ceSopenharmony_ci data_.flags = flags; 69848f512ceSopenharmony_ci if (strncpy_s(data_.filename, KILO, filename.c_str(), filename.size()) != 0) { 69948f512ceSopenharmony_ci HLOGE("strncpy_s failed"); 70048f512ceSopenharmony_ci } 70148f512ceSopenharmony_ci 70248f512ceSopenharmony_ci header.size = sizeof(header) + sizeof(data_) - KILO + filename.size() + 1; 70348f512ceSopenharmony_ci} 70448f512ceSopenharmony_ci 70548f512ceSopenharmony_ciPerfRecordMmap2::PerfRecordMmap2(bool inKernel, u32 pid, u32 tid, std::shared_ptr<DfxMap> item) 70648f512ceSopenharmony_ci : PerfEventRecord(PERF_RECORD_MMAP2, inKernel, "mmap2") 70748f512ceSopenharmony_ci{ 70848f512ceSopenharmony_ci data_.pid = pid; 70948f512ceSopenharmony_ci data_.tid = tid; 71048f512ceSopenharmony_ci if (item != nullptr) { 71148f512ceSopenharmony_ci data_.addr = item->begin; 71248f512ceSopenharmony_ci data_.len = item->end - item->begin; 71348f512ceSopenharmony_ci data_.pgoff = item->offset; 71448f512ceSopenharmony_ci data_.maj = item->major; 71548f512ceSopenharmony_ci data_.min = item->minor; 71648f512ceSopenharmony_ci data_.ino = item->inode; 71748f512ceSopenharmony_ci data_.ino_generation = 0; 71848f512ceSopenharmony_ci // r--p 00000000 103:3e 12307 /data/storage/el1/bundle/entry.hap 71948f512ceSopenharmony_ci // why prot get from this is 7. rwxp 72048f512ceSopenharmony_ci DfxMap::PermsToProts(item->perms, data_.prot, data_.flags); 72148f512ceSopenharmony_ci if (strncpy_s(data_.filename, KILO, item->name.c_str(), item->name.size()) != 0) { 72248f512ceSopenharmony_ci HLOGE("strncpy_s failed"); 72348f512ceSopenharmony_ci } 72448f512ceSopenharmony_ci 72548f512ceSopenharmony_ci header.size = sizeof(header) + sizeof(data_) - KILO + item->name.size() + 1; 72648f512ceSopenharmony_ci } else { 72748f512ceSopenharmony_ci data_.addr = 0; 72848f512ceSopenharmony_ci data_.len = 0; 72948f512ceSopenharmony_ci data_.pgoff = 0; 73048f512ceSopenharmony_ci data_.maj = 0; 73148f512ceSopenharmony_ci data_.min = 0; 73248f512ceSopenharmony_ci data_.ino = 0; 73348f512ceSopenharmony_ci data_.ino_generation = 0; 73448f512ceSopenharmony_ci if (memset_s(data_.filename, KILO, 0, KILO) != EOK) { 73548f512ceSopenharmony_ci HLOGE("memset_s failed"); 73648f512ceSopenharmony_ci } 73748f512ceSopenharmony_ci } 73848f512ceSopenharmony_ci} 73948f512ceSopenharmony_ci 74048f512ceSopenharmony_cibool PerfRecordMmap2::GetBinary(std::vector<uint8_t> &buf) const 74148f512ceSopenharmony_ci{ 74248f512ceSopenharmony_ci if (buf.size() < GetSize()) { 74348f512ceSopenharmony_ci buf.resize(GetSize()); 74448f512ceSopenharmony_ci } 74548f512ceSopenharmony_ci 74648f512ceSopenharmony_ci GetHeaderBinary(buf); 74748f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 74848f512ceSopenharmony_ci 74948f512ceSopenharmony_ci // data_.filename[] is variable-length 75048f512ceSopenharmony_ci std::copy(reinterpret_cast<const uint8_t *>(&data_), 75148f512ceSopenharmony_ci reinterpret_cast<const uint8_t *>(&data_) + GetSize() - GetHeaderSize(), p); 75248f512ceSopenharmony_ci return true; 75348f512ceSopenharmony_ci} 75448f512ceSopenharmony_ci 75548f512ceSopenharmony_civoid PerfRecordMmap2::DumpData(int indent) const 75648f512ceSopenharmony_ci{ 75748f512ceSopenharmony_ci#if defined(is_ohos) && is_ohos 75848f512ceSopenharmony_ci if (IsRoot()) { 75948f512ceSopenharmony_ci PRINT_INDENT(indent, "pid %u, tid %u, addr 0x%llx, len 0x%llx\n", data_.pid, data_.tid, 76048f512ceSopenharmony_ci data_.addr, data_.len); 76148f512ceSopenharmony_ci PRINT_INDENT(indent, "pgoff 0x%llx, maj %u, min %u, ino %llu, ino_generation %llu\n", 76248f512ceSopenharmony_ci data_.pgoff, data_.maj, data_.min, data_.ino, data_.ino_generation); 76348f512ceSopenharmony_ci PRINT_INDENT(indent, "prot %u, flags %u, filename %s\n", data_.prot, data_.flags, 76448f512ceSopenharmony_ci data_.filename); 76548f512ceSopenharmony_ci } 76648f512ceSopenharmony_ci#endif 76748f512ceSopenharmony_ci} 76848f512ceSopenharmony_civoid PerfRecordMmap2::DumpLog(const std::string &prefix) const 76948f512ceSopenharmony_ci{ 77048f512ceSopenharmony_ci HLOGV("%s: MMAP2: size %d pid %u tid %u dso '%s' (0x%llx-0x%llx)@0x%llx", prefix.c_str(), 77148f512ceSopenharmony_ci header.size, data_.pid, data_.tid, data_.filename, data_.addr, data_.addr + data_.len, 77248f512ceSopenharmony_ci data_.pgoff); 77348f512ceSopenharmony_ci} 77448f512ceSopenharmony_ci 77548f512ceSopenharmony_ciPerfRecordLost::PerfRecordLost(uint8_t *p) : PerfEventRecord(p, "lost") 77648f512ceSopenharmony_ci{ 77748f512ceSopenharmony_ci size_t dataSize = GetSize(); 77848f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 77948f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 78048f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 78148f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 78248f512ceSopenharmony_ci } 78348f512ceSopenharmony_ci } else { 78448f512ceSopenharmony_ci HLOGE("PerfRecordLost retren failed !!!"); 78548f512ceSopenharmony_ci } 78648f512ceSopenharmony_ci} 78748f512ceSopenharmony_ci 78848f512ceSopenharmony_cibool PerfRecordLost::GetBinary(std::vector<uint8_t> &buf) const 78948f512ceSopenharmony_ci{ 79048f512ceSopenharmony_ci if (buf.size() < GetSize()) { 79148f512ceSopenharmony_ci buf.resize(GetSize()); 79248f512ceSopenharmony_ci } 79348f512ceSopenharmony_ci 79448f512ceSopenharmony_ci GetHeaderBinary(buf); 79548f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 79648f512ceSopenharmony_ci 79748f512ceSopenharmony_ci auto pDest = reinterpret_cast<PerfRecordLostData *>(p); 79848f512ceSopenharmony_ci *pDest = data_; 79948f512ceSopenharmony_ci 80048f512ceSopenharmony_ci return true; 80148f512ceSopenharmony_ci} 80248f512ceSopenharmony_ci 80348f512ceSopenharmony_civoid PerfRecordLost::DumpData(int indent) const 80448f512ceSopenharmony_ci{ 80548f512ceSopenharmony_ci PRINT_INDENT(indent, "id %llu, lost %llu\n", data_.id, data_.lost); 80648f512ceSopenharmony_ci} 80748f512ceSopenharmony_ci 80848f512ceSopenharmony_ciPerfRecordComm::PerfRecordComm(uint8_t *p) : PerfEventRecord(p, "comm") 80948f512ceSopenharmony_ci{ 81048f512ceSopenharmony_ci size_t dataSize = GetSize(); 81148f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 81248f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 81348f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 81448f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 81548f512ceSopenharmony_ci } 81648f512ceSopenharmony_ci } else { 81748f512ceSopenharmony_ci HLOGE("PerfRecordComm retren failed !!!"); 81848f512ceSopenharmony_ci } 81948f512ceSopenharmony_ci} 82048f512ceSopenharmony_ci 82148f512ceSopenharmony_ciPerfRecordComm::PerfRecordComm(bool inKernel, u32 pid, u32 tid, const std::string &comm) 82248f512ceSopenharmony_ci : PerfEventRecord(PERF_RECORD_COMM, inKernel, "comm") 82348f512ceSopenharmony_ci{ 82448f512ceSopenharmony_ci data_.pid = pid; 82548f512ceSopenharmony_ci data_.tid = tid; 82648f512ceSopenharmony_ci if (strncpy_s(data_.comm, KILO, comm.c_str(), comm.size()) != 0) { 82748f512ceSopenharmony_ci HLOGE("strncpy_s failed !!!"); 82848f512ceSopenharmony_ci } 82948f512ceSopenharmony_ci 83048f512ceSopenharmony_ci header.size = sizeof(header) + sizeof(data_) - KILO + comm.size() + 1; 83148f512ceSopenharmony_ci} 83248f512ceSopenharmony_ci 83348f512ceSopenharmony_cibool PerfRecordComm::GetBinary(std::vector<uint8_t> &buf) const 83448f512ceSopenharmony_ci{ 83548f512ceSopenharmony_ci if (buf.size() < GetSize()) { 83648f512ceSopenharmony_ci buf.resize(GetSize()); 83748f512ceSopenharmony_ci } 83848f512ceSopenharmony_ci 83948f512ceSopenharmony_ci GetHeaderBinary(buf); 84048f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 84148f512ceSopenharmony_ci 84248f512ceSopenharmony_ci // data_.comm[] is variable-length 84348f512ceSopenharmony_ci std::copy(reinterpret_cast<const uint8_t *>(&data_), 84448f512ceSopenharmony_ci reinterpret_cast<const uint8_t *>(&data_) + GetSize() - GetHeaderSize(), p); 84548f512ceSopenharmony_ci 84648f512ceSopenharmony_ci return true; 84748f512ceSopenharmony_ci} 84848f512ceSopenharmony_ci 84948f512ceSopenharmony_civoid PerfRecordComm::DumpData(int indent) const 85048f512ceSopenharmony_ci{ 85148f512ceSopenharmony_ci PRINT_INDENT(indent, "pid %u, tid %u, comm %s\n", data_.pid, data_.tid, data_.comm); 85248f512ceSopenharmony_ci} 85348f512ceSopenharmony_ci 85448f512ceSopenharmony_civoid PerfRecordComm::DumpLog(const std::string &prefix) const 85548f512ceSopenharmony_ci{ 85648f512ceSopenharmony_ci HLOGV("pid %u, tid %u, comm %s\n", data_.pid, data_.tid, data_.comm); 85748f512ceSopenharmony_ci} 85848f512ceSopenharmony_ci 85948f512ceSopenharmony_ciPerfRecordExit::PerfRecordExit(uint8_t *p) : PerfEventRecord(p, "exit") 86048f512ceSopenharmony_ci{ 86148f512ceSopenharmony_ci size_t dataSize = GetSize(); 86248f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 86348f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 86448f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 86548f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 86648f512ceSopenharmony_ci } 86748f512ceSopenharmony_ci } else { 86848f512ceSopenharmony_ci HLOGE("PerfRecordExit retren failed !!!"); 86948f512ceSopenharmony_ci } 87048f512ceSopenharmony_ci} 87148f512ceSopenharmony_ci 87248f512ceSopenharmony_cibool PerfRecordExit::GetBinary(std::vector<uint8_t> &buf) const 87348f512ceSopenharmony_ci{ 87448f512ceSopenharmony_ci if (buf.size() < GetSize()) { 87548f512ceSopenharmony_ci buf.resize(GetSize()); 87648f512ceSopenharmony_ci } 87748f512ceSopenharmony_ci 87848f512ceSopenharmony_ci GetHeaderBinary(buf); 87948f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 88048f512ceSopenharmony_ci 88148f512ceSopenharmony_ci auto pDest = reinterpret_cast<PerfRecordExitData *>(p); 88248f512ceSopenharmony_ci *pDest = data_; 88348f512ceSopenharmony_ci return true; 88448f512ceSopenharmony_ci} 88548f512ceSopenharmony_ci 88648f512ceSopenharmony_civoid PerfRecordExit::DumpData(int indent) const 88748f512ceSopenharmony_ci{ 88848f512ceSopenharmony_ci PRINT_INDENT(indent, "pid %u, ppid %u, tid %u, ptid %u time 0x%llx\n", data_.pid, data_.ppid, 88948f512ceSopenharmony_ci data_.tid, data_.ptid, data_.time); 89048f512ceSopenharmony_ci} 89148f512ceSopenharmony_ci 89248f512ceSopenharmony_ciPerfRecordThrottle::PerfRecordThrottle(uint8_t *p) : PerfEventRecord(p, "throttle") 89348f512ceSopenharmony_ci{ 89448f512ceSopenharmony_ci size_t dataSize = GetSize(); 89548f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 89648f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 89748f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 89848f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 89948f512ceSopenharmony_ci } 90048f512ceSopenharmony_ci } else { 90148f512ceSopenharmony_ci HLOGE("PerfRecordThrottle retren failed !!!"); 90248f512ceSopenharmony_ci } 90348f512ceSopenharmony_ci} 90448f512ceSopenharmony_ci 90548f512ceSopenharmony_cibool PerfRecordThrottle::GetBinary(std::vector<uint8_t> &buf) const 90648f512ceSopenharmony_ci{ 90748f512ceSopenharmony_ci if (buf.size() < GetSize()) { 90848f512ceSopenharmony_ci buf.resize(GetSize()); 90948f512ceSopenharmony_ci } 91048f512ceSopenharmony_ci 91148f512ceSopenharmony_ci GetHeaderBinary(buf); 91248f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 91348f512ceSopenharmony_ci 91448f512ceSopenharmony_ci auto pDest = reinterpret_cast<PerfRecordThrottleData *>(p); 91548f512ceSopenharmony_ci *pDest = data_; 91648f512ceSopenharmony_ci return true; 91748f512ceSopenharmony_ci} 91848f512ceSopenharmony_ci 91948f512ceSopenharmony_civoid PerfRecordThrottle::DumpData(int indent) const 92048f512ceSopenharmony_ci{ 92148f512ceSopenharmony_ci PRINT_INDENT(indent, "time 0x%llx, id %llx, stream_id %llx\n", data_.time, data_.id, 92248f512ceSopenharmony_ci data_.stream_id); 92348f512ceSopenharmony_ci} 92448f512ceSopenharmony_ci 92548f512ceSopenharmony_ciPerfRecordUnthrottle::PerfRecordUnthrottle(uint8_t *p) : PerfEventRecord(p, "unthrottle") 92648f512ceSopenharmony_ci{ 92748f512ceSopenharmony_ci size_t dataSize = GetSize(); 92848f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 92948f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 93048f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 93148f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 93248f512ceSopenharmony_ci } 93348f512ceSopenharmony_ci } else { 93448f512ceSopenharmony_ci HLOGE("PerfRecordUnthrottle retren failed !!!"); 93548f512ceSopenharmony_ci } 93648f512ceSopenharmony_ci} 93748f512ceSopenharmony_ci 93848f512ceSopenharmony_cibool PerfRecordUnthrottle::GetBinary(std::vector<uint8_t> &buf) const 93948f512ceSopenharmony_ci{ 94048f512ceSopenharmony_ci if (buf.size() < GetSize()) { 94148f512ceSopenharmony_ci buf.resize(GetSize()); 94248f512ceSopenharmony_ci } 94348f512ceSopenharmony_ci 94448f512ceSopenharmony_ci GetHeaderBinary(buf); 94548f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 94648f512ceSopenharmony_ci 94748f512ceSopenharmony_ci auto pDest = reinterpret_cast<PerfRecordThrottleData *>(p); 94848f512ceSopenharmony_ci *pDest = data_; 94948f512ceSopenharmony_ci return true; 95048f512ceSopenharmony_ci} 95148f512ceSopenharmony_civoid PerfRecordUnthrottle::DumpData(int indent) const 95248f512ceSopenharmony_ci{ 95348f512ceSopenharmony_ci PRINT_INDENT(indent, "time 0x%llx, id %llx, stream_id %llx\n", data_.time, data_.id, 95448f512ceSopenharmony_ci data_.stream_id); 95548f512ceSopenharmony_ci} 95648f512ceSopenharmony_ci 95748f512ceSopenharmony_ciPerfRecordFork::PerfRecordFork(uint8_t *p) : PerfEventRecord(p, "fork") 95848f512ceSopenharmony_ci{ 95948f512ceSopenharmony_ci size_t dataSize = GetSize(); 96048f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 96148f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 96248f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 96348f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 96448f512ceSopenharmony_ci } 96548f512ceSopenharmony_ci } else { 96648f512ceSopenharmony_ci HLOGE("PerfRecordFork retren failed !!!"); 96748f512ceSopenharmony_ci } 96848f512ceSopenharmony_ci} 96948f512ceSopenharmony_ci 97048f512ceSopenharmony_cibool PerfRecordFork::GetBinary(std::vector<uint8_t> &buf) const 97148f512ceSopenharmony_ci{ 97248f512ceSopenharmony_ci if (buf.size() < GetSize()) { 97348f512ceSopenharmony_ci buf.resize(GetSize()); 97448f512ceSopenharmony_ci } 97548f512ceSopenharmony_ci 97648f512ceSopenharmony_ci GetHeaderBinary(buf); 97748f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 97848f512ceSopenharmony_ci 97948f512ceSopenharmony_ci auto pDest = reinterpret_cast<PerfRecordForkData *>(p); 98048f512ceSopenharmony_ci *pDest = data_; 98148f512ceSopenharmony_ci return true; 98248f512ceSopenharmony_ci} 98348f512ceSopenharmony_ci 98448f512ceSopenharmony_civoid PerfRecordFork::DumpData(int indent) const 98548f512ceSopenharmony_ci{ 98648f512ceSopenharmony_ci PRINT_INDENT(indent, "pid %u, ppid %u, tid %u, ptid %u\n", data_.pid, data_.ppid, data_.tid, 98748f512ceSopenharmony_ci data_.ptid); 98848f512ceSopenharmony_ci} 98948f512ceSopenharmony_ci 99048f512ceSopenharmony_ciPerfRecordRead::PerfRecordRead(uint8_t *p) : PerfEventRecord(p, "read") 99148f512ceSopenharmony_ci{ 99248f512ceSopenharmony_ci size_t dataSize = GetSize(); 99348f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 99448f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 99548f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 99648f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 99748f512ceSopenharmony_ci } 99848f512ceSopenharmony_ci } else { 99948f512ceSopenharmony_ci HLOGE("PerfRecordRead retren failed !!!"); 100048f512ceSopenharmony_ci } 100148f512ceSopenharmony_ci} 100248f512ceSopenharmony_ci 100348f512ceSopenharmony_cibool PerfRecordRead::GetBinary(std::vector<uint8_t> &buf) const 100448f512ceSopenharmony_ci{ 100548f512ceSopenharmony_ci if (buf.size() < GetSize()) { 100648f512ceSopenharmony_ci buf.resize(GetSize()); 100748f512ceSopenharmony_ci } 100848f512ceSopenharmony_ci 100948f512ceSopenharmony_ci GetHeaderBinary(buf); 101048f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 101148f512ceSopenharmony_ci 101248f512ceSopenharmony_ci auto pDest = reinterpret_cast<PerfRecordReadData *>(p); 101348f512ceSopenharmony_ci *pDest = data_; 101448f512ceSopenharmony_ci return true; 101548f512ceSopenharmony_ci} 101648f512ceSopenharmony_ci 101748f512ceSopenharmony_civoid PerfRecordRead::DumpData(int indent) const 101848f512ceSopenharmony_ci{ 101948f512ceSopenharmony_ci PRINT_INDENT(indent, "pid %u, tid %u\n", data_.pid, data_.tid); 102048f512ceSopenharmony_ci PRINT_INDENT(indent, "values: value %llx, timeEnabled %llx, timeRunning %llx, id %llx\n", 102148f512ceSopenharmony_ci data_.values.value, data_.values.timeEnabled, data_.values.timeRunning, data_.values.id); 102248f512ceSopenharmony_ci} 102348f512ceSopenharmony_ci 102448f512ceSopenharmony_ciPerfRecordAux::PerfRecordAux(uint8_t *p) : PerfEventRecord(p, "aux") 102548f512ceSopenharmony_ci{ 102648f512ceSopenharmony_ci size_t dataSize = GetSize(); 102748f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 102848f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 102948f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 103048f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 103148f512ceSopenharmony_ci } 103248f512ceSopenharmony_ci } else { 103348f512ceSopenharmony_ci HLOGE("PerfRecordAux retren failed !!!"); 103448f512ceSopenharmony_ci } 103548f512ceSopenharmony_ci} 103648f512ceSopenharmony_ci 103748f512ceSopenharmony_cibool PerfRecordAux::GetBinary(std::vector<uint8_t> &buf) const 103848f512ceSopenharmony_ci{ 103948f512ceSopenharmony_ci if (buf.size() < GetSize()) { 104048f512ceSopenharmony_ci buf.resize(GetSize()); 104148f512ceSopenharmony_ci } 104248f512ceSopenharmony_ci 104348f512ceSopenharmony_ci GetHeaderBinary(buf); 104448f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 104548f512ceSopenharmony_ci 104648f512ceSopenharmony_ci PushToBinary(true, p, data_.aux_offset); 104748f512ceSopenharmony_ci PushToBinary(true, p, data_.aux_size); 104848f512ceSopenharmony_ci PushToBinary(true, p, data_.flags); 104948f512ceSopenharmony_ci PushToBinary2(sampleType_ & PERF_SAMPLE_TID, p, data_.sample_id.pid, data_.sample_id.tid); 105048f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_TIME, p, data_.sample_id.time); 105148f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_ID, p, data_.sample_id.id); 105248f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_STREAM_ID, p, data_.sample_id.stream_id); 105348f512ceSopenharmony_ci 105448f512ceSopenharmony_ci PushToBinary2(sampleType_ & PERF_SAMPLE_CPU, p, data_.sample_id.cpu, data_.sample_id.res); 105548f512ceSopenharmony_ci PushToBinary(sampleType_ & PERF_SAMPLE_IDENTIFIER, p, data_.sample_id.id2); 105648f512ceSopenharmony_ci return true; 105748f512ceSopenharmony_ci} 105848f512ceSopenharmony_ci 105948f512ceSopenharmony_civoid PerfRecordAux::DumpData(int indent) const 106048f512ceSopenharmony_ci{ 106148f512ceSopenharmony_ci PRINT_INDENT(indent, "aux_offset 0x%llx aux_size 0x%llx flags 0x%llx pid %u tid %u time %llu", 106248f512ceSopenharmony_ci data_.aux_offset, data_.aux_size, data_.flags, data_.sample_id.pid, data_.sample_id.tid, 106348f512ceSopenharmony_ci data_.sample_id.time); 106448f512ceSopenharmony_ci} 106548f512ceSopenharmony_ci 106648f512ceSopenharmony_ciPerfRecordItraceStart::PerfRecordItraceStart(uint8_t *p) : PerfEventRecord(p, "itraceStart") 106748f512ceSopenharmony_ci{ 106848f512ceSopenharmony_ci size_t dataSize = GetSize(); 106948f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 107048f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 107148f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 107248f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 107348f512ceSopenharmony_ci } 107448f512ceSopenharmony_ci } else { 107548f512ceSopenharmony_ci HLOGE("PerfRecordItraceStart retren failed !!!"); 107648f512ceSopenharmony_ci } 107748f512ceSopenharmony_ci} 107848f512ceSopenharmony_ci 107948f512ceSopenharmony_cibool PerfRecordItraceStart::GetBinary(std::vector<uint8_t> &buf) const 108048f512ceSopenharmony_ci{ 108148f512ceSopenharmony_ci if (buf.size() < GetSize()) { 108248f512ceSopenharmony_ci buf.resize(GetSize()); 108348f512ceSopenharmony_ci } 108448f512ceSopenharmony_ci 108548f512ceSopenharmony_ci GetHeaderBinary(buf); 108648f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 108748f512ceSopenharmony_ci 108848f512ceSopenharmony_ci auto pDest = reinterpret_cast<PerfRecordItraceStartData *>(p); 108948f512ceSopenharmony_ci *pDest = data_; 109048f512ceSopenharmony_ci return true; 109148f512ceSopenharmony_ci} 109248f512ceSopenharmony_ci 109348f512ceSopenharmony_civoid PerfRecordItraceStart::DumpData(int indent) const 109448f512ceSopenharmony_ci{ 109548f512ceSopenharmony_ci PRINT_INDENT(indent, "pid %u, tid %u\n", data_.pid, data_.tid); 109648f512ceSopenharmony_ci} 109748f512ceSopenharmony_ci 109848f512ceSopenharmony_ciPerfRecordLostSamples::PerfRecordLostSamples(uint8_t *p) : PerfEventRecord(p, "lostSamples") 109948f512ceSopenharmony_ci{ 110048f512ceSopenharmony_ci size_t dataSize = GetSize(); 110148f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 110248f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 110348f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 110448f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 110548f512ceSopenharmony_ci } 110648f512ceSopenharmony_ci } else { 110748f512ceSopenharmony_ci HLOGE("PerfRecordLostSamples retren failed !!!"); 110848f512ceSopenharmony_ci } 110948f512ceSopenharmony_ci} 111048f512ceSopenharmony_ci 111148f512ceSopenharmony_cibool PerfRecordLostSamples::GetBinary(std::vector<uint8_t> &buf) const 111248f512ceSopenharmony_ci{ 111348f512ceSopenharmony_ci if (buf.size() < GetSize()) { 111448f512ceSopenharmony_ci buf.resize(GetSize()); 111548f512ceSopenharmony_ci } 111648f512ceSopenharmony_ci 111748f512ceSopenharmony_ci GetHeaderBinary(buf); 111848f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 111948f512ceSopenharmony_ci 112048f512ceSopenharmony_ci auto pDest = reinterpret_cast<PerfRecordLostSamplesData *>(p); 112148f512ceSopenharmony_ci *pDest = data_; 112248f512ceSopenharmony_ci return true; 112348f512ceSopenharmony_ci} 112448f512ceSopenharmony_ci 112548f512ceSopenharmony_civoid PerfRecordLostSamples::DumpData(int indent) const 112648f512ceSopenharmony_ci{ 112748f512ceSopenharmony_ci PRINT_INDENT(indent, "lost %llu\n", data_.lost); 112848f512ceSopenharmony_ci} 112948f512ceSopenharmony_ci 113048f512ceSopenharmony_ciPerfRecordSwitch::PerfRecordSwitch(uint8_t *p) : PerfEventRecord(p, "switch") 113148f512ceSopenharmony_ci{ 113248f512ceSopenharmony_ci size_t dataSize = GetSize(); 113348f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 113448f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 113548f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 113648f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 113748f512ceSopenharmony_ci } 113848f512ceSopenharmony_ci } else { 113948f512ceSopenharmony_ci HLOGE("PerfRecordSwitch retren failed !!!"); 114048f512ceSopenharmony_ci } 114148f512ceSopenharmony_ci} 114248f512ceSopenharmony_ci 114348f512ceSopenharmony_cibool PerfRecordSwitch::GetBinary(std::vector<uint8_t> &buf) const 114448f512ceSopenharmony_ci{ 114548f512ceSopenharmony_ci if (buf.size() < GetSize()) { 114648f512ceSopenharmony_ci buf.resize(GetSize()); 114748f512ceSopenharmony_ci } 114848f512ceSopenharmony_ci 114948f512ceSopenharmony_ci GetHeaderBinary(buf); 115048f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 115148f512ceSopenharmony_ci 115248f512ceSopenharmony_ci auto pDest = reinterpret_cast<PerfRecordSwitchData *>(p); 115348f512ceSopenharmony_ci *pDest = data_; 115448f512ceSopenharmony_ci return true; 115548f512ceSopenharmony_ci} 115648f512ceSopenharmony_ci 115748f512ceSopenharmony_ciPerfRecordSwitchCpuWide::PerfRecordSwitchCpuWide(uint8_t *p) : PerfEventRecord(p, "switchCpuWide") 115848f512ceSopenharmony_ci{ 115948f512ceSopenharmony_ci size_t dataSize = GetSize(); 116048f512ceSopenharmony_ci if (dataSize >= sizeof(header)) { 116148f512ceSopenharmony_ci size_t copySize = dataSize - sizeof(header); 116248f512ceSopenharmony_ci if (memcpy_s(reinterpret_cast<uint8_t *>(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { 116348f512ceSopenharmony_ci HLOGE("memcpy_s retren failed !!!"); 116448f512ceSopenharmony_ci } 116548f512ceSopenharmony_ci } else { 116648f512ceSopenharmony_ci HLOGE("PerfRecordSwitchCpuWide retren failed !!!"); 116748f512ceSopenharmony_ci } 116848f512ceSopenharmony_ci} 116948f512ceSopenharmony_ci 117048f512ceSopenharmony_cibool PerfRecordSwitchCpuWide::GetBinary(std::vector<uint8_t> &buf) const 117148f512ceSopenharmony_ci{ 117248f512ceSopenharmony_ci if (buf.size() < GetSize()) { 117348f512ceSopenharmony_ci buf.resize(GetSize()); 117448f512ceSopenharmony_ci } 117548f512ceSopenharmony_ci 117648f512ceSopenharmony_ci GetHeaderBinary(buf); 117748f512ceSopenharmony_ci uint8_t *p = buf.data() + GetHeaderSize(); 117848f512ceSopenharmony_ci 117948f512ceSopenharmony_ci auto pDest = reinterpret_cast<PerfRecordSwitchCpuWideData *>(p); 118048f512ceSopenharmony_ci *pDest = data_; 118148f512ceSopenharmony_ci return true; 118248f512ceSopenharmony_ci} 118348f512ceSopenharmony_ci 118448f512ceSopenharmony_civoid PerfRecordSwitchCpuWide::DumpData(int indent) const 118548f512ceSopenharmony_ci{ 118648f512ceSopenharmony_ci PRINT_INDENT(indent, "next_prev_pid %u, next_prev_tid %u\n", data_.next_prev_pid, 118748f512ceSopenharmony_ci data_.next_prev_tid); 118848f512ceSopenharmony_ci} 118948f512ceSopenharmony_ci 119048f512ceSopenharmony_cipid_t PerfRecordSample::GetUstackServerPid() 119148f512ceSopenharmony_ci{ 119248f512ceSopenharmony_ci if (!data_.server_nr) { 119348f512ceSopenharmony_ci return data_.pid; 119448f512ceSopenharmony_ci } 119548f512ceSopenharmony_ci 119648f512ceSopenharmony_ci size_t currServer = 0; 119748f512ceSopenharmony_ci // ipNr == 1...nr: server_pid of data_.ips[nr] 119848f512ceSopenharmony_ci for (size_t i = 0; i < data_.nr; i++) { 119948f512ceSopenharmony_ci // context change, use next server pid 120048f512ceSopenharmony_ci if (data_.ips[i] >= PERF_CONTEXT_MAX) { 120148f512ceSopenharmony_ci currServer++; 120248f512ceSopenharmony_ci } 120348f512ceSopenharmony_ci } 120448f512ceSopenharmony_ci // ipNr == nr + 1: server_pid of ustack 120548f512ceSopenharmony_ci if (currServer > 0) { 120648f512ceSopenharmony_ci currServer++; 120748f512ceSopenharmony_ci } 120848f512ceSopenharmony_ci if (currServer >= data_.server_nr) { 120948f512ceSopenharmony_ci HLOGE("ustack server pid nr %zu out of range", currServer); 121048f512ceSopenharmony_ci return data_.pid; 121148f512ceSopenharmony_ci } 121248f512ceSopenharmony_ci 121348f512ceSopenharmony_ci // return server pid 121448f512ceSopenharmony_ci return data_.server_pids[currServer]; 121548f512ceSopenharmony_ci} 121648f512ceSopenharmony_ci 121748f512ceSopenharmony_cipid_t PerfRecordSample::GetServerPidof(unsigned int ipNr) 121848f512ceSopenharmony_ci{ 121948f512ceSopenharmony_ci if (!data_.server_nr) { 122048f512ceSopenharmony_ci return data_.pid; 122148f512ceSopenharmony_ci } 122248f512ceSopenharmony_ci 122348f512ceSopenharmony_ci // init serverPidMap_ 122448f512ceSopenharmony_ci if (!serverPidMap_.size()) { 122548f512ceSopenharmony_ci size_t currServer = 0; 122648f512ceSopenharmony_ci // ipNr == 0: server_pid of data_.ip 122748f512ceSopenharmony_ci serverPidMap_.emplace_back(data_.server_pids[currServer]); 122848f512ceSopenharmony_ci // ipNr == 1...nr: server_pid of data_.ips[nr] 122948f512ceSopenharmony_ci for (size_t i = 1; i < data_.nr; i++) { 123048f512ceSopenharmony_ci // context change, use next server pid 123148f512ceSopenharmony_ci if (data_.ips[i] >= PERF_CONTEXT_MAX) { 123248f512ceSopenharmony_ci currServer++; 123348f512ceSopenharmony_ci } 123448f512ceSopenharmony_ci if (currServer >= data_.server_nr) { 123548f512ceSopenharmony_ci HLOGE("callchain server pid nr %zu out of range", currServer); 123648f512ceSopenharmony_ci break; 123748f512ceSopenharmony_ci } 123848f512ceSopenharmony_ci serverPidMap_.emplace_back(data_.server_pids[currServer]); 123948f512ceSopenharmony_ci } 124048f512ceSopenharmony_ci } 124148f512ceSopenharmony_ci 124248f512ceSopenharmony_ci // return server pid 124348f512ceSopenharmony_ci if (ipNr >= serverPidMap_.size()) { 124448f512ceSopenharmony_ci return data_.pid; 124548f512ceSopenharmony_ci } else { 124648f512ceSopenharmony_ci return serverPidMap_[ipNr]; 124748f512ceSopenharmony_ci } 124848f512ceSopenharmony_ci} 124948f512ceSopenharmony_ci} // namespace HiPerf 125048f512ceSopenharmony_ci} // namespace Developtools 125148f512ceSopenharmony_ci} // namespace OHOS 1252