From aaedc3043de9f4931baea55e0d9510c7dc00ebaf Mon Sep 17 00:00:00 2001 From: GalaxyG Date: Mon, 1 Sep 2025 19:25:10 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96perf.data=E5=AF=B9autofdo?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=9A=84=E5=85=BC=E5=AE=B9=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 提供选项addIdHdr,用于决定是否对非PERF_RECORD_SAMPLE添加id信息。 对于autofdo 0.19,需要添加IdHdr才能执行create_gcov; 对于autofdo 0.20,添加IdHdr并且sample_id_all=0(libkperf的perf.data并未设置sample_id_all,参考79e44828f4d083b11bcf2d16c8d7afe883f72389)会导致执行create_gcov失败。所以对于该版本,不能添加IdHdr。 --- example/pmu_perfdata.cpp | 7 ++++++- include/pmu.h | 5 +++-- pmu/dump_perf_data.cpp | 11 +++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/example/pmu_perfdata.cpp b/example/pmu_perfdata.cpp index 5ecd766..b7889c2 100644 --- a/example/pmu_perfdata.cpp +++ b/example/pmu_perfdata.cpp @@ -47,6 +47,7 @@ struct Param { unsigned duration = UINT32_MAX; unsigned freq = 4000; unsigned interval = 1000; // ms + bool addIdHdr; }; int64_t GetTime() @@ -84,6 +85,7 @@ static void PrintHelp() std::cerr << "Options:\n"; std::cerr << " -e , event list. default: cycles\n"; std::cerr << " -b whether to use brbe.\n"; + std::cerr << " --sample-id add sample id for Non PERF_RECORD_SAMPLE samples, mostly used for autofdo-0.19.\n"; std::cerr << " -o output file path. default: ./libkperf.data\n"; std::cerr << " -d count of reading: default: UINT32_MAX\n"; std::cerr << " -I interval for reading buffer. unit: ms. default: 1000\n"; @@ -106,6 +108,7 @@ static int ToInt(const char *str) static Param ParseArgs(int argc, char** argv) { Param param; + param.addIdHdr = false; bool inCmd = false; for (int i = 1; i < argc; ++i) { if (inCmd) { @@ -134,6 +137,8 @@ static Param ParseArgs(int argc, char** argv) ++i; } else if (strcmp(argv[i], "-v") == 0) { verbose = true; + } else if (strcmp(argv[i], "--sample-id") == 0) { + param.addIdHdr = true; } else { PrintHelp(); exit(0); @@ -235,7 +240,7 @@ int Collect(const Param ¶m) FreeEvtList(evtlist, param.events.size()); return Perrorno(); } - file = PmuBeginWrite(param.dataPath.c_str(), &attr); + file = PmuBeginWrite(param.dataPath.c_str(), &attr, param.addIdHdr); if (file == NULL) { FreeEvtList(evtlist, param.events.size()); return Perrorno(); diff --git a/include/pmu.h b/include/pmu.h index dd64250..4db13cd 100644 --- a/include/pmu.h +++ b/include/pmu.h @@ -707,12 +707,13 @@ typedef void* PmuFile; * @brief Begin to write PmuData list to perf.data file. * It is a simplified perf.data only include basic fields for perf sample, * including id, tid, pid, addr and branch stack. - * It also includes sample like mmap, mmap2, comm, fork. + * It also includes sample like mmap, mmap2, comm, fork and one feature section(build id). * @param path path of perf.data * @param pattr PmuAttr of collection task + * @param addIdHdr add sample id for Non PERF_RECORD_SAMPLE samples * @return a handle of file to write. If error, return NULL and check Perrorno. */ -PmuFile PmuBeginWrite(const char *path, const struct PmuAttr *pattr); +PmuFile PmuBeginWrite(const char *path, const struct PmuAttr *pattr, const int addIdHdr); /** * @brief Write PmuData list to file. diff --git a/pmu/dump_perf_data.cpp b/pmu/dump_perf_data.cpp index e6e16fd..c84984d 100644 --- a/pmu/dump_perf_data.cpp +++ b/pmu/dump_perf_data.cpp @@ -87,7 +87,7 @@ struct PerfSample { class PerfDataDumper { public: - PerfDataDumper(const char *path) :path(path){ + PerfDataDumper(const char *path, const bool addIdHdr) :path(path), addIdHdr(addIdHdr){ } ~PerfDataDumper() = default; @@ -127,7 +127,9 @@ public: return LIBPERF_ERR_OPEN_INVALID_FILE; } // Calculate essential id header size, used for synthesized events. - idHdrSize = GetIdHeaderSize(); + if (addIdHdr) { + idHdrSize = GetIdHeaderSize(); + } // Start to write perf.data, refer to perf_session__write_header in linux. @@ -619,6 +621,7 @@ private: } unsigned idHdrSize = 0; + bool addIdHdr = false; const char *path = nullptr; PerfFileHeader ph = {0}; int fd = 0; @@ -631,10 +634,10 @@ private: map> dumpers; -PmuFile PmuBeginWrite(const char *path, const PmuAttr *pattr) +PmuFile PmuBeginWrite(const char *path, const PmuAttr *pattr, const int addIdHdr) { try { - unique_ptr dumper(new PerfDataDumper(path)); + unique_ptr dumper(new PerfDataDumper(path, addIdHdr)); int err = dumper->Start(pattr); if (err != SUCCESS) { New(err); -- Gitee