diff --git a/example/pmu_perfdata.cpp b/example/pmu_perfdata.cpp index 5ecd76686dcb61e5b2f56e009bd5c12e76248352..b7889c2eae2730052572549f3d47a3be876f4949 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 dd642500f159237ea5560a5108d4db801e3db5bb..4db13cdae6e0b0bb89ea6ace35c29dbf711237ee 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 e6e16fdbbb7a044921afc70daa39afa6d15186be..c84984d85c1737f0f9e7e91781b1db223cef6f2a 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);