From af40901576e20ee00476e9e3e8708e7fb8d66633 Mon Sep 17 00:00:00 2001 From: Galaxy Date: Tue, 21 May 2024 00:57:10 -0700 Subject: [PATCH] Add API: PmuDumpData Implement interface PmuDumpData for dump PmuData list to an output file. Refer to API reference for detail. --- include/pcerrc.h | 2 +- include/pmu.h | 14 ++++++++++- pmu/pmu.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ util/pcerr.cpp | 1 + 4 files changed, 80 insertions(+), 2 deletions(-) diff --git a/include/pcerrc.h b/include/pcerrc.h index aaed5c4..a677cff 100644 --- a/include/pcerrc.h +++ b/include/pcerrc.h @@ -72,7 +72,7 @@ extern "C" { #define LIBPERF_ERR_NOT_OPENED 1028 #define LIBPERF_ERR_QUERY_EVENT_TYPE_INVALID 1029 #define LIBPERF_ERR_QUERY_EVENT_LIST_FAILED 1030 -#define LIBPERF_ERR_FOLDER_PATH_INACCESSIBLE 1031 +#define LIBPERF_ERR_PATH_INACCESSIBLE 1031 #define LIBPERF_ERR_INVALID_SAMPLE_RATE 1032 #define UNKNOWN_ERROR 9999 diff --git a/include/pmu.h b/include/pmu.h index 9ba1f34..08d75c6 100644 --- a/include/pmu.h +++ b/include/pmu.h @@ -128,7 +128,6 @@ struct PmuData { uint64_t period; // number of Samples uint64_t count; // event count. Only available for Counting. struct PmuDataExt *ext; // extension. Only available for Spe. - }; /** @@ -212,6 +211,19 @@ int PmuRead(int pd, struct PmuData** pmuData); */ int PmuAppendData(struct PmuData *fromData, struct PmuData **toData); +/** + * @brief + * Dump pmu data to a specific file. + * If file exists, then data will be appended to file. + * If file does not exist, then file will be created. + * Dump format: comm pid tid cpu period evt count addr symbolName offset module fileName lineNum + * @param pmuData data list. + * @param len data length. + * @param filepath path of the output file. + * @param dumpDwf if 0, source file and line number of symbols will not be dumped, otherwise, they will be dumped to file. +*/ +int PmuDumpData(struct PmuData *pmuData, unsigned len, char *filepath, int dumpDwf); + /** * @brief Close all the file descriptor opened during collecting process */ diff --git a/pmu/pmu.cpp b/pmu/pmu.cpp index 5f50b26..dd1ed6e 100644 --- a/pmu/pmu.cpp +++ b/pmu/pmu.cpp @@ -670,3 +670,68 @@ void PmuDataFree(struct PmuData* pmuData) PmuList::GetInstance()->FreeData(pmuData); New(SUCCESS); } + +static void DumpStack(ofstream &out, Stack *stack, int dumpDwf) +{ + if (stack->next) { + out << endl; + } + while (stack) { + if (stack->symbol) { + auto symbol = stack->symbol; + out << std::hex << symbol->addr << std::dec << " " + << symbol->symbolName << " 0x" << std::hex + << symbol->offset << std::dec << " " + << symbol->module << " "; + + if (dumpDwf) { + out << symbol->fileName << ":" << symbol->lineNum; + } + out << endl; + } + stack = stack->next; + } +} + +int PmuDumpData(struct PmuData *pmuData, unsigned len, char *filepath, int dumpDwf) +{ + ofstream out(filepath, ios_base::app); + if (!out.is_open()) { + New(LIBPERF_ERR_PATH_INACCESSIBLE, "cannot access: " + string(filepath)); + return -1; + } + + for (unsigned i = 0; i < len; ++i) { + auto &data = pmuData[i]; + if (data.comm) { + out << data.comm << " "; + } else { + out << "NULL "; + } + + out << data.pid << " " + << data.tid << " " + << data.cpu << " " + << data.period << " "; + + if (data.evt) { + out << data.evt << " "; + } else { + out << "NULL "; + } + out << data.count << " "; + + if (data.ext) { + out << std::hex << data.ext->va << " " + << data.ext->pa << " " + << data.ext->event << " " << std::dec; + } + + if (data.stack) { + DumpStack(out, data.stack, dumpDwf); + } + out << endl; + } + New(SUCCESS); + return 0; +} \ No newline at end of file diff --git a/util/pcerr.cpp b/util/pcerr.cpp index b26f188..f286d25 100644 --- a/util/pcerr.cpp +++ b/util/pcerr.cpp @@ -43,6 +43,7 @@ namespace pcerr { {LIBPERF_ERR_KERNEL_NOT_SUPPORT, "current pmu task is not supported by kernel"}, {LIBPERF_ERR_TOO_MANY_FD, "too many open files"}, {LIBPERF_ERR_RAISE_FD, "failed to setrlimit or getrlimit"}, + {LIBPERF_ERR_PATH_INACCESSIBLE, "cannot access file path"}, {LIBPERF_ERR_INVALID_SAMPLE_RATE, "invalid sample rate, please check /proc/sys/kernel/perf_event_max_sample_rate"}, }; -- Gitee