diff --git a/include/perf_event_record.h b/include/perf_event_record.h index ae10c66..c394acd 100644 --- a/include/perf_event_record.h +++ b/include/perf_event_record.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -39,63 +40,34 @@ namespace OHOS { namespace Developtools { namespace HiPerf { using namespace OHOS::HiviewDFX; +using PerfRecordType = int32_t; static constexpr uint32_t RECORD_SIZE_LIMIT = 65535; static constexpr uint32_t RECORD_SIZE_LIMIT_SPE = 524288; // auxMmapPages_ * pageSize_ +static constexpr char PERF_RECORD_TYPE_AUXTRACE[] = "auxtrace"; +static constexpr char PERF_RECORD_TYPE_SAMPLE[] = "sample"; +static constexpr char PERF_RECORD_TYPE_MMAP[] = "mmap"; +static constexpr char PERF_RECORD_TYPE_MMAP2[] = "mmap2"; +static constexpr char PERF_RECORD_TYPE_LOST[] = "lost"; +static constexpr char PERF_RECORD_TYPE_COMM[] = "comm"; +static constexpr char PERF_RECORD_TYPE_EXIT[] = "exit"; +static constexpr char PERF_RECORD_TYPE_THROTTLE[] = "throttle"; +static constexpr char PERF_RECORD_TYPE_UNTHROTTLE[] = "unthrottle"; +static constexpr char PERF_RECORD_TYPE_FORK[] = "fork"; +static constexpr char PERF_RECORD_TYPE_READ[] = "read"; +static constexpr char PERF_RECORD_TYPE_AUX[] = "aux"; +static constexpr char PERF_RECORD_TYPE_ITRACESTART[] = "itraceStart"; +static constexpr char PERF_RECORD_TYPE_LOSTSAMPLE[] = "lostSamples"; +static constexpr char PERF_RECORD_TYPE_SWITCH[] = "switch"; +static constexpr char PERF_RECORD_TYPE_SWITCHCPUWIDE[] = "switchCpuWide"; +static constexpr char* PERF_RECORD_TYPE_NULL = nullptr; + enum perf_event_hiperf_ext_type { PERF_RECORD_AUXTRACE = 71, PERF_RECORD_HIPERF_CALLSTACK = UINT32_MAX / 2, }; -struct CallFrame { - uint64_t ip_ = 0; // pc - uint64_t sp_ = 0; // sp - int32_t symbolFileIndex_ = -1; // symbolFileIndex_, symbols file index, used to report protobuf file - uint64_t vaddrInFile_ = 0; // funcOffset, vaddr of symbol in file - uint64_t offsetToVaddr_ = 0; // mapOffset, offset of ip to vaddr - int32_t symbolIndex_ = -1; // index, symbols index , should update after sort - std::string_view symbolName_; // funcName - std::string_view filePath_; // mapName, lib path , elf path - - CallFrame(uint64_t ip, uint64_t sp = 0) : ip_(ip), sp_(sp) {} - - // this is for ut test - CallFrame(uint64_t ip, uint64_t vaddrInFile, const char *name, const char *filePath) - : ip_(ip), vaddrInFile_(vaddrInFile), symbolName_(name), filePath_(filePath) - { - } - bool operator==(const CallFrame &b) const - { - return (ip_ == b.ip_) && (sp_ == b.sp_); - } - bool operator!=(const CallFrame &b) const - { - return (ip_ != b.ip_) || (sp_ != b.sp_); - } - std::string ToString() const - { - return StringPrintf("ip: 0x%016llx sp: 0x%016llx", ip_, sp_); - } - std::string ToSymbolString() const - { - std::string output = StringPrintf(" 0x%016llx : ", ip_); - output.append(symbolName_); - if (vaddrInFile_ != 0) { - output += StringPrintf("[0x%016llx:0x%016llx][+0x%llx]", ip_ - offsetToVaddr_, - vaddrInFile_, offsetToVaddr_); - } - - output.append("@"); - output.append(filePath_); - if (symbolIndex_ != -1) { - output.append(":"); - output.append(std::to_string(symbolIndex_)); - } - return output; - } -}; - struct AttrWithId { perf_event_attr attr; std::vector ids; @@ -104,50 +76,39 @@ struct AttrWithId { class PerfEventRecord { public: - PerfEventRecord(const PerfEventRecord &) = delete; - PerfEventRecord &operator=(const PerfEventRecord &) = delete; + struct perf_event_header header_ = {}; - struct perf_event_header header; - const std::string name_ {}; + virtual const char* GetName() const = 0; + virtual void Init(uint8_t* data, const perf_event_attr& attr) = 0; - PerfEventRecord(perf_event_type type, bool inKernel, const std::string &name); - PerfEventRecord(perf_event_hiperf_ext_type type, const std::string &name); - - PerfEventRecord(uint8_t *p, const std::string &name); - - virtual ~PerfEventRecord() {} + virtual ~PerfEventRecord() = default; virtual size_t GetSize() const { - return header.size; + return header_.size; }; size_t GetHeaderSize() const { - return sizeof(header); + return sizeof(header_); }; void GetHeaderBinary(std::vector &buf) const; uint32_t GetType() const { - return header.type; + return header_.type; }; uint16_t GetMisc() const { - return header.misc; + return header_.misc; }; - bool inKernel() + bool InKernel() { - return header.misc & PERF_RECORD_MISC_KERNEL; + return header_.misc & PERF_RECORD_MISC_KERNEL; } - bool inUser() + bool InUser() { - return header.misc & PERF_RECORD_MISC_USER; + return header_.misc & PERF_RECORD_MISC_USER; } - const std::string &GetName() const - { - return name_; - }; - // to support --exclude-hiperf, return sample_id.pid to filter record, virtual pid_t GetPid() const { @@ -157,7 +118,42 @@ public: virtual bool GetBinary(std::vector &buf) const = 0; void Dump(int indent = 0, std::string outputFilename = "", FILE *outputDump = nullptr) const; virtual void DumpData(int indent) const = 0; - virtual void DumpLog(const std::string &prefix) const; + virtual void DumpLog(const std::string& prefix) const; + +protected: + void Init(perf_event_type type, bool inKernel); + void Init(perf_event_hiperf_ext_type type); + void InitHeader(uint8_t* p); +}; + +template +class PerfEventRecordTemplate : public PerfEventRecord { +public: + PerfEventRecordTemplate(const PerfEventRecordTemplate&) = delete; + PerfEventRecordTemplate& operator=(const PerfEventRecordTemplate&) = delete; + + DataType data_ = {}; + const char* GetName() const override final + { + return RECORD_TYPE_NAME; + } + + PerfEventRecordTemplate() = default; + virtual ~PerfEventRecordTemplate() = default; + void Init(uint8_t* p, const perf_event_attr& = {}) override + { + InitHeader(p); + + size_t dataSize = GetSize(); + if (dataSize >= sizeof(header_)) { + size_t copySize = dataSize - sizeof(header_); + if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header_), copySize) != 0) { + HLOGE("init perf record memcpy_s failed!"); + } + } else { + HLOGE("init perf record failed!"); + } + }; }; // define convert from linux/perf_event.h @@ -171,12 +167,12 @@ constexpr __u64 SAMPLE_TYPE = PERF_SAMPLE_IP | SAMPLE_ID | PERF_SAMPLE_PERIOD; constexpr __u32 MIN_SAMPLE_STACK_SIZE = 8; constexpr __u32 MAX_SAMPLE_STACK_SIZE = 65528; -class PerfRecordAuxtrace : public PerfEventRecord { +class PerfRecordAuxtrace : public PerfEventRecordTemplate { public: - PerfRecordAuxtraceData data_; u8* rawData_ = nullptr; - explicit PerfRecordAuxtrace(uint8_t *p); + PerfRecordAuxtrace() = default; PerfRecordAuxtrace(u64 size, u64 offset, u64 reference, u32 idx, u32 tid, u32 cpu, u32 pid); + void Init(uint8_t* data, const perf_event_attr& attr) override; bool GetBinary1(std::vector &buf) const; bool GetBinary(std::vector &buf) const override; @@ -186,12 +182,9 @@ public: virtual size_t GetSize() const override; }; -class PerfRecordMmap : public PerfEventRecord { +class PerfRecordMmap : public PerfEventRecordTemplate { public: - PerfRecordMmapData data_; - - explicit PerfRecordMmap(uint8_t *p); - + PerfRecordMmap() = default; PerfRecordMmap(bool inKernel, u32 pid, u32 tid, u64 addr, u64 len, u64 pgoff, const std::string &filename); @@ -200,11 +193,10 @@ public: void DumpLog(const std::string &prefix) const override; }; -class PerfRecordMmap2 : public PerfEventRecord { +class PerfRecordMmap2 : public PerfEventRecordTemplate { public: - PerfRecordMmap2Data data_; - explicit PerfRecordMmap2(uint8_t *p); + PerfRecordMmap2() = default; PerfRecordMmap2(bool inKernel, u32 pid, u32 tid, u64 addr, u64 len, u64 pgoff, u32 maj, u32 min, u64 ino, u32 prot, u32 flags, const std::string &filename); @@ -217,31 +209,28 @@ public: bool discard_ = false; }; -class PerfRecordLost : public PerfEventRecord { +class PerfRecordLost : public PerfEventRecordTemplate { public: - PerfRecordLostData data_; - explicit PerfRecordLost(uint8_t *p); + PerfRecordLost() = default; bool GetBinary(std::vector &buf) const override; void DumpData(int indent) const override; // only for UT PerfRecordLost(bool inKernel, u64 id, u64 lost) - : PerfEventRecord(PERF_RECORD_LOST, inKernel, "lost") { + PerfEventRecord::Init(PERF_RECORD_LOST, inKernel); data_.id = id; data_.lost = lost; - header.size = sizeof(header) + sizeof(data_); + header_.size = sizeof(header_) + sizeof(data_); } }; -class PerfRecordComm : public PerfEventRecord { +class PerfRecordComm : public PerfEventRecordTemplate { public: - PerfRecordCommData data_; - - explicit PerfRecordComm(uint8_t *p); + PerfRecordComm() = default; PerfRecordComm(bool inKernel, u32 pid, u32 tid, const std::string &comm); bool GetBinary(std::vector &buf) const override; @@ -249,9 +238,8 @@ public: void DumpLog(const std::string &prefix) const override; }; -class PerfRecordSample : public PerfEventRecord { +class PerfRecordSample : public PerfEventRecordTemplate { public: - PerfRecordSampleData data_ = {}; uint64_t sampleType_ = SAMPLE_TYPE; uint64_t skipKernel_ = 0; uint64_t skipPid_ = 0; @@ -262,11 +250,15 @@ public: static std::vector callFrames_; static std::vector serverPidMap_; + PerfRecordSample() = default; + PerfRecordSample(const PerfRecordSample& sample); + // referenced input(p) in PerfRecordSample, require caller keep input(p) together + void Init(uint8_t* data, const perf_event_attr& attr) override; + StackId stackId_ {0}; bool removeStack_ {false}; - inline static bool dumpRemoveStack_ {false}; - // referenced input(p) in PerfRecordSample, require caller keep input(p) together - PerfRecordSample(uint8_t *p, const perf_event_attr &attr); + static void SetDumpRemoveStack(bool dumpRemoveStack); + static bool IsDumpRemoveStack(); bool GetBinary(std::vector &buf) const override; void DumpData(int indent = 0) const override; void DumpLog(const std::string &prefix) const override; @@ -279,56 +271,50 @@ public: // only for UT PerfRecordSample(bool inKernel, u32 pid, u32 tid, u64 period = 0, u64 time = 0, u64 id = 0) - : PerfEventRecord(PERF_RECORD_SAMPLE, inKernel, "sample") { + PerfEventRecord::Init(PERF_RECORD_SAMPLE, inKernel); Clean(); data_.pid = pid; data_.tid = tid; data_.period = period; data_.time = time; data_.id = 0; - header.size = sizeof(header) + sizeof(data_); - }; + header_.size = sizeof(header_) + sizeof(data_); + } pid_t GetUstackServerPid(); pid_t GetServerPidof(unsigned int ipNr); +private: + static bool dumpRemoveStack_; }; -class PerfRecordExit : public PerfEventRecord { +class PerfRecordExit : public PerfEventRecordTemplate { public: - PerfRecordExitData data_; - - explicit PerfRecordExit(uint8_t *p); + PerfRecordExit() = default; bool GetBinary(std::vector &buf) const override; void DumpData(int indent) const override; }; -class PerfRecordThrottle : public PerfEventRecord { +class PerfRecordThrottle : public PerfEventRecordTemplate { public: - PerfRecordThrottleData data_; - - PerfRecordThrottle(uint8_t *p); + PerfRecordThrottle() = default; bool GetBinary(std::vector &buf) const override; void DumpData(int indent) const override; }; -class PerfRecordUnthrottle : public PerfEventRecord { +class PerfRecordUnthrottle : public PerfEventRecordTemplate { public: - PerfRecordThrottleData data_; - - explicit PerfRecordUnthrottle(uint8_t *p); + PerfRecordUnthrottle() = default; bool GetBinary(std::vector &buf) const override; void DumpData(int indent) const override; }; -class PerfRecordFork : public PerfEventRecord { +class PerfRecordFork : public PerfEventRecordTemplate { public: - PerfRecordForkData data_; - - explicit PerfRecordFork(uint8_t *p); + PerfRecordFork() = default; bool GetBinary(std::vector &buf) const override; void DumpData(int indent) const override; @@ -337,11 +323,10 @@ public: /* This record indicates a read event. */ -class PerfRecordRead : public PerfEventRecord { +class PerfRecordRead : public PerfEventRecordTemplate { public: - PerfRecordReadData data_; + PerfRecordRead() = default; - explicit PerfRecordRead(uint8_t *p); bool GetBinary(std::vector &buf) const override; void DumpData(int indent) const override; }; @@ -365,12 +350,11 @@ public: if set, then the data returned has overwritten previous data. */ -class PerfRecordAux : public PerfEventRecord { +class PerfRecordAux : public PerfEventRecordTemplate { public: uint64_t sampleType_ = SAMPLE_ID; - PerfRecordAuxData data_; + PerfRecordAux() = default; - explicit PerfRecordAux(uint8_t *p); bool GetBinary(std::vector &buf) const override; void DumpData(int indent) const override; }; @@ -386,11 +370,10 @@ public: tid thread ID of the thread starting an instruction trace. */ -class PerfRecordItraceStart : public PerfEventRecord { +class PerfRecordItraceStart : public PerfEventRecordTemplate { public: - PerfRecordItraceStartData data_; + PerfRecordItraceStart() = default; - explicit PerfRecordItraceStart(uint8_t *p); bool GetBinary(std::vector &buf) const override; void DumpData(int indent) const override; }; @@ -400,11 +383,10 @@ public: record indicates some number of samples that may have been lost. */ -class PerfRecordLostSamples : public PerfEventRecord { +class PerfRecordLostSamples : public PerfEventRecordTemplate { public: - PerfRecordLostSamplesData data_; + PerfRecordLostSamples() = default; - explicit PerfRecordLostSamples(uint8_t *p); bool GetBinary(std::vector &buf) const override; void DumpData(int indent) const override; }; @@ -415,12 +397,12 @@ public: indicates whether it was a context switch into or away from the current process. */ -class PerfRecordSwitch : public PerfEventRecord { +class PerfRecordSwitch : public PerfEventRecordTemplate { public: - PerfRecordSwitchData data_; - explicit PerfRecordSwitch(uint8_t *p); + PerfRecordSwitch() = default; + bool GetBinary(std::vector &buf) const override; - void DumpData([[maybe_unused]] int indent) const override {}; + void DumpData(int) const override {}; }; /* @@ -441,20 +423,30 @@ public: The thread ID of the previous (if switching in) or next (if switching out) thread on the CPU. */ -class PerfRecordSwitchCpuWide : public PerfEventRecord { +class PerfRecordSwitchCpuWide + : public PerfEventRecordTemplate { public: - PerfRecordSwitchCpuWideData data_; - explicit PerfRecordSwitchCpuWide(uint8_t *p); + PerfRecordSwitchCpuWide() = default; + bool GetBinary(std::vector &buf) const override; void DumpData(int indent) const override; }; -std::unique_ptr GetPerfEventRecord(const int type, uint8_t *p, - const perf_event_attr &attr); -std::unique_ptr GetPerfSampleFromCache(const int type, uint8_t *p, - const perf_event_attr &attr); -std::unique_ptr GetPerfSampleFromCacheMain(const int type, uint8_t *p, - const perf_event_attr &attr); +class PerfRecordNull : public PerfEventRecordTemplate { +public: + PerfRecordNull() = default; + + bool GetBinary(std::vector&) const override { return false; }; + void DumpData(int indent) const override {}; +}; + +class PerfEventRecordFactory { +public: + static PerfEventRecord& GetPerfEventRecord(PerfRecordType type, uint8_t* data, + const perf_event_attr& attr); +private: + static thread_local std::unordered_map recordMap_; +}; template void PushToBinary(bool condition, uint8_t *&p, const T &v); diff --git a/include/perf_events.h b/include/perf_events.h index f2daaa4..b5eaa3d 100644 --- a/include/perf_events.h +++ b/include/perf_events.h @@ -443,7 +443,7 @@ public: }; using StatCallBack = std::function> &)>; - using RecordCallBack = std::function)>; + using RecordCallBack = std::function; void SetStatCallBack(StatCallBack reportCallBack); void SetRecordCallBack(RecordCallBack recordCallBack); diff --git a/include/perf_file_reader.h b/include/perf_file_reader.h index cec2a29..6f9b11b 100644 --- a/include/perf_file_reader.h +++ b/include/perf_file_reader.h @@ -26,7 +26,7 @@ namespace OHOS { namespace Developtools { namespace HiPerf { -using ProcessRecordCB = const std::function record)>; +using ProcessRecordCB = const std::function; // read record from data file, like perf.data. // format of file follow // tools/perf/Documentation/perf.data-file-format.txt diff --git a/include/perf_file_writer.h b/include/perf_file_writer.h index ebcdbe4..f027c94 100644 --- a/include/perf_file_writer.h +++ b/include/perf_file_writer.h @@ -61,7 +61,7 @@ public: uint GetRecordCount() const; std::chrono::microseconds writeTimes_ = std::chrono::microseconds::zero(); - using ProcessRecordCB = const std::function record)>; + using ProcessRecordCB = const std::function; bool ReadDataSection(ProcessRecordCB &callback); bool ReadRecords(ProcessRecordCB &callback); bool Read(void *buf, size_t len); diff --git a/include/subcommand_dump.h b/include/subcommand_dump.h index 176bb14..2e7ddcc 100644 --- a/include/subcommand_dump.h +++ b/include/subcommand_dump.h @@ -107,10 +107,10 @@ private: void DumpPrintFileHeader(int indent = 0); void DumpAttrPortion(int indent = 0); void DumpDataPortion(int indent = 0); - void DumpCallChain(int indent, std::unique_ptr &sample); + void DumpCallChain(int indent, const PerfRecordSample& sample); void DumpFeaturePortion(int indent = 0); void DumpUniqueStackTableNode(int indent, const PerfFileSectionUniStackTable &uniStackTable); - void ExprotUserData(std::unique_ptr &record); + void ExprotUserData(PerfEventRecord& record); void ExprotUserStack(const PerfRecordSample &recordSample); void PrintHeaderInfo(const int &indent); void PrintSymbolFile(const int &indent, const SymbolFileStruct &symbolFileStruct); diff --git a/include/subcommand_record.h b/include/subcommand_record.h index 877369a..81f1b18 100644 --- a/include/subcommand_record.h +++ b/include/subcommand_record.h @@ -303,8 +303,8 @@ private: bool isSpe_ = false; // callback to process record - bool ProcessRecord(std::unique_ptr); - bool SaveRecord(std::unique_ptr, bool ptrReleaseFlag = false); + bool ProcessRecord(PerfEventRecord& record); + bool SaveRecord(const PerfEventRecord& record, bool ptrReleaseFlag = false); // file format like as 0,1-3,4-6,7,8 uint32_t GetCountFromFile(const std::string &fileName); @@ -327,7 +327,7 @@ private: void ReportTime(); #endif - bool CollectionSymbol(std::unique_ptr record); + bool CollectionSymbol(PerfEventRecord& record); void CollectSymbol(PerfRecordSample *sample); bool SetPerfLimit(const std::string& file, int value, std::function const& cmd, const std::string& param); diff --git a/include/subcommand_report.h b/include/subcommand_report.h index e7cfbd1..91c7b94 100644 --- a/include/subcommand_report.h +++ b/include/subcommand_report.h @@ -107,7 +107,7 @@ public: bool ParseOption(std::vector &args) override; void DumpOptions(void) const override; static bool RegisterSubCommandReport(void); - bool RecordCallBack(std::unique_ptr record); + bool RecordCallBack(PerfEventRecord& record); ~SubCommandReport(); diff --git a/include/utilities.h b/include/utilities.h index e4589f9..bad5069 100644 --- a/include/utilities.h +++ b/include/utilities.h @@ -345,29 +345,6 @@ bool IsArkJsFile(const std::string& filepath); std::string GetProcessName(int pid); bool NeedAdaptSandboxPath(char *filename, int pid, u16 &headerSize); bool NeedAdaptHMBundlePath(std::string& filename, const std::string& threadname); - -template -class ScopeGuard { -public: - explicit ScopeGuard(Func&& fn) - : fn_(fn) {} - ~ScopeGuard() - { - fn_(); - } -private: - Func fn_; -}; - -struct ScopeGuardOnExit {}; -template -static inline ScopeGuard operator+(ScopeGuardOnExit, Func&& fn) -{ - return ScopeGuard(std::forward(fn)); -} - -#define ON_SCOPE_EXIT \ - auto __onGuardExit__ = ScopeGuardOnExit{} + [&] } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/include/virtual_runtime.h b/include/virtual_runtime.h index 39fe3a3..0224989 100644 --- a/include/virtual_runtime.h +++ b/include/virtual_runtime.h @@ -51,7 +51,7 @@ public: // from the record , it will call back to write some Simulated Record // case 1. some mmap will be create when it read mmaps for each new process (from record sample) - using RecordCallBack = std::function)>; + using RecordCallBack = std::function; using CollectSymbolCallBack = std::function; void SetRecordMode(RecordCallBack recordCallBack); diff --git a/src/perf_event_record.cpp b/src/perf_event_record.cpp index 4edd038..51d9218 100644 --- a/src/perf_event_record.cpp +++ b/src/perf_event_record.cpp @@ -24,94 +24,50 @@ namespace OHOS { namespace Developtools { namespace HiPerf { -void *g_sampleMemCache = nullptr; // for read record from buf thread -void *g_sampleMemCacheMain = nullptr; // for main thread:collecttionsymbol -constexpr size_t SAMPLE_CACHE_SIZE = 4 * 1024; +bool PerfRecordSample::dumpRemoveStack_ = false; +thread_local std::unordered_map PerfEventRecordFactory::recordMap_ = {}; -std::unique_ptr GetPerfEventRecord(const int type, uint8_t *p, - const perf_event_attr &attr) +static PerfEventRecord* CreatePerfEventRecord(PerfRecordType type) { - HLOG_ASSERT(p); - uint8_t *data = p; - - // check kernel switch (type) { case PERF_RECORD_SAMPLE: - return std::make_unique(data, attr); + return new PerfRecordSample(); case PERF_RECORD_MMAP: - return std::make_unique(data); + return new PerfRecordMmap(); case PERF_RECORD_MMAP2: - return std::make_unique(data); + return new PerfRecordMmap2(); case PERF_RECORD_LOST: - return std::make_unique(data); + return new PerfRecordLost(); case PERF_RECORD_COMM: - return std::make_unique(data); + return new PerfRecordComm(); case PERF_RECORD_EXIT: - return std::make_unique(data); + return new PerfRecordExit(); case PERF_RECORD_THROTTLE: - return std::make_unique(data); + return new PerfRecordThrottle(); case PERF_RECORD_UNTHROTTLE: - return std::make_unique(data); + return new PerfRecordUnthrottle(); case PERF_RECORD_FORK: - return std::make_unique(data); + return new PerfRecordFork(); case PERF_RECORD_READ: - return std::make_unique(data); + return new PerfRecordRead(); case PERF_RECORD_AUX: - return std::make_unique(data); + return new PerfRecordAux(); case PERF_RECORD_AUXTRACE: - return std::make_unique(data); + return new PerfRecordAuxtrace(); case PERF_RECORD_ITRACE_START: - return std::make_unique(data); + return new PerfRecordItraceStart(); case PERF_RECORD_LOST_SAMPLES: - return std::make_unique(data); + return new PerfRecordLostSamples(); case PERF_RECORD_SWITCH: - return std::make_unique(data); + return new PerfRecordSwitch(); case PERF_RECORD_SWITCH_CPU_WIDE: - return std::make_unique(data); + return new PerfRecordSwitchCpuWide(); default: HLOGE("unknown record type %d\n", type); - return nullptr; + return new PerfRecordNull(); } } -std::unique_ptr GetPerfSampleFromCache(const int type, uint8_t *p, - const perf_event_attr &attr) -{ - HLOG_ASSERT(p); - uint8_t *data = p; - - if (type == PERF_RECORD_SAMPLE) { - if (g_sampleMemCache != nullptr) { - memset_s(g_sampleMemCache, SAMPLE_CACHE_SIZE, 0, SAMPLE_CACHE_SIZE); - return std::unique_ptr(new (g_sampleMemCache) PerfRecordSample(data, attr)); - } else { - g_sampleMemCache = std::malloc(SAMPLE_CACHE_SIZE); - memset_s(g_sampleMemCache, SAMPLE_CACHE_SIZE, 0, SAMPLE_CACHE_SIZE); - return std::unique_ptr(new (g_sampleMemCache) PerfRecordSample(data, attr)); - } - } - return GetPerfEventRecord(type, p, attr); -} - -std::unique_ptr GetPerfSampleFromCacheMain(const int type, uint8_t *p, - const perf_event_attr &attr) -{ - HLOG_ASSERT(p); - uint8_t *data = p; - - if (type == PERF_RECORD_SAMPLE) { - if (g_sampleMemCacheMain != nullptr) { - memset_s(g_sampleMemCacheMain, SAMPLE_CACHE_SIZE, 0, SAMPLE_CACHE_SIZE); - return std::unique_ptr(new (g_sampleMemCacheMain) PerfRecordSample(data, attr)); - } else { - g_sampleMemCacheMain = std::malloc(SAMPLE_CACHE_SIZE); - memset_s(g_sampleMemCacheMain, SAMPLE_CACHE_SIZE, 0, SAMPLE_CACHE_SIZE); - return std::unique_ptr(new (g_sampleMemCacheMain) PerfRecordSample(data, attr)); - } - } - return GetPerfEventRecord(type, p, attr); -} - template inline void PushToBinary(bool condition, uint8_t *&p, const T &v) { @@ -153,31 +109,29 @@ inline void PopFromBinary2(bool condition, uint8_t *&p, T1 &v1, T2 &v2) } // PerfEventRecord -PerfEventRecord::PerfEventRecord(perf_event_type type, bool inKernel, const std::string &name) - : name_(name) +void PerfEventRecord::Init(perf_event_type type, bool inKernel) { - header.type = type; - header.misc = inKernel ? PERF_RECORD_MISC_KERNEL : PERF_RECORD_MISC_USER; - header.size = sizeof(header); + header_.type = type; + header_.misc = inKernel ? PERF_RECORD_MISC_KERNEL : PERF_RECORD_MISC_USER; + header_.size = sizeof(header_); +}; + +void PerfEventRecord::Init(perf_event_hiperf_ext_type type) +{ + header_.type = type; + header_.misc = PERF_RECORD_MISC_USER; + header_.size = sizeof(header_); } -PerfEventRecord::PerfEventRecord(perf_event_hiperf_ext_type type, const std::string &name) - : name_(name) -{ - header.type = type; - header.misc = PERF_RECORD_MISC_USER; - header.size = sizeof(header); -} - -PerfEventRecord::PerfEventRecord(uint8_t *p, const std::string &name) : name_(name) +void PerfEventRecord::InitHeader(uint8_t* p) { if (p == nullptr) { - header.type = PERF_RECORD_MMAP; - header.misc = PERF_RECORD_MISC_USER; - header.size = 0; + header_.type = PERF_RECORD_MMAP; + header_.misc = PERF_RECORD_MISC_USER; + header_.size = 0; return; } - header = *(reinterpret_cast(p)); + header_ = *(reinterpret_cast(p)); } void PerfEventRecord::GetHeaderBinary(std::vector &buf) const @@ -186,7 +140,7 @@ void PerfEventRecord::GetHeaderBinary(std::vector &buf) const buf.resize(GetHeaderSize()); } uint8_t *p = buf.data(); - *(reinterpret_cast(p)) = header; + *(reinterpret_cast(p)) = header_; } void PerfEventRecord::Dump(int indent, std::string outputFilename, FILE *outputDump) const @@ -202,14 +156,14 @@ void PerfEventRecord::Dump(int indent, std::string outputFilename, FILE *outputD } } PRINT_INDENT(indent, "\n"); - PRINT_INDENT(indent, "record %s: type %u, misc %u, size %zu\n", GetName().c_str(), GetType(), + PRINT_INDENT(indent, "record %s: type %u, misc %u, size %zu\n", GetName(), GetType(), GetMisc(), GetSize()); DumpData(indent + 1); } void PerfEventRecord::DumpLog(const std::string &prefix) const { - HLOGV("%s: record %s: type %u, misc %u, size %zu\n", prefix.c_str(), GetName().c_str(), + HLOGV("%s: record %s: type %u, misc %u, size %zu\n", prefix.c_str(), GetName(), GetType(), GetMisc(), GetSize()); } @@ -217,22 +171,15 @@ std::vector PerfRecordSample::ips_ = {}; std::vector PerfRecordSample::callFrames_ = {}; std::vector PerfRecordSample::serverPidMap_ = {}; -PerfRecordAuxtrace::PerfRecordAuxtrace(uint8_t *p) : PerfEventRecord(p, "auxtrace") +void PerfRecordAuxtrace::Init(uint8_t* data, const perf_event_attr& attr) { - if (header.size >= sizeof(header)) { - size_t copySize = header.size - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordAuxtrace retren failed !!!"); - } - rawData_ = p + header.size; + PerfEventRecordTemplate::Init(data); + rawData_ = data + header_.size; } PerfRecordAuxtrace::PerfRecordAuxtrace(u64 size, u64 offset, u64 reference, u32 idx, u32 tid, u32 cpu, u32 pid) - : PerfEventRecord(PERF_RECORD_AUXTRACE, "auxtrace") { + PerfEventRecord::Init(PERF_RECORD_AUXTRACE); data_.size = size; data_.offset = offset; data_.reference = reference; @@ -241,19 +188,19 @@ PerfRecordAuxtrace::PerfRecordAuxtrace(u64 size, u64 offset, u64 reference, u32 data_.cpu = cpu; data_.reserved__ = pid; - header.size = sizeof(header) + sizeof(data_); + header_.size = sizeof(header_) + sizeof(data_); } bool PerfRecordAuxtrace::GetBinary1(std::vector &buf) const { - if (buf.size() < header.size) { - buf.resize(header.size); + if (buf.size() < header_.size) { + buf.resize(header_.size); } GetHeaderBinary(buf); uint8_t *p = buf.data() + GetHeaderSize(); - size_t copySize = header.size - GetHeaderSize(); + size_t copySize = header_.size - GetHeaderSize(); if (memcpy_s(p, sizeof(data_), reinterpret_cast(&data_), copySize) != 0) { HLOGE("memcpy_s return failed"); return false; @@ -270,12 +217,12 @@ bool PerfRecordAuxtrace::GetBinary(std::vector &buf) const GetHeaderBinary(buf); uint8_t *p = buf.data() + GetHeaderSize(); - size_t copySize = header.size - GetHeaderSize(); + size_t copySize = header_.size - GetHeaderSize(); if (memcpy_s(p, sizeof(data_), reinterpret_cast(&data_), copySize) != 0) { HLOGE("memcpy_s return failed"); return false; } - p += header.size - GetHeaderSize(); + p += header_.size - GetHeaderSize(); if (memcpy_s(p, data_.size, static_cast(rawData_), data_.size) != 0) { HLOGE("memcpy_s return failed"); return false; @@ -302,13 +249,13 @@ void PerfRecordAuxtrace::DumpLog(const std::string &prefix) const size_t PerfRecordAuxtrace::GetSize() const { - return header.size + data_.size; + return header_.size + data_.size; } void PerfRecordSample::DumpLog(const std::string &prefix) const { HLOGV("%s: SAMPLE: id= %llu size %d pid %u tid %u ips %llu regs %llu, stacks %llu time %llu", - prefix.c_str(), data_.sample_id, header.size, data_.pid, data_.tid, data_.nr, + prefix.c_str(), data_.sample_id, header_.size, data_.pid, data_.tid, data_.nr, data_.reg_nr, data_.dyn_size, data_.time); } @@ -352,15 +299,15 @@ void PerfRecordSample::ReplaceWithCallStack(size_t originalSize) } if (sampleType_ & PERF_SAMPLE_REGS_USER) { - header.size -= data_.reg_nr * sizeof(u64); + header_.size -= data_.reg_nr * sizeof(u64); data_.reg_nr = 0; data_.user_abi = 0; } if (sampleType_ & PERF_SAMPLE_STACK_USER) { // 1. remove the user stack - header.size -= data_.stack_size; - header.size -= sizeof(data_.dyn_size); + header_.size -= data_.stack_size; + header_.size -= sizeof(data_.dyn_size); // 2. clean the size data_.stack_size = 0; @@ -371,11 +318,11 @@ void PerfRecordSample::ReplaceWithCallStack(size_t originalSize) HLOGV("ips change from %llu -> %zu", data_.nr, ips_.size()); // 3. remove the nr size - header.size -= data_.nr * sizeof(u64); + header_.size -= data_.nr * sizeof(u64); // 4. add new nr size data_.nr = ips_.size(); - header.size += data_.nr * sizeof(u64); + header_.size += data_.nr * sizeof(u64); // 5. change ips potin to our ips array and hold it. data_.ips = ips_.data(); @@ -386,20 +333,21 @@ void PerfRecordSample::ReplaceWithCallStack(size_t originalSize) } } -PerfRecordSample::PerfRecordSample(uint8_t *p, const perf_event_attr &attr) - : PerfEventRecord(p, "sample") +void PerfRecordSample::Init(uint8_t *p, const perf_event_attr &attr) { - if (p == nullptr) { - HLOG_ASSERT(p); - return; - } - // clear the static vector data + PerfEventRecord::InitHeader(p); + + HLOG_ASSERT(p != nullptr); + // clear the vector data Clean(); sampleType_ = attr.sample_type; - + skipKernel_ = 0; + skipPid_ = 0; + stackId_ = {0}; + removeStack_ = false; + data_ = {}; uint8_t *start = p; - - p += sizeof(header); + p += sizeof(header_); // parse record according SAMPLE_TYPE PopFromBinary(sampleType_ & PERF_SAMPLE_IDENTIFIER, p, data_.sample_id); @@ -446,7 +394,7 @@ PerfRecordSample::PerfRecordSample(uint8_t *p, const perf_event_attr &attr) p += data_.stack_size; PopFromBinary(true, p, data_.dyn_size); } - uint32_t remain = header.size - (p - start); + uint32_t remain = header_.size - (p - start); if (data_.nr == 0 && dumpRemoveStack_ && remain == sizeof(stackId_)) { PopFromBinary(true, p, stackId_.value); } @@ -603,23 +551,11 @@ void PerfRecordSample::Clean() serverPidMap_.clear(); } -PerfRecordMmap::PerfRecordMmap(uint8_t *p) : PerfEventRecord(p, "mmap") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordMmap retren failed !!!"); - } -} - PerfRecordMmap::PerfRecordMmap(bool inKernel, u32 pid, u32 tid, u64 addr, u64 len, u64 pgoff, const std::string &filename) - : PerfEventRecord(PERF_RECORD_MMAP, inKernel, "mmap") { + PerfEventRecord::Init(PERF_RECORD_MMAP, inKernel); + data_.pid = pid; data_.tid = tid; data_.addr = addr; @@ -629,7 +565,7 @@ PerfRecordMmap::PerfRecordMmap(bool inKernel, u32 pid, u32 tid, u64 addr, u64 le HLOGE("strncpy_s failed"); } - header.size = sizeof(header) + sizeof(data_) - KILO + filename.size() + 1; + header_.size = sizeof(header_) + sizeof(data_) - KILO + filename.size() + 1; } bool PerfRecordMmap::GetBinary(std::vector &buf) const @@ -661,27 +597,14 @@ void PerfRecordMmap::DumpData(int indent) const void PerfRecordMmap::DumpLog(const std::string &prefix) const { HLOGV("%s: MMAP: size %d pid %u tid %u dso '%s' (0x%llx-0x%llx)@0x%llx", prefix.c_str(), - header.size, data_.pid, data_.tid, data_.filename, data_.addr, data_.addr + data_.len, data_.pgoff); -} - -PerfRecordMmap2::PerfRecordMmap2(uint8_t *p) : PerfEventRecord(p, "mmap2") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordMmap2 retren failed !!!"); - } + header_.size, data_.pid, data_.tid, data_.filename, data_.addr, data_.addr + data_.len, data_.pgoff); } PerfRecordMmap2::PerfRecordMmap2(bool inKernel, u32 pid, u32 tid, u64 addr, u64 len, u64 pgoff, u32 maj, u32 min, u64 ino, u32 prot, u32 flags, const std::string &filename) - : PerfEventRecord(PERF_RECORD_MMAP2, inKernel, "mmap2") { + PerfEventRecord::Init(PERF_RECORD_MMAP2, inKernel); data_.pid = pid; data_.tid = tid; data_.addr = addr; @@ -697,12 +620,12 @@ PerfRecordMmap2::PerfRecordMmap2(bool inKernel, u32 pid, u32 tid, u64 addr, u64 HLOGE("strncpy_s failed"); } - header.size = sizeof(header) + sizeof(data_) - KILO + filename.size() + 1; + header_.size = sizeof(header_) + sizeof(data_) - KILO + filename.size() + 1; } PerfRecordMmap2::PerfRecordMmap2(bool inKernel, u32 pid, u32 tid, std::shared_ptr item) - : PerfEventRecord(PERF_RECORD_MMAP2, inKernel, "mmap2") { + PerfEventRecord::Init(PERF_RECORD_MMAP2, inKernel); data_.pid = pid; data_.tid = tid; if (item != nullptr) { @@ -720,7 +643,7 @@ PerfRecordMmap2::PerfRecordMmap2(bool inKernel, u32 pid, u32 tid, std::shared_pt HLOGE("strncpy_s failed"); } - header.size = sizeof(header) + sizeof(data_) - KILO + item->name.size() + 1; + header_.size = sizeof(header_) + sizeof(data_) - KILO + item->name.size() + 1; } else { data_.addr = 0; data_.len = 0; @@ -763,26 +686,14 @@ void PerfRecordMmap2::DumpData(int indent) const } #endif } + void PerfRecordMmap2::DumpLog(const std::string &prefix) const { HLOGV("%s: MMAP2: size %d pid %u tid %u dso '%s' (0x%llx-0x%llx)@0x%llx", prefix.c_str(), - header.size, data_.pid, data_.tid, data_.filename, data_.addr, data_.addr + data_.len, + header_.size, data_.pid, data_.tid, data_.filename, data_.addr, data_.addr + data_.len, data_.pgoff); } -PerfRecordLost::PerfRecordLost(uint8_t *p) : PerfEventRecord(p, "lost") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordLost retren failed !!!"); - } -} - bool PerfRecordLost::GetBinary(std::vector &buf) const { if (buf.size() < GetSize()) { @@ -803,29 +714,17 @@ void PerfRecordLost::DumpData(int indent) const PRINT_INDENT(indent, "id %llu, lost %llu\n", data_.id, data_.lost); } -PerfRecordComm::PerfRecordComm(uint8_t *p) : PerfEventRecord(p, "comm") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordComm retren failed !!!"); - } -} PerfRecordComm::PerfRecordComm(bool inKernel, u32 pid, u32 tid, const std::string &comm) - : PerfEventRecord(PERF_RECORD_COMM, inKernel, "comm") { + PerfEventRecord::Init(PERF_RECORD_COMM, inKernel); data_.pid = pid; data_.tid = tid; if (strncpy_s(data_.comm, KILO, comm.c_str(), comm.size()) != 0) { HLOGE("strncpy_s failed !!!"); } - header.size = sizeof(header) + sizeof(data_) - KILO + comm.size() + 1; + header_.size = sizeof(header_) + sizeof(data_) - KILO + comm.size() + 1; } bool PerfRecordComm::GetBinary(std::vector &buf) const @@ -854,17 +753,31 @@ void PerfRecordComm::DumpLog(const std::string &prefix) const HLOGV("pid %u, tid %u, comm %s\n", data_.pid, data_.tid, data_.comm); } -PerfRecordExit::PerfRecordExit(uint8_t *p) : PerfEventRecord(p, "exit") +PerfRecordSample::PerfRecordSample(const PerfRecordSample& sample) { - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordExit retren failed !!!"); - } + header_ = sample.header_; + data_ = sample.data_; + + sampleType_ = sample.sampleType_; + skipKernel_ = sample.skipKernel_; + skipPid_ = sample.skipPid_; + + ips_ = sample.ips_; + callFrames_ = sample.callFrames_; + serverPidMap_ = sample.serverPidMap_; + + stackId_ = sample.stackId_; + removeStack_ = sample.removeStack_; +} + +void PerfRecordSample::SetDumpRemoveStack(bool dumpRemoveStack) +{ + dumpRemoveStack_ = dumpRemoveStack; +} + +bool PerfRecordSample::IsDumpRemoveStack() +{ + return dumpRemoveStack_; } bool PerfRecordExit::GetBinary(std::vector &buf) const @@ -887,19 +800,6 @@ void PerfRecordExit::DumpData(int indent) const data_.tid, data_.ptid, data_.time); } -PerfRecordThrottle::PerfRecordThrottle(uint8_t *p) : PerfEventRecord(p, "throttle") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordThrottle retren failed !!!"); - } -} - bool PerfRecordThrottle::GetBinary(std::vector &buf) const { if (buf.size() < GetSize()) { @@ -920,19 +820,6 @@ void PerfRecordThrottle::DumpData(int indent) const data_.stream_id); } -PerfRecordUnthrottle::PerfRecordUnthrottle(uint8_t *p) : PerfEventRecord(p, "unthrottle") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordUnthrottle retren failed !!!"); - } -} - bool PerfRecordUnthrottle::GetBinary(std::vector &buf) const { if (buf.size() < GetSize()) { @@ -946,25 +833,13 @@ bool PerfRecordUnthrottle::GetBinary(std::vector &buf) const *pDest = data_; return true; } + void PerfRecordUnthrottle::DumpData(int indent) const { PRINT_INDENT(indent, "time 0x%llx, id %llx, stream_id %llx\n", data_.time, data_.id, data_.stream_id); } -PerfRecordFork::PerfRecordFork(uint8_t *p) : PerfEventRecord(p, "fork") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordFork retren failed !!!"); - } -} - bool PerfRecordFork::GetBinary(std::vector &buf) const { if (buf.size() < GetSize()) { @@ -985,19 +860,6 @@ void PerfRecordFork::DumpData(int indent) const data_.ptid); } -PerfRecordRead::PerfRecordRead(uint8_t *p) : PerfEventRecord(p, "read") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordRead retren failed !!!"); - } -} - bool PerfRecordRead::GetBinary(std::vector &buf) const { if (buf.size() < GetSize()) { @@ -1019,19 +881,6 @@ void PerfRecordRead::DumpData(int indent) const data_.values.value, data_.values.timeEnabled, data_.values.timeRunning, data_.values.id); } -PerfRecordAux::PerfRecordAux(uint8_t *p) : PerfEventRecord(p, "aux") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordAux retren failed !!!"); - } -} - bool PerfRecordAux::GetBinary(std::vector &buf) const { if (buf.size() < GetSize()) { @@ -1061,19 +910,6 @@ void PerfRecordAux::DumpData(int indent) const data_.sample_id.time); } -PerfRecordItraceStart::PerfRecordItraceStart(uint8_t *p) : PerfEventRecord(p, "itraceStart") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordItraceStart retren failed !!!"); - } -} - bool PerfRecordItraceStart::GetBinary(std::vector &buf) const { if (buf.size() < GetSize()) { @@ -1093,19 +929,6 @@ void PerfRecordItraceStart::DumpData(int indent) const PRINT_INDENT(indent, "pid %u, tid %u\n", data_.pid, data_.tid); } -PerfRecordLostSamples::PerfRecordLostSamples(uint8_t *p) : PerfEventRecord(p, "lostSamples") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordLostSamples retren failed !!!"); - } -} - bool PerfRecordLostSamples::GetBinary(std::vector &buf) const { if (buf.size() < GetSize()) { @@ -1125,19 +948,6 @@ void PerfRecordLostSamples::DumpData(int indent) const PRINT_INDENT(indent, "lost %llu\n", data_.lost); } -PerfRecordSwitch::PerfRecordSwitch(uint8_t *p) : PerfEventRecord(p, "switch") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordSwitch retren failed !!!"); - } -} - bool PerfRecordSwitch::GetBinary(std::vector &buf) const { if (buf.size() < GetSize()) { @@ -1152,19 +962,6 @@ bool PerfRecordSwitch::GetBinary(std::vector &buf) const return true; } -PerfRecordSwitchCpuWide::PerfRecordSwitchCpuWide(uint8_t *p) : PerfEventRecord(p, "switchCpuWide") -{ - size_t dataSize = GetSize(); - if (dataSize >= sizeof(header)) { - size_t copySize = dataSize - sizeof(header); - if (memcpy_s(reinterpret_cast(&data_), sizeof(data_), p + sizeof(header), copySize) != 0) { - HLOGE("memcpy_s retren failed !!!"); - } - } else { - HLOGE("PerfRecordSwitchCpuWide retren failed !!!"); - } -} - bool PerfRecordSwitchCpuWide::GetBinary(std::vector &buf) const { if (buf.size() < GetSize()) { @@ -1244,6 +1041,23 @@ pid_t PerfRecordSample::GetServerPidof(unsigned int ipNr) return serverPidMap_[ipNr]; } } + +PerfEventRecord& PerfEventRecordFactory::GetPerfEventRecord(PerfRecordType type, uint8_t* data, + const perf_event_attr &attr) +{ + HLOG_ASSERT(data != nullptr); + PerfEventRecord* record = nullptr; + auto it = recordMap_.find(type); + if (it == recordMap_.end()) { + record = CreatePerfEventRecord(type); + recordMap_.emplace(type, record); + } else { + record = it->second; + } + record->Init(data, attr); + return *record; +} + } // namespace HiPerf } // namespace Developtools } // namespace OHOS diff --git a/src/perf_events.cpp b/src/perf_events.cpp index 11f0863..1650af4 100644 --- a/src/perf_events.cpp +++ b/src/perf_events.cpp @@ -117,16 +117,16 @@ void PerfEvents::ReadRecordsFromSpeMmaps(MmapFd& mmapFd, u64 auxOffset, u64 auxS arm_spe_reference(), cpu, tid, cpu, pid); static std::vector vbuf(RECORD_SIZE_LIMIT); uint8_t *buf; - if ((buf = recordBuf_->AllocForWrite(auxtraceRecord.header.size + auxSize)) == nullptr) { + if ((buf = recordBuf_->AllocForWrite(auxtraceRecord.header_.size + auxSize)) == nullptr) { HLOGD("alloc buffer failed: PerfRecordAuxtrace record, readSize: %llu", auxSize); return; } auxtraceRecord.GetBinary1(vbuf); - if (memcpy_s(buf, auxtraceRecord.header.size, vbuf.data(), auxtraceRecord.header.size) != 0) { + if (memcpy_s(buf, auxtraceRecord.header_.size, vbuf.data(), auxtraceRecord.header_.size) != 0) { HLOGE("memcpy_s return failed"); return; } - buf += auxtraceRecord.header.size; + buf += auxtraceRecord.header_.size; while (auxSize > 0) { u64 readSize = pageSize_; @@ -1624,7 +1624,7 @@ void PerfEvents::ReadRecordFromBuf() const auto readingStartTime_ = steady_clock::now(); #endif #if !HIDEBUG_SKIP_CALLBACK - recordCallBack_(GetPerfSampleFromCache(*type, p, *attr)); + recordCallBack_(PerfEventRecordFactory::GetPerfEventRecord(*type, p, *attr)); #endif recordEventCount_++; #ifdef HIPERF_DEBUG_TIME @@ -1643,7 +1643,7 @@ void PerfEvents::ReadRecordFromBuf() const auto readingStartTime_ = steady_clock::now(); #endif #if !HIDEBUG_SKIP_CALLBACK - recordCallBack_(GetPerfSampleFromCache(*type, p, *attr)); + recordCallBack_(PerfEventRecordFactory::GetPerfEventRecord(*type, p, *attr)); #endif recordEventCount_++; #ifdef HIPERF_DEBUG_TIME diff --git a/src/perf_file_reader.cpp b/src/perf_file_reader.cpp index 6f67390..a053ee2 100644 --- a/src/perf_file_reader.cpp +++ b/src/perf_file_reader.cpp @@ -278,20 +278,20 @@ bool PerfFileReader::ReadRecord(ProcessRecordCB &callback) } } uint8_t *data = buf; - std::unique_ptr record = GetPerfEventRecord( + PerfEventRecord& record = PerfEventRecordFactory::GetPerfEventRecord( static_cast(header->type), data, *attr); // unknown record , break the process - if (!record) { + if (record.GetName() == nullptr) { return false; } else { - HLOGV("record type %u", record->GetType()); + HLOGV("record type %u", record.GetType()); } remainingSize = remainingSize - header->size - speSize; #ifdef HIPERF_DEBUG_TIME const auto startCallbackTime = steady_clock::now(); #endif // call callback to process, then destroy record - callback(std::move(record)); + callback(record); recordNumber++; #ifdef HIPERF_DEBUG_TIME readCallbackTime_ += @@ -425,7 +425,7 @@ bool PerfFileReader::ReadFeatureSection() } else if (feature == FEATURE::HIPERF_FILES_UNISTACK_TABLE) { perfFileSections_.emplace_back( std::make_unique(feature, (char *)&buf[0], buf.size())); - PerfRecordSample::dumpRemoveStack_ = true; + PerfRecordSample::SetDumpRemoveStack(true); } else { HLOGW("still not imp how to process with feature %d", feature); } diff --git a/src/perf_file_writer.cpp b/src/perf_file_writer.cpp index 4fa75a9..72913a4 100644 --- a/src/perf_file_writer.cpp +++ b/src/perf_file_writer.cpp @@ -125,10 +125,10 @@ bool PerfFileWriter::WriteRecord(const PerfEventRecord &record) return false; } - HLOGV("write '%s', size %zu", record.GetName().c_str(), record.GetSize()); + HLOGV("write '%s', size %zu", record.GetName(), record.GetSize()); CHECK_TRUE(record.GetSize() > RECORD_SIZE_LIMIT_SPE, false, 1, - "%s record size exceed limit", record.GetName().c_str()); + "%s record size exceed limit", record.GetName()); // signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr 0xb64eb195 static std::vector buf(RECORD_SIZE_LIMIT_SPE); @@ -186,13 +186,13 @@ bool PerfFileWriter::ReadRecords(ProcessRecordCB &callback) } uint8_t *data = buf; // the record is allowed from a cache memory, does not free memory after use - auto record = GetPerfSampleFromCacheMain(static_cast(header->type), - data, defaultEventAttr_); + PerfEventRecord& record = PerfEventRecordFactory::GetPerfEventRecord( + static_cast(header->type), data, defaultEventAttr_); // skip unknown record - CHECK_TRUE(record == nullptr, true, 0, ""); + CHECK_TRUE(record.GetName() == nullptr, true, 0, ""); remainingSize = remainingSize - header->size - speSize; // call callback to process, do not destroy the record - callback(std::move(record)); + callback(record); recordNumber++; } } else { diff --git a/src/subcommand_dump.cpp b/src/subcommand_dump.cpp index e326368..069be66 100644 --- a/src/subcommand_dump.cpp +++ b/src/subcommand_dump.cpp @@ -405,13 +405,13 @@ void SubCommandDump::ExprotUserStack(const PerfRecordSample &recordSample) } } -void SubCommandDump::ExprotUserData(std::unique_ptr &record) +void SubCommandDump::ExprotUserData(PerfEventRecord& record) { - if (record->GetType() == PERF_RECORD_SAMPLE) { + if (record.GetType() == PERF_RECORD_SAMPLE) { if (currectSampleIndex_++ != exportSampleIndex_) { return; } - PerfRecordSample *recordSample = static_cast(record.get()); + PerfRecordSample* recordSample = static_cast(&record); ExprotUserStack(*recordSample); std::string userData = @@ -427,14 +427,14 @@ void SubCommandDump::ExprotUserData(std::unique_ptr &record) } } -void SubCommandDump::DumpCallChain(int indent, std::unique_ptr &sample) +void SubCommandDump::DumpCallChain(int indent, const PerfRecordSample& sample) { - PRINT_INDENT(indent, "\n callchain: %zu\n", sample->callFrames_.size()); - if (sample->callFrames_.size() > 0) { + PRINT_INDENT(indent, "\n callchain: %zu\n", sample.callFrames_.size()); + if (sample.callFrames_.size() > 0) { indent += indent + 1; - for (auto frameIt = sample->callFrames_.begin(); frameIt != sample->callFrames_.end(); + for (auto frameIt = sample.callFrames_.begin(); frameIt != sample.callFrames_.end(); frameIt++) { - PRINT_INDENT(indent, "%02zd:%s\n", std::distance(frameIt, sample->callFrames_.end()), + PRINT_INDENT(indent, "%02zd:%s\n", std::distance(frameIt, sample.callFrames_.end()), frameIt->ToSymbolString().c_str()); } } @@ -443,8 +443,8 @@ void SubCommandDump::DumpCallChain(int indent, std::unique_ptr void SubCommandDump::DumpDataPortion(int indent) { int recordCount = 0; - auto recordcCallback = [&](std::unique_ptr record) { - CHECK_TRUE(record == nullptr, false, 0, ""); // return false in callback can stop the read process + auto recordcCallback = [&](PerfEventRecord& record) { + CHECK_TRUE(record.GetName() == nullptr, false, 0, ""); // return false in callback can stop the read process // for UT if (exportSampleIndex_ > 0) { @@ -452,15 +452,13 @@ void SubCommandDump::DumpDataPortion(int indent) } // tell process tree what happend for rebuild symbols - vr_.UpdateFromRecord(*record); + vr_.UpdateFromRecord(record); recordCount++; - record->Dump(indent, outputFilename_, g_outputDump); + record.Dump(indent, outputFilename_, g_outputDump); - if (record->GetType() == PERF_RECORD_SAMPLE) { - std::unique_ptr sample( - static_cast(record.release())); - DumpCallChain(indent, sample); + if (record.GetType() == PERF_RECORD_SAMPLE) { + DumpCallChain(indent, static_cast(record)); } return true; diff --git a/src/subcommand_record.cpp b/src/subcommand_record.cpp index 754f5dd..1492ebd 100644 --- a/src/subcommand_record.cpp +++ b/src/subcommand_record.cpp @@ -811,8 +811,8 @@ void SubCommandRecord::RecoverSavedCmdlinesSize() bool SubCommandRecord::PreparePerfEvent() { // we need to notify perfEvents_ sampling mode by SetRecordCallBack first - auto processRecord = [this](std::unique_ptr record) -> bool { - return this->ProcessRecord(std::move(record)); + auto processRecord = [this](PerfEventRecord& record) -> bool { + return this->ProcessRecord(record); }; perfEvents_.SetRecordCallBack(processRecord); @@ -897,8 +897,8 @@ bool SubCommandRecord::PrepareSysKernel() bool SubCommandRecord::PrepareVirtualRuntime() { - auto saveRecord = [this](std::unique_ptr record) -> bool { - return this->SaveRecord(std::move(record), false); + auto saveRecord = [this](PerfEventRecord& record) -> bool { + return this->SaveRecord(record, false); }; virtualRuntime_.SetRecordMode(saveRecord); @@ -1323,21 +1323,17 @@ void SubCommandRecord::RemoveVdsoTmpFile() } } -bool SubCommandRecord::ProcessRecord(std::unique_ptr record) +bool SubCommandRecord::ProcessRecord(PerfEventRecord& record) { - CHECK_TRUE(record == nullptr, false, 1, "record is null"); + CHECK_TRUE(record.GetName() == nullptr, false, 1, "record is null"); #if HIDEBUG_RECORD_NOT_PROCESS // some times we want to check performance // but we still want to see the record number - if (record->GetType() == PERF_RECORD_SAMPLE) { + if (record.GetType() == PERF_RECORD_SAMPLE) { recordSamples_++; } else { recordNoSamples_++; } - if (record->GetType() == PERF_RECORD_SAMPLE) { - // when the record is allowed from a cache memory, does not free memory after use - record.release(); - } return true; #else #ifdef HIPERF_DEBUG_TIME @@ -1345,11 +1341,7 @@ bool SubCommandRecord::ProcessRecord(std::unique_ptr record) #endif if (excludeHiperf_) { static pid_t pid = getpid(); - if (record->GetPid() == pid) { - if (record->GetType() == PERF_RECORD_SAMPLE) { - // when the record is allowed from a cache memory, does not free memory after use - record.release(); - } + if (record.GetPid() == pid) { // discard record return true; } @@ -1358,23 +1350,17 @@ bool SubCommandRecord::ProcessRecord(std::unique_ptr record) // May create some simulated events // it will call ProcessRecord before next line #if !HIDEBUG_RECORD_NOT_PROCESS_VM - virtualRuntime_.UpdateFromRecord(*record); + virtualRuntime_.UpdateFromRecord(record); #endif #ifdef HIPERF_DEBUG_TIME prcessRecordTimes_ += duration_cast(steady_clock::now() - startTime); #endif - return SaveRecord(std::move(record), true); + return SaveRecord(record, true); #endif } -bool SubCommandRecord::SaveRecord(std::unique_ptr record, bool ptrReleaseFlag) +bool SubCommandRecord::SaveRecord(const PerfEventRecord& record, bool ptrReleaseFlag) { - ON_SCOPE_EXIT { - if (ptrReleaseFlag && record->GetType() == PERF_RECORD_SAMPLE) { - // when the record is allowed from a cache memory, does not free memory after use - record.release(); - } - }; #if HIDEBUG_RECORD_NOT_SAVE return true; #endif @@ -1389,22 +1375,22 @@ bool SubCommandRecord::SaveRecord(std::unique_ptr record, bool } } - if (record) { + if (record.GetName() != nullptr) { #ifdef HIPERF_DEBUG_TIME const auto saveTime = steady_clock::now(); #endif - if (!fileWriter_->WriteRecord(*record)) { + if (!fileWriter_->WriteRecord(record)) { // write file failed, need stop record perfEvents_.StopTracking(); - HLOGV("fail to write record %s", record->GetName().c_str()); + HLOGV("fail to write record %s", record.GetName()); return false; } - if (record->GetType() == PERF_RECORD_SAMPLE) { + if (record.GetType() == PERF_RECORD_SAMPLE) { recordSamples_++; } else { recordNoSamples_++; } - HLOGV(" write done. size=%zu name=%s", record->GetSize(), record->GetName().c_str()); + HLOGV(" write done. size=%zu name=%s", record.GetSize(), record.GetName()); #ifdef HIPERF_DEBUG_TIME saveRecordTimes_ += duration_cast(steady_clock::now() - saveTime); #endif @@ -1620,15 +1606,15 @@ bool SubCommandRecord::PostProcessRecordFile() } // 2. read out the file and unwind - auto record_callback = [&](std::unique_ptr record) { - if (record == nullptr) { + auto record_callback = [&](PerfEventRecord& record) { + if (record.GetName() == nullptr) { // return false in callback can stop the read process return false; - } else if (record->GetType() == PERF_RECORD_SAMPLE) { + } else if (record.GetType() == PERF_RECORD_SAMPLE) { HLOGM("readback record for unwind"); - virtualRuntime_.UnwindFromRecord(static_cast(*record)); + virtualRuntime_.UnwindFromRecord(static_cast(record)); } - SaveRecord(std::move(record)); + SaveRecord(record); return true; }; fileReader->ReadDataSection(record_callback); @@ -1669,22 +1655,20 @@ void SubCommandRecord::SymbolicHits() } #endif -bool SubCommandRecord::CollectionSymbol(std::unique_ptr record) +bool SubCommandRecord::CollectionSymbol(PerfEventRecord& record) { - CHECK_TRUE(record == nullptr, false, 0, ""); - if (record->GetType() == PERF_RECORD_SAMPLE) { - PerfRecordSample *sample = static_cast(record.get()); + CHECK_TRUE(record.GetName() == nullptr, false, 0, ""); + if (record.GetType() == PERF_RECORD_SAMPLE) { + PerfRecordSample* sample = static_cast(&record); #if USE_COLLECT_SYMBOLIC CollectSymbol(sample); #else virtualRuntime_.SymbolicRecord(*sample); #endif - // the record is allowed from a cache memory, does not free memory after use - record.release(); } - if (isSpe_ && record->GetType() == PERF_RECORD_AUXTRACE) { - PerfRecordAuxtrace *sample = static_cast(record.get()); + if (isSpe_ && record.GetType() == PERF_RECORD_AUXTRACE) { + PerfRecordAuxtrace* sample = static_cast(&record); virtualRuntime_.SymbolSpeRecord(*sample); } @@ -1694,7 +1678,7 @@ bool SubCommandRecord::CollectionSymbol(std::unique_ptr record) void SubCommandRecord::CollectSymbol(PerfRecordSample *sample) { CHECK_TRUE(sample == nullptr, NO_RETVAL, 0, ""); - perf_callchain_context context = sample->inKernel() ? PERF_CONTEXT_KERNEL + perf_callchain_context context = sample->InKernel() ? PERF_CONTEXT_KERNEL : PERF_CONTEXT_USER; pid_t serverPid; // if no nr use ip ? remove stack nr == 0? @@ -1754,8 +1738,8 @@ bool SubCommandRecord::FinishWriteRecordFile() virtualRuntime_.CollectDedupSymbol(kernelSymbolsHits_, userSymbolsHits_); } else { fileWriter_->ReadDataSection( - [this] (std::unique_ptr record) -> bool { - return this->CollectionSymbol(std::move(record)); + [this] (PerfEventRecord& record) -> bool { + return this->CollectionSymbol(record); }); } #if USE_COLLECT_SYMBOLIC diff --git a/src/subcommand_report.cpp b/src/subcommand_report.cpp index 0a43a84..5ae0ef8 100644 --- a/src/subcommand_report.cpp +++ b/src/subcommand_report.cpp @@ -223,13 +223,14 @@ void SubCommandReport::ProcessSample(std::unique_ptr &sample) } } -bool SubCommandReport::RecordCallBack(std::unique_ptr record) +bool SubCommandReport::RecordCallBack(PerfEventRecord& record) { // tell process tree what happend for rebuild symbols - GetReport().virtualRuntime_.UpdateFromRecord(*record); + GetReport().virtualRuntime_.UpdateFromRecord(record); - if (record->GetType() == PERF_RECORD_SAMPLE) { - std::unique_ptr sample(static_cast(record.release())); + if (record.GetType() == PERF_RECORD_SAMPLE) { + std::unique_ptr sample + = std::make_unique(static_cast(record)); std::unique_ptr prevSample = nullptr; if (cpuOffMode_) { auto prevIt = prevSampleCache_.find(sample->data_.tid); @@ -264,7 +265,7 @@ bool SubCommandReport::RecordCallBack(std::unique_ptr record) } else { #if defined(HAVE_PROTOBUF) && HAVE_PROTOBUF if (protobufFormat_) { - protobufOutputFileWriter_->ProcessRecord(*record); + protobufOutputFileWriter_->ProcessRecord(record); } #endif } @@ -478,8 +479,8 @@ bool SubCommandReport::LoadPerfData() // before load data section SetHM(); recordFileReader_->ReadDataSection( - [this] (std::unique_ptr record) -> bool { - return this->RecordCallBack(std::move(record)); + [this] (PerfEventRecord& record) -> bool { + return this->RecordCallBack(record); }); if (cpuOffMode_) { FlushCacheRecord(); diff --git a/src/virtual_runtime.cpp b/src/virtual_runtime.cpp index db447e9..64b8851 100644 --- a/src/virtual_runtime.cpp +++ b/src/virtual_runtime.cpp @@ -148,7 +148,7 @@ VirtualThread &VirtualRuntime::CreateThread(pid_t pid, pid_t tid, const std::str thread.name_.c_str(), thread.GetMaps().size()); // we need make a PerfRecordComm auto commRecord = std::make_unique(IsKernelThread(pid), pid, tid, thread.name_); - recordCallBack_(std::move(commRecord)); + recordCallBack_(*commRecord); // only work for pid if (pid == tid) { if (isHM_) { @@ -169,7 +169,7 @@ VirtualThread &VirtualRuntime::CreateThread(pid_t pid, pid_t tid, const std::str HLOGD("make PerfRecordMmap2 %d:%d:%s:%s(0x%" PRIx64 "-0x%" PRIx64 ")@%" PRIx64 " ", thread.pid_, thread.tid_, thread.name_.c_str(), map->name.c_str(), map->begin, map->end, map->offset); - recordCallBack_(std::move(mmapRecord)); + recordCallBack_(*mmapRecord); if (updateNormalSymbol) { UpdateSymbols(map, pid); } @@ -286,7 +286,7 @@ void VirtualRuntime::UpdateKernelModulesSpaceMaps() for (const auto &map : koMaps) { auto record = std::make_unique(true, 0, 0, map.begin, map.end - map.begin, 0, map.name); - recordCallBack_(std::move(record)); + recordCallBack_(*record); } } std::move(koMaps.begin(), koMaps.end(), std::back_inserter(kernelSpaceMemMaps_)); @@ -299,7 +299,7 @@ void VirtualRuntime::UpdateKernelSpaceMaps() if (recordCallBack_) { auto record = std::make_unique(true, 0, 0, map.begin, map.end - map.begin, 0, map.name); - recordCallBack_(std::move(record)); + recordCallBack_(*record); } } @@ -338,7 +338,7 @@ void VirtualRuntime::UpdateKernelSymbols() kernelFile->textExecVaddrFileOffset_, KERNEL_MMAP_NAME); if (recordCallBack_) { - recordCallBack_(std::move(record)); + recordCallBack_(*record); } symbolsFiles_.emplace_back(std::move(kernelFile)); } else { @@ -395,7 +395,7 @@ void VirtualRuntime::DedupFromRecord(PerfRecordSample *recordSample) } // callstack dedup success recordSample->stackId_.value = stackId.value; - recordSample->header.size -= (sizeof(u64) * nr - sizeof(stackId)); + recordSample->header_.size -= (sizeof(u64) * nr - sizeof(stackId)); recordSample->data_.nr = 0; recordSample->data_.ips = nullptr; recordSample->removeStack_ = true; @@ -558,7 +558,7 @@ void VirtualRuntime::NeedDropKernelCallChain(PerfRecordSample &sample) { // only do this in record mode. if (recordCallBack_ == nullptr || needkernelCallChain_ || - !sample.inKernel() || sample.data_.nr == 0) { + !sample.InKernel() || sample.data_.nr == 0) { return; } @@ -575,11 +575,11 @@ void VirtualRuntime::NeedDropKernelCallChain(PerfRecordSample &sample) } sample.skipKernel_ = skip; sample.data_.nr -= skip; - sample.header.size -= sizeof(u64) * skip; + sample.header_.size -= sizeof(u64) * skip; if (sample.data_.server_nr > 0) { sample.skipPid_ = skipPid; sample.data_.server_nr -= skipPid; - sample.header.size -= sizeof(u64) * skipPid; + sample.header_.size -= sizeof(u64) * skipPid; } } @@ -661,9 +661,9 @@ void VirtualRuntime::UpdateFromRecord(PerfRecordSample &recordSample) void VirtualRuntime::UpdateFromRecord(PerfRecordMmap &recordMmap) { - HLOGV(" MMAP: size %d pid %u tid %u", recordMmap.header.size, recordMmap.data_.pid, + HLOGV(" MMAP: size %d pid %u tid %u", recordMmap.header_.size, recordMmap.data_.pid, recordMmap.data_.tid); - HLOGV(" MMAP: %s dso '%s' (0x%llx-0x%llx)@0x%llx", recordMmap.inKernel() ? "kernel" : "user", + HLOGV(" MMAP: %s dso '%s' (0x%llx-0x%llx)@0x%llx", recordMmap.InKernel() ? "kernel" : "user", recordMmap.data_.filename, recordMmap.data_.addr, recordMmap.data_.addr + recordMmap.data_.len, recordMmap.data_.pgoff); // kernel mmap @@ -671,12 +671,12 @@ void VirtualRuntime::UpdateFromRecord(PerfRecordMmap &recordMmap) if (IsKernelThread(recordMmap.data_.pid)) { UpdateKernelThreadMap(recordMmap.data_.pid, recordMmap.data_.addr, recordMmap.data_.len, recordMmap.data_.filename); - } else if (recordMmap.inKernel()) { + } else if (recordMmap.InKernel()) { UpdatekernelMap(recordMmap.data_.addr, recordMmap.data_.addr + recordMmap.data_.len, recordMmap.data_.pgoff, recordMmap.data_.filename); } else { - NeedAdaptSandboxPath(recordMmap.data_.filename, recordMmap.data_.pid, recordMmap.header.size); - FixHMBundleMmap(recordMmap.data_.filename, recordMmap.data_.pid, recordMmap.header.size); + NeedAdaptSandboxPath(recordMmap.data_.filename, recordMmap.data_.pid, recordMmap.header_.size); + FixHMBundleMmap(recordMmap.data_.filename, recordMmap.data_.pid, recordMmap.header_.size); auto map = UpdateThreadMaps(recordMmap.data_.pid, recordMmap.data_.tid, recordMmap.data_.filename, recordMmap.data_.addr, recordMmap.data_.len, recordMmap.data_.pgoff); UpdateSymbols(map, recordMmap.data_.pid); @@ -715,11 +715,11 @@ bool VirtualRuntime::CheckValidSandBoxMmap(PerfRecordMmap2 &recordMmap2) u64 len = elfLoadInfoMap[0].mmapLen; u64 pgoff = elfLoadInfoMap[0].offset & (~(elfLoadInfoMap[0].align >= 1 ? elfLoadInfoMap[0].align - 1 : 0)); std::unique_ptr mmap2FirstSeg = - std::make_unique(recordMmap2.inKernel(), recordMmap2.data_.pid, recordMmap2.data_.tid, + std::make_unique(recordMmap2.InKernel(), recordMmap2.data_.pid, recordMmap2.data_.tid, begin, len, pgoff, 0, 0, 0, PROT_READ, 0, std::string(recordMmap2.data_.filename)); UpdateThreadMaps(mmap2FirstSeg->data_.pid, mmap2FirstSeg->data_.tid, mmap2FirstSeg->data_.filename, mmap2FirstSeg->data_.addr, mmap2FirstSeg->data_.len, mmap2FirstSeg->data_.pgoff); - recordCallBack_(std::move(mmap2FirstSeg)); + recordCallBack_(*mmap2FirstSeg); } else { auto elfLoadInfoMap = symFile->GetPtLoads(); u64 begin = recordMmap2.data_.addr - elfLoadInfoMap[0].mmapLen; @@ -727,21 +727,21 @@ bool VirtualRuntime::CheckValidSandBoxMmap(PerfRecordMmap2 &recordMmap2) u64 pgoff = elfLoadInfoMap[0].offset & (~(elfLoadInfoMap[0].align >= 1 ? elfLoadInfoMap[0].align - 1 : 0)); std::unique_ptr mmap2FirstSeg = - std::make_unique(recordMmap2.inKernel(), recordMmap2.data_.pid, recordMmap2.data_.tid, + std::make_unique(recordMmap2.InKernel(), recordMmap2.data_.pid, recordMmap2.data_.tid, begin, len, pgoff, 0, 0, 0, PROT_READ, 0, curMap->name); UpdateThreadMaps(mmap2FirstSeg->data_.pid, mmap2FirstSeg->data_.tid, curMap->name, mmap2FirstSeg->data_.addr, mmap2FirstSeg->data_.len, mmap2FirstSeg->data_.pgoff); - recordCallBack_(std::move(mmap2FirstSeg)); + recordCallBack_(*mmap2FirstSeg); std::unique_ptr mmap2SecondSegment = - std::make_unique(recordMmap2.inKernel(), recordMmap2.data_.pid, recordMmap2.data_.tid, + std::make_unique(recordMmap2.InKernel(), recordMmap2.data_.pid, recordMmap2.data_.tid, recordMmap2.data_.addr, recordMmap2.data_.len, recordMmap2.data_.pgoff - prevMap->offset, // minus load offset of hap 0, 0, 0, recordMmap2.data_.prot, 0, curMap->name); UpdateThreadMaps(mmap2SecondSegment->data_.pid, mmap2SecondSegment->data_.tid, curMap->name, mmap2SecondSegment->data_.addr, mmap2SecondSegment->data_.len, mmap2SecondSegment->data_.pgoff); - recordCallBack_(std::move(mmap2SecondSegment)); + recordCallBack_(*mmap2SecondSegment); recordMmap2.discard_ = true; } symbolsFiles_.emplace_back(std::move(symFile)); @@ -769,15 +769,15 @@ void VirtualRuntime::UpdateFromRecord(PerfRecordMmap2 &recordMmap2) return; } - HLOGV(" MMAP2: size %d pid %u tid %u", recordMmap2.header.size, recordMmap2.data_.pid, + HLOGV(" MMAP2: size %d pid %u tid %u", recordMmap2.header_.size, recordMmap2.data_.pid, recordMmap2.data_.tid); - HLOGV(" MMAP2: %s dso '%s' (0x%llx-0x%llx)@0x%llx prot:%u", recordMmap2.inKernel() ? "kernel" : "user", + HLOGV(" MMAP2: %s dso '%s' (0x%llx-0x%llx)@0x%llx prot:%u", recordMmap2.InKernel() ? "kernel" : "user", recordMmap2.data_.filename, recordMmap2.data_.addr, recordMmap2.data_.addr + recordMmap2.data_.len, recordMmap2.data_.pgoff, recordMmap2.data_.prot); if (recordCallBack_) { - if (NeedAdaptSandboxPath(recordMmap2.data_.filename, recordMmap2.data_.pid, recordMmap2.header.size)) { - FixHMBundleMmap(recordMmap2.data_.filename, recordMmap2.data_.pid, recordMmap2.header.size); + if (NeedAdaptSandboxPath(recordMmap2.data_.filename, recordMmap2.data_.pid, recordMmap2.header_.size)) { + FixHMBundleMmap(recordMmap2.data_.filename, recordMmap2.data_.pid, recordMmap2.header_.size); CHECK_TRUE(!CheckValidSandBoxMmap(recordMmap2), NO_RETVAL, 0, ""); } } @@ -1258,7 +1258,7 @@ void VirtualRuntime::UpdateServiceSpaceMaps() std::make_unique(true, SYSMGR_PID, SYSMGR_PID, map->begin, map->end - map->begin, 0, SYSMGR_FILE_NAME); - recordCallBack_(std::move(record)); + recordCallBack_(*record); } } } @@ -1296,7 +1296,7 @@ void VirtualRuntime::UpdateDevhostSpaceMaps() std::make_unique(false, devhostPid_, devhostPid_, map->begin, map->end - map->begin, 0, map->name); - recordCallBack_(std::move(record)); + recordCallBack_(*record); } } } diff --git a/test/fuzztest/perffile_fuzzer/PerfFile_fuzzer.cpp b/test/fuzztest/perffile_fuzzer/PerfFile_fuzzer.cpp index e2faedd..4c080e5 100644 --- a/test/fuzztest/perffile_fuzzer/PerfFile_fuzzer.cpp +++ b/test/fuzztest/perffile_fuzzer/PerfFile_fuzzer.cpp @@ -73,7 +73,7 @@ bool FuzzPerfFileReader(const uint8_t *data, size_t size) } reader->ReadFeatureSection(); - auto recordCallback = [&](const std::unique_ptr &record) { + auto recordCallback = [&](PerfEventRecord& record) { // nothing to do return true; }; diff --git a/test/unittest/common/native/perf_event_record_test.cpp b/test/unittest/common/native/perf_event_record_test.cpp index a060e42..ed05e08 100644 --- a/test/unittest/common/native/perf_event_record_test.cpp +++ b/test/unittest/common/native/perf_event_record_test.cpp @@ -16,6 +16,7 @@ #include "perf_event_record_test.h" #include +#include using namespace testing::ext; using namespace std; @@ -80,7 +81,8 @@ HWTEST_F(PerfEventRecordTest, Mmap, TestSize.Level1) size_t buffSize = HEADER_SIZE + sizeof(PerfRecordMmapData) - KILO + strlen(data.filename) + 1; ASSERT_EQ(recordIn.GetSize(), buffSize); - PerfRecordMmap recordOut(buff.data()); + PerfRecordMmap recordOut; + recordOut.Init(buff.data()); ASSERT_EQ(recordOut.GetType(), PERF_RECORD_MMAP); ASSERT_EQ(recordOut.GetName(), RECORDNAME_MMAP); ASSERT_EQ(recordOut.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -115,7 +117,8 @@ HWTEST_F(PerfEventRecordTest, Mmap2, TestSize.Level1) size_t buffSize = HEADER_SIZE + sizeof(PerfRecordMmap2Data) - KILO + strlen(data.filename) + 1; ASSERT_EQ(recordIn.GetSize(), buffSize); - PerfRecordMmap2 recordOut(buff.data()); + PerfRecordMmap2 recordOut; + recordOut.Init(buff.data()); ASSERT_EQ(recordOut.GetType(), PERF_RECORD_MMAP2); ASSERT_EQ(recordOut.GetName(), RECORDNAME_MMAP2); ASSERT_EQ(recordOut.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -153,7 +156,8 @@ HWTEST_F(PerfEventRecordTest, Comm, TestSize.Level1) size_t buffSize = HEADER_SIZE + sizeof(PerfRecordCommData) - KILO + strlen(data.comm) + 1; ASSERT_EQ(recordIn.GetSize(), buffSize); - PerfRecordComm recordOut(buff.data()); + PerfRecordComm recordOut; + recordOut.Init(buff.data()); ASSERT_EQ(recordOut.GetType(), PERF_RECORD_COMM); ASSERT_EQ(recordOut.GetName(), RECORDNAME_COMM); ASSERT_EQ(recordOut.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -175,7 +179,8 @@ HWTEST_F(PerfEventRecordTest, Lost, TestSize.Level1) {PERF_RECORD_LOST_SAMPLES, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordLostst)}, {1, 2}}; - PerfRecordLost record((uint8_t *)&data); + PerfRecordLost record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_LOST_SAMPLES); ASSERT_EQ(record.GetName(), RECORDNAME_LOST); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -197,7 +202,8 @@ HWTEST_F(PerfEventRecordTest, Exit, TestSize.Level1) TestRecordExitst data = {{PERF_RECORD_EXIT, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordExitst)}, {1, 2, 3, 4, 5}}; - PerfRecordExit record((uint8_t *)&data); + PerfRecordExit record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_EXIT); ASSERT_EQ(record.GetName(), RECORDNAME_EXIT); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -220,7 +226,8 @@ HWTEST_F(PerfEventRecordTest, Throttle, TestSize.Level1) {PERF_RECORD_THROTTLE, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordThrottlest)}, {1, 2, 3}}; - PerfRecordThrottle record((uint8_t *)&data); + PerfRecordThrottle record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_THROTTLE); ASSERT_EQ(record.GetName(), RECORDNAME_THROTTLE); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -243,7 +250,8 @@ HWTEST_F(PerfEventRecordTest, Unthrottle, TestSize.Level1) {PERF_RECORD_UNTHROTTLE, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordUNThrottlest)}, {1, 2, 3}}; - PerfRecordUnthrottle record((uint8_t *)&data); + PerfRecordUnthrottle record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_UNTHROTTLE); ASSERT_EQ(record.GetName(), RECORDNAME_UNTHROTTLE); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -265,7 +273,8 @@ HWTEST_F(PerfEventRecordTest, Fork, TestSize.Level1) TestRecordForkst data = {{PERF_RECORD_FORK, PERF_RECORD_MISC_KERNEL, sizeof(TestRecordForkst)}, {1, 2, 3, 4, 5}}; - PerfRecordFork record((uint8_t *)&data); + PerfRecordFork record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_FORK); ASSERT_EQ(record.GetName(), RECORDNAME_FORK); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -419,7 +428,8 @@ HWTEST_F(PerfEventRecordTest, Sample, TestSize.Level1) {}}; InitTestRecordSample(data); - PerfRecordSample record((uint8_t *)&data, attr); + PerfRecordSample record; + record.Init((uint8_t *)&data, attr); ASSERT_EQ(record.GetType(), PERF_RECORD_SAMPLE); ASSERT_EQ(record.GetName(), RECORDNAME_SAMPLE); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -439,7 +449,8 @@ HWTEST_F(PerfEventRecordTest, SampleReplaceWithCallStack1, TestSize.Level1) {}}; InitTestRecordSample(data); - PerfRecordSample record((uint8_t *)&data, attr); + PerfRecordSample record; + record.Init((uint8_t *)&data, attr); record.sampleType_ |= PERF_SAMPLE_REGS_USER; record.sampleType_ |= PERF_SAMPLE_STACK_USER; record.sampleType_ |= PERF_SAMPLE_CALLCHAIN; @@ -472,7 +483,8 @@ HWTEST_F(PerfEventRecordTest, SampleReplaceWithCallStack2, TestSize.Level1) {}}; InitTestRecordSample(data); - PerfRecordSample record((uint8_t *)&data, attr); + PerfRecordSample record; + record.Init((uint8_t *)&data, attr); record.sampleType_ |= PERF_SAMPLE_CALLCHAIN; std::vector ips = {}; @@ -498,7 +510,8 @@ HWTEST_F(PerfEventRecordTest, SampleReplaceWithCallStack3, TestSize.Level1) {}}; InitTestRecordSample(data); - PerfRecordSample record((uint8_t *)&data, attr); + PerfRecordSample record; + record.Init((uint8_t *)&data, attr); record.sampleType_ |= PERF_SAMPLE_CALLCHAIN; record.callFrames_ = {4, 5, 6, 7, 8, 9}; @@ -527,7 +540,8 @@ HWTEST_F(PerfEventRecordTest, SampleReplaceWithCallStack4, TestSize.Level1) {}}; InitTestRecordSample(data); - PerfRecordSample record((uint8_t *)&data, attr); + PerfRecordSample record; + record.Init((uint8_t *)&data, attr); record.sampleType_ |= PERF_SAMPLE_CALLCHAIN; record.callFrames_ = {}; @@ -553,7 +567,8 @@ HWTEST_F(PerfEventRecordTest, Read, TestSize.Level1) PerfRecordReadst data = {{PERF_RECORD_READ, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordReadst)}, {1, 2, {11, 12, 13, 14}}}; - PerfRecordRead record((uint8_t *)&data); + PerfRecordRead record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_READ); ASSERT_EQ(record.GetName(), RECORDNAME_READ); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -575,7 +590,8 @@ HWTEST_F(PerfEventRecordTest, Aux, TestSize.Level1) PerfRecordAuxst data = {{PERF_RECORD_AUX, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordAuxst)}, {1, 2, 3}}; - PerfRecordAux record((uint8_t *)&data); + PerfRecordAux record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_AUX); ASSERT_EQ(record.GetName(), RECORDNAME_AUX); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -598,7 +614,8 @@ HWTEST_F(PerfEventRecordTest, ItraceStart, TestSize.Level1) {PERF_RECORD_ITRACE_START, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordItraceStartst)}, {1, 2}}; - PerfRecordItraceStart record((uint8_t *)&data); + PerfRecordItraceStart record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_ITRACE_START); ASSERT_EQ(record.GetName(), RECORDNAME_ITRACE_START); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -621,7 +638,8 @@ HWTEST_F(PerfEventRecordTest, LostSamples, TestSize.Level1) {PERF_RECORD_LOST_SAMPLES, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordLostSamplesst)}, {1}}; - PerfRecordLostSamples record((uint8_t *)&data); + PerfRecordLostSamples record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_LOST_SAMPLES); ASSERT_EQ(record.GetName(), RECORDNAME_LOST_SAMPLES); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -644,7 +662,8 @@ HWTEST_F(PerfEventRecordTest, Switch, TestSize.Level1) {PERF_RECORD_SWITCH, PERF_RECORD_MISC_KERNEL, sizeof(perf_event_header)}, {}}; - PerfRecordSwitch record((uint8_t *)&data); + PerfRecordSwitch record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_SWITCH); ASSERT_EQ(record.GetName(), RECORDNAME_SWITCH); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -667,7 +686,8 @@ HWTEST_F(PerfEventRecordTest, SwitchCpuWide, TestSize.Level1) {PERF_RECORD_SWITCH_CPU_WIDE, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordSwitchCpuWidest)}, {}}; - PerfRecordSwitchCpuWide record((uint8_t *)&data); + PerfRecordSwitchCpuWide record; + record.Init((uint8_t *)&data); ASSERT_EQ(record.GetType(), PERF_RECORD_SWITCH_CPU_WIDE); ASSERT_EQ(record.GetName(), RECORDNAME_SWITCH_CPU_WIDE); ASSERT_EQ(record.GetMisc(), PERF_RECORD_MISC_KERNEL); @@ -694,16 +714,84 @@ HWTEST_F(PerfEventRecordTest, GetPerfEventRecord, TestSize.Level1) if (type == PERF_RECORD_SAMPLE) { continue; } - std::unique_ptr perfEventRecord = - GetPerfEventRecord(static_cast(type), reinterpret_cast(&data), attr); + PerfEventRecord& perfEventRecord = + PerfEventRecordFactory::GetPerfEventRecord(static_cast(type), + reinterpret_cast(&data), attr); if (type < PERF_RECORD_NAMESPACES) { - ASSERT_EQ(perfEventRecord != nullptr, true); + ASSERT_EQ(perfEventRecord.GetName() != nullptr, true); } } - std::unique_ptr perfEventRecord = - GetPerfEventRecord(static_cast(PERF_RECORD_AUXTRACE), - reinterpret_cast(&data), attr); - ASSERT_EQ(perfEventRecord != nullptr, true); + PerfEventRecord& perfEventRecord = + PerfEventRecordFactory::GetPerfEventRecord(static_cast(PERF_RECORD_AUXTRACE), + reinterpret_cast(&data), attr); + ASSERT_EQ(perfEventRecord.GetName() != nullptr, true); +} + +HWTEST_F(PerfEventRecordTest, GetPerfEventRecord2, TestSize.Level1) +{ + struct PerfRecordSwitchCpuWidest { + perf_event_header h; + PerfRecordSwitchCpuWideData d; + }; + PerfRecordSwitchCpuWidest data = { + {PERF_RECORD_SWITCH_CPU_WIDE, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordSwitchCpuWidest)}, + {}}; + perf_event_attr attr {}; + attr.sample_type = UINT64_MAX; + PerfEventRecord& perfEventRecord1 = + PerfEventRecordFactory::GetPerfEventRecord(static_cast(PERF_RECORD_AUXTRACE), + reinterpret_cast(&data), attr); + PerfEventRecord& perfEventRecord2 = + PerfEventRecordFactory::GetPerfEventRecord(static_cast(PERF_RECORD_AUXTRACE), + reinterpret_cast(&data), attr); + + ASSERT_TRUE(&perfEventRecord1 == &perfEventRecord2); +} + + +HWTEST_F(PerfEventRecordTest, GetPerfEventRecord3, TestSize.Level1) +{ + struct PerfRecordSwitchCpuWidest { + perf_event_header h; + PerfRecordSwitchCpuWideData d; + }; + PerfRecordSwitchCpuWidest data = { + {PERF_RECORD_SWITCH_CPU_WIDE, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordSwitchCpuWidest)}, + {}}; + perf_event_attr attr {}; + attr.sample_type = UINT64_MAX; + PerfEventRecord& perfEventRecord1 = + PerfEventRecordFactory::GetPerfEventRecord(static_cast(PERF_RECORD_AUXTRACE), + reinterpret_cast(&data), attr); + PerfEventRecord& perfEventRecord2 = + PerfEventRecordFactory::GetPerfEventRecord(INT32_MAX, + reinterpret_cast(&data), attr); + ASSERT_TRUE(perfEventRecord1.GetName() != nullptr); + ASSERT_TRUE(perfEventRecord2.GetName() == nullptr); +} + +HWTEST_F(PerfEventRecordTest, MultiThreadGetPerfEventRecord, TestSize.Level1) +{ + struct PerfRecordSwitchCpuWidest { + perf_event_header h; + PerfRecordSwitchCpuWideData d; + }; + PerfRecordSwitchCpuWidest data = { + {PERF_RECORD_SWITCH_CPU_WIDE, PERF_RECORD_MISC_KERNEL, sizeof(PerfRecordSwitchCpuWidest)}, + {}}; + perf_event_attr attr {}; + attr.sample_type = UINT64_MAX; + PerfEventRecord& perfEventRecord1 = + PerfEventRecordFactory::GetPerfEventRecord(static_cast(PERF_RECORD_AUXTRACE), + reinterpret_cast(&data), attr); + + std::thread t1([&perfEventRecord1, &data, attr]() { + PerfEventRecord& perfEventRecord2 = + PerfEventRecordFactory::GetPerfEventRecord(static_cast(PERF_RECORD_AUXTRACE), + reinterpret_cast(&data), attr); + ASSERT_TRUE(&perfEventRecord1 != &perfEventRecord2); + }); + t1.join(); } } // namespace HiPerf } // namespace Developtools diff --git a/test/unittest/common/native/perf_events_test.cpp b/test/unittest/common/native/perf_events_test.cpp index e12fef4..7bf177c 100644 --- a/test/unittest/common/native/perf_events_test.cpp +++ b/test/unittest/common/native/perf_events_test.cpp @@ -41,7 +41,7 @@ public: static void TestCodeThread(void); static void RunTestThreads(std::vector &threads); static void SetAllConfig(PerfEvents &event); - static bool RecordCount(std::unique_ptr record); + static bool RecordCount(PerfEventRecord& record); static void StatCount( const std::map> &countEvents); @@ -71,13 +71,9 @@ void PerfEventsTest::TearDown() {} uint64_t PerfEventsTest::g_recordCount = 0; uint64_t PerfEventsTest::g_statCount = 0; -bool PerfEventsTest::RecordCount(std::unique_ptr record) +bool PerfEventsTest::RecordCount(PerfEventRecord& record) { g_recordCount++; - if (record->GetType() == PERF_RECORD_SAMPLE) { - // the record is allowed from a cache memory, does not free memory after use - record.release(); - } return true; } diff --git a/test/unittest/common/native/perf_file_reader_test.cpp b/test/unittest/common/native/perf_file_reader_test.cpp index dd1f18b..d7eec63 100644 --- a/test/unittest/common/native/perf_file_reader_test.cpp +++ b/test/unittest/common/native/perf_file_reader_test.cpp @@ -25,7 +25,7 @@ using namespace OHOS::HiviewDFX; namespace OHOS { namespace Developtools { namespace HiPerf { -using ProcessRecordCB = const std::function record)>; +using ProcessRecordCB = const std::function; class PerfFileReaderTest : public testing::Test { public: static void SetUpTestCase(void); diff --git a/test/unittest/common/native/virtual_runtime_test.cpp b/test/unittest/common/native/virtual_runtime_test.cpp index 9eec14d..bca726a 100644 --- a/test/unittest/common/native/virtual_runtime_test.cpp +++ b/test/unittest/common/native/virtual_runtime_test.cpp @@ -41,7 +41,7 @@ public: void LogLevelTest(std::vector args, DebugLevel level); default_random_engine rnd_; std::unique_ptr runtime_; - bool RecordCallBack(std::unique_ptr record); + bool RecordCallBack(PerfEventRecord& record); size_t callbackCount_ = 0; void PrepareKernelSymbol(); @@ -69,10 +69,10 @@ void VirtualRuntimeTest::TearDown() runtime_.release(); } -bool VirtualRuntimeTest::RecordCallBack(std::unique_ptr record) +bool VirtualRuntimeTest::RecordCallBack(PerfEventRecord& record) { callbackCount_++; - printf("callbackCount_ %zu: type %d\n", callbackCount_, record->GetType()); + printf("callbackCount_ %zu: type %d\n", callbackCount_, record.GetType()); return true; } @@ -371,7 +371,8 @@ HWTEST_F(VirtualRuntimeTest, UnwindFromRecord, TestSize.Level1) (void)memset_s(&attr, sizeof(perf_event_attr), 0, sizeof(perf_event_attr)); attr.sample_type = TEST_RECORD_SAMPLE_TYPE; attr.sample_regs_user = TEST_DWARF_RECORD_REGS_USER; - PerfRecordSample sample(data.data(), attr); + PerfRecordSample sample; + sample.Init(data.data(), attr); sample.DumpLog("UnwindFromRecord"); ASSERT_EQ(sample.data_.stack_size, TEST_DWARF_RECORD_STACK_SIZE);