From d02deea31cf82bf4bb64a1c6692ede0577ae32e8 Mon Sep 17 00:00:00 2001 From: GalaxyG Date: Wed, 10 Sep 2025 17:50:36 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86header->size=3D=3D0=E7=9A=84?= =?UTF-8?q?=E5=BC=82=E5=B8=B8=E5=9C=BA=E6=99=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在极端场景下,ring buffer的event->header.size可能会等于0,需要规避该场景,避免出现死循环。 --- include/pcerrc.h | 1 + pmu/sample_process.cpp | 6 ++++++ pmu/sampler.cpp | 3 +++ pmu/spe.cpp | 13 ++++++++++--- pmu/spe.h | 2 +- python/modules/kperf/perror.py | 1 + 6 files changed, 22 insertions(+), 4 deletions(-) diff --git a/include/pcerrc.h b/include/pcerrc.h index 13c04e9..7a13931 100644 --- a/include/pcerrc.h +++ b/include/pcerrc.h @@ -79,6 +79,7 @@ extern "C" { #define LIBPERF_ERR_COUNT_OVERFLOW 1035 #define LIBPERF_ERR_INVALID_GROUP_SPE 1036 #define LIBPERF_ERR_INVALID_GROUP_ALL_UNCORE 1037 +#define LIBPERF_ERR_BUFFER_CORRUPTED 1038 #define UNKNOWN_ERROR 9999 diff --git a/pmu/sample_process.cpp b/pmu/sample_process.cpp index fcd1bfa..85d7d7b 100644 --- a/pmu/sample_process.cpp +++ b/pmu/sample_process.cpp @@ -16,12 +16,14 @@ #include #include #include "pcerrc.h" +#include "pcerr.h" #include "evt.h" #include "sample_process.h" #define PAGE_SIZE (sysconf(_SC_PAGESIZE)) #define MB() asm volatile("dmb ish" ::: "memory") static constexpr int MAX_DATA_SIZE = 8192; +using namespace pcerr; #define PerfRingbufferSmpStoreRelease(p, v) \ ({ \ union { \ @@ -102,6 +104,10 @@ static inline union KUNPENG_PMU::PerfEvent *PerfMmapRead(KUNPENG_PMU::PerfMmap & event = (union KUNPENG_PMU::PerfEvent *)&data[*startPointer & map.mask]; size = event->header.size; + if (__glibc_unlikely(size == 0)) { + New(LIBPERF_ERR_BUFFER_CORRUPTED); + return nullptr; + } if (__glibc_unlikely(size < sizeof(event->header) || diff < size)) { return nullptr; diff --git a/pmu/sampler.cpp b/pmu/sampler.cpp index b71825d..45bb0ca 100644 --- a/pmu/sampler.cpp +++ b/pmu/sampler.cpp @@ -253,6 +253,9 @@ int KUNPENG_PMU::PerfSampler::Read(vector &data, std::vectorReadRingBuffer(data, sampleIps); + if (__glibc_unlikely(Perrorno() == LIBPERF_ERR_BUFFER_CORRUPTED)) { + return Perrorno(); + } if (this->pid == -1) { FillComm(cnt, data.size(), data); } diff --git a/pmu/spe.cpp b/pmu/spe.cpp index 99b7a89..158e7c1 100644 --- a/pmu/spe.cpp +++ b/pmu/spe.cpp @@ -344,7 +344,7 @@ static void ParseContextSwitch(PerfEventSampleContextSwitch *contextSample, Cont } } -void Spe::CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData *data, int size, int pageSize) +int Spe::CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData *data, int size, int pageSize) { uint64_t maxNum = size / sizeof(struct ContextSwitchData); uint64_t num = 1; @@ -358,6 +358,9 @@ void Spe::CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData while ((dataTail < dataHead) && (num < maxNum)) { uint64_t off = dataTail % mpage->data_size; struct perf_event_header *header = (struct perf_event_header *)(ringBuf + off); + if (__glibc_unlikely(header->size == 0)) { + return LIBPERF_ERR_BUFFER_CORRUPTED; + } if (header->type == PERF_RECORD_MMAP && symbolMode != NO_SYMBOL_RESOLVE) { struct PerfRecordMmap *sample = (struct PerfRecordMmap *)header; @@ -528,7 +531,11 @@ int Spe::SpeReadData(struct SpeContext *context, struct SpeRecord *buf, int size { int remainSize = size; int dummySize = context->dummyMmapSize; - CoreDummyData(context->coreCtxes, dummyData, dummySize, context->pageSize); + int err = CoreDummyData(context->coreCtxes, dummyData, dummySize, context->pageSize); + if (err != SUCCESS) { + New(err); + return -1; + } buf = CoreSpeData(context->coreCtxes, dummyData, buf, &remainSize, context->pageSize, cpu); return size - remainSize; } @@ -627,7 +634,7 @@ int Spe::Read() pidRecords[rec->tid].push_back(rec); } status |= READ; - if (Perrorno() == LIBPERF_ERR_KERNEL_NOT_SUPPORT) { + if (Perrorno() == LIBPERF_ERR_KERNEL_NOT_SUPPORT || Perrorno() == LIBPERF_ERR_BUFFER_CORRUPTED) { return Perrorno(); } return SUCCESS; diff --git a/pmu/spe.h b/pmu/spe.h index fc937d1..09e50de 100644 --- a/pmu/spe.h +++ b/pmu/spe.h @@ -199,7 +199,7 @@ public: private: int SpeReadData(struct SpeContext *context, struct SpeRecord *buf, int size); - void CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData *data, int size, int pageSize); + int CoreDummyData(struct SpeCoreContext *context, struct ContextSwitchData *data, int size, int pageSize); void UpdateProcMap(__u32 ppid, __u32 pid); const unsigned short NONE = 0; diff --git a/python/modules/kperf/perror.py b/python/modules/kperf/perror.py index 6f5cfb3..a5c6fe3 100644 --- a/python/modules/kperf/perror.py +++ b/python/modules/kperf/perror.py @@ -78,6 +78,7 @@ class Error: LIBPERF_ERR_COUNT_OVERFLOW = 1035 LIBPERF_ERR_INVALID_GROUP_SPE = 1036 LIBPERF_ERR_INVALID_GROUP_ALL_UNCORE = 1037 + LIBPERF_ERR_BUFFER_CORRUPTED = 1038 UNKNOWN_ERROR = 9999 -- Gitee