From eb96d01dc932b0c1b371106b664c4f5c8d2a83d0 Mon Sep 17 00:00:00 2001 From: xlgitee Date: Tue, 15 Jul 2025 23:04:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=99=E8=BD=AC=E5=82=A8?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: xlgitee Change-Id: I89fa1e6b4b5620a1a8b20bf8e94e701452f8abf9 --- services/BUILD.gn | 2 +- ...pp => kernel_snapshot_content_builder.cpp} | 100 +++++++++++++----- ...il.h => kernel_snapshot_content_builder.h} | 41 +++++-- services/snapshot/kernel_snapshot_manager.cpp | 2 +- services/snapshot/kernel_snapshot_printer.cpp | 13 +-- .../snapshot/kernel_snapshot_reporter.cpp | 4 +- test/unittest/kernel_snapshot/BUILD.gn | 2 +- .../kernel_snapshot/kernel_snapshot_test.cpp | 69 ++++++++---- 8 files changed, 163 insertions(+), 70 deletions(-) rename services/snapshot/{kernel_snapshot_util.cpp => kernel_snapshot_content_builder.cpp} (36%) rename services/snapshot/{kernel_snapshot_util.h => kernel_snapshot_content_builder.h} (39%) diff --git a/services/BUILD.gn b/services/BUILD.gn index af120826a..1c0c28b40 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -78,6 +78,7 @@ if (defined(ohos_lite)) { } } else { faultloggerd_sources += [ + "./snapshot/kernel_snapshot_content_builder.cpp", "./snapshot/kernel_snapshot_kernel_frame.cpp", "./snapshot/kernel_snapshot_manager.cpp", "./snapshot/kernel_snapshot_parser.cpp", @@ -85,7 +86,6 @@ if (defined(ohos_lite)) { "./snapshot/kernel_snapshot_processor_impl.cpp", "./snapshot/kernel_snapshot_reporter.cpp", "./snapshot/kernel_snapshot_trie.cpp", - "./snapshot/kernel_snapshot_util.cpp", "fault_logger_pipe.cpp", ] diff --git a/services/snapshot/kernel_snapshot_util.cpp b/services/snapshot/kernel_snapshot_content_builder.cpp similarity index 36% rename from services/snapshot/kernel_snapshot_util.cpp rename to services/snapshot/kernel_snapshot_content_builder.cpp index 6d5e6a1e9..688f48404 100644 --- a/services/snapshot/kernel_snapshot_util.cpp +++ b/services/snapshot/kernel_snapshot_content_builder.cpp @@ -13,7 +13,7 @@ * limitations under the License. */ -#include "kernel_snapshot_util.h" +#include "kernel_snapshot_content_builder.h" #include "parameters.h" @@ -22,18 +22,8 @@ namespace OHOS { namespace HiviewDFX { -namespace KernelSnapshotUtil { namespace { constexpr const char * const KERNEL_SNAPSHOT_REASON = "CppCrashKernelSnapshot"; -} - -std::string FilterEmptySection(const std::string& secHead, const std::string& secCont, const std::string& end) -{ - if (secCont.empty()) { - return ""; - } - return secHead + secCont + end; -} std::string FormatTimestamp(const std::string& timestamp) { @@ -50,26 +40,84 @@ std::string GetBuildInfo() static std::string buildInfo = OHOS::system::GetParameter("const.product.software.version", "Unknown"); return buildInfo; } +} // namespace + +bool KernelSnapshotContentBuilder::SnapshotUserSection::IsEmptyContent() const +{ + return content.empty(); +} + +size_t KernelSnapshotContentBuilder::SnapshotUserSection::Length() const +{ + if (IsEmptyContent()) { + return 0; + } + return title.length() + content.length() + suffix.length(); +} + +void KernelSnapshotContentBuilder::SnapshotUserSection::WriteTo(std::string& output) const +{ + if (IsEmptyContent()) { + return; + } + output += title; + output += content; + output += suffix; +} -std::string FillSummary(CrashMap& output, bool isLocal) +std::string KernelSnapshotContentBuilder::GenerateSummary() { + contentSections_ = BuildSections(); + return ComposeSummary(); +} + +size_t KernelSnapshotContentBuilder::ComputeTotalLength() +{ + size_t totalLength = 0; + for (const auto& section : contentSections_) { + if (!section.IsEmptyContent()) { + totalLength += section.Length(); + } + } + return totalLength; +} + +std::vector KernelSnapshotContentBuilder::BuildSections() +{ + std::vector sections = { + {"Build info: ", GetBuildInfo(), "\n"}, + {"Timestamp: ", FormatTimestamp(crashData_[CrashSection::TIME_STAMP]), ""}, + {"Pid: ", crashData_[CrashSection::PID], "\n"}, + {"Uid: ", crashData_[CrashSection::UID], "\n"}, + {"Process name: ", crashData_[CrashSection::PROCESS_NAME], "\n"}, + {"Reason: ", KERNEL_SNAPSHOT_REASON, "\n"}, + {"Exception registers:\n", crashData_[CrashSection::EXCEPTION_REGISTERS], ""}, + {"Fault thread info:\n", crashData_[CrashSection::FAULT_THREAD_INFO], ""}, + {"Registers:\n", crashData_[CrashSection::CREGISTERS], ""} + }; + if (isLocal_) { + sections.emplace_back("Memory near registers:\n", crashData_[CrashSection::MEMORY_NEAR_REGISTERS], ""); + sections.emplace_back("FaultStack:\n", crashData_[CrashSection::FAULT_STACK], ""); + } + sections.emplace_back("Elfs:\n", crashData_[CrashSection::MAPS], ""); + + return sections; +} + +std::string KernelSnapshotContentBuilder::ComposeSummary() +{ + const size_t totalLength = ComputeTotalLength(); + if (totalLength == 0) { + return ""; + } + std::string summary; - summary += FilterEmptySection("Build info: ", GetBuildInfo(), "\n"); - summary += FilterEmptySection("Timestamp: ", FormatTimestamp(output[CrashSection::TIME_STAMP]), ""); - summary += FilterEmptySection("Pid: ", output[CrashSection::PID], "\n"); - summary += FilterEmptySection("Uid: ", output[CrashSection::UID], "\n"); - summary += FilterEmptySection("Process name: ", output[CrashSection::PROCESS_NAME], "\n"); - summary += FilterEmptySection("Reason: ", KERNEL_SNAPSHOT_REASON, "\n"); - summary += FilterEmptySection("Exception registers:\n", output[CrashSection::EXCEPTION_REGISTERS], ""); - summary += FilterEmptySection("Fault thread info:\n", output[CrashSection::FAULT_THREAD_INFO], ""); - summary += FilterEmptySection("Registers:\n", output[CrashSection::CREGISTERS], ""); - if (isLocal) { - summary += FilterEmptySection("Memory near registers:\n", output[CrashSection::MEMORY_NEAR_REGISTERS], ""); - summary += FilterEmptySection("FaultStack:\n", output[CrashSection::FAULT_STACK], ""); + summary.reserve(totalLength); + + for (const auto& section : contentSections_) { + section.WriteTo(summary); } - summary += FilterEmptySection("Elfs:\n", output[CrashSection::MAPS], ""); return summary; } -} } // namespace HiviewDFX } // namespace OHOS diff --git a/services/snapshot/kernel_snapshot_util.h b/services/snapshot/kernel_snapshot_content_builder.h similarity index 39% rename from services/snapshot/kernel_snapshot_util.h rename to services/snapshot/kernel_snapshot_content_builder.h index fc4626b5b..9d3ee7303 100644 --- a/services/snapshot/kernel_snapshot_util.h +++ b/services/snapshot/kernel_snapshot_content_builder.h @@ -13,20 +13,43 @@ * limitations under the License. */ -#ifndef KERNEL_SNAPSHOT_UTIL_H -#define KERNEL_SNAPSHOT_UTIL_H -#include +#ifndef KERNEL_SNAPSHOT_CONTENT_BUILDER_H +#define KERNEL_SNAPSHOT_CONTENT_BUILDER_H #include "kernel_snapshot_data.h" namespace OHOS { namespace HiviewDFX { -namespace KernelSnapshotUtil { -std::string FilterEmptySection(const std::string& secHead, const std::string& secCont, const std::string& end); -std::string FormatTimestamp(const std::string& timestamp); -std::string GetBuildInfo(); -std::string FillSummary(CrashMap& output, bool isLocal = false); -} +class KernelSnapshotContentBuilder { +public: + explicit KernelSnapshotContentBuilder(CrashMap& crashData, bool isLocal = false) + : crashData_(crashData), isLocal_(isLocal) {} + std::string GenerateSummary(); + + KernelSnapshotContentBuilder(const KernelSnapshotContentBuilder&) = delete; + KernelSnapshotContentBuilder& operator=(const KernelSnapshotContentBuilder&) = delete; + +private: + struct SnapshotUserSection { + std::string title; + std::string content; + std::string suffix; + + SnapshotUserSection(std::string title, std::string content, std::string suffix) + : title(std::move(title)), content(std::move(content)), suffix(std::move(suffix)) {} + bool IsEmptyContent() const; + size_t Length() const; + void WriteTo(std::string& output) const; + }; + + std::vector BuildSections(); + size_t ComputeTotalLength(); + std::string ComposeSummary(); + + CrashMap& crashData_; + bool isLocal_; + std::vector contentSections_; +}; } // namespace HiviewDFX } // namespace OHOS #endif diff --git a/services/snapshot/kernel_snapshot_manager.cpp b/services/snapshot/kernel_snapshot_manager.cpp index 5584461b2..4708e91c4 100644 --- a/services/snapshot/kernel_snapshot_manager.cpp +++ b/services/snapshot/kernel_snapshot_manager.cpp @@ -26,8 +26,8 @@ #include "dfx_log.h" #include "dfx_util.h" +#include "kernel_snapshot_content_builder.h" #include "kernel_snapshot_processor_impl.h" -#include "kernel_snapshot_util.h" #include "smart_fd.h" namespace OHOS { diff --git a/services/snapshot/kernel_snapshot_printer.cpp b/services/snapshot/kernel_snapshot_printer.cpp index 42ab7b644..67d5e7203 100644 --- a/services/snapshot/kernel_snapshot_printer.cpp +++ b/services/snapshot/kernel_snapshot_printer.cpp @@ -18,7 +18,7 @@ #include "dfx_log.h" #include "string_util.h" -#include "kernel_snapshot_util.h" +#include "kernel_snapshot_content_builder.h" namespace OHOS { namespace HiviewDFX { namespace { @@ -27,19 +27,16 @@ constexpr const char * const KBOX_SNAPSHOT_DUMP_PATH = "/data/log/faultlog/temp/ void KernelSnapshotPrinter::OutputToFile(const std::string& filePath, CrashMap& output) { - FILE* file = fopen(filePath.c_str(), "w"); - if (file == nullptr) { + std::unique_ptr file(fopen(filePath.c_str(), "w"), fclose); + if (!file) { DFXLOGE("open file failed %{public}s errno %{public}d", filePath.c_str(), errno); return; } - std::string outputCont = KernelSnapshotUtil::FillSummary(output, true); - if (fwrite(outputCont.c_str(), sizeof(char), outputCont.length(), file) != outputCont.length()) { + std::string outputCont = KernelSnapshotContentBuilder(output, true).GenerateSummary(); + if (fwrite(outputCont.c_str(), sizeof(char), outputCont.length(), file.get()) != outputCont.length()) { DFXLOGE("write file failed %{public}s errno %{public}d", filePath.c_str(), errno); } - if (fclose(file) != 0) { - DFXLOGE("close file failed %{public}s errno %{public}d", filePath.c_str(), errno); - } } void KernelSnapshotPrinter::SaveSnapshot(CrashMap& output) diff --git a/services/snapshot/kernel_snapshot_reporter.cpp b/services/snapshot/kernel_snapshot_reporter.cpp index f5cc53922..c66195884 100644 --- a/services/snapshot/kernel_snapshot_reporter.cpp +++ b/services/snapshot/kernel_snapshot_reporter.cpp @@ -22,7 +22,7 @@ #include "hisysevent.h" #endif -#include "kernel_snapshot_util.h" +#include "kernel_snapshot_content_builder.h" namespace OHOS { namespace HiviewDFX { @@ -54,7 +54,7 @@ bool KernelSnapshotReporter::ReportCrashNoLogEvent(CrashMap& output) "PID", pid, "PROCESS_NAME", output[CrashSection::PROCESS_NAME], "HAPPEN_TIME", timeStamp, - "SUMMARY", KernelSnapshotUtil::FillSummary(output)); + "SUMMARY", KernelSnapshotContentBuilder(output).GenerateSummary()); DFXLOGI("Report kernel snapshot event done, ret %{public}d", ret); return ret == 0; #else diff --git a/test/unittest/kernel_snapshot/BUILD.gn b/test/unittest/kernel_snapshot/BUILD.gn index 5af60d522..7d3cfc058 100644 --- a/test/unittest/kernel_snapshot/BUILD.gn +++ b/test/unittest/kernel_snapshot/BUILD.gn @@ -41,6 +41,7 @@ if (defined(ohos_lite)) { ] sources = [ + "$faultloggerd_path/services/snapshot/kernel_snapshot_content_builder.cpp", "$faultloggerd_path/services/snapshot/kernel_snapshot_kernel_frame.cpp", "$faultloggerd_path/services/snapshot/kernel_snapshot_manager.cpp", "$faultloggerd_path/services/snapshot/kernel_snapshot_parser.cpp", @@ -48,7 +49,6 @@ if (defined(ohos_lite)) { "$faultloggerd_path/services/snapshot/kernel_snapshot_processor_impl.cpp", "$faultloggerd_path/services/snapshot/kernel_snapshot_reporter.cpp", "$faultloggerd_path/services/snapshot/kernel_snapshot_trie.cpp", - "$faultloggerd_path/services/snapshot/kernel_snapshot_util.cpp", "kernel_snapshot_test.cpp", ] cflags_cc = [ "-Dprivate=public" ] diff --git a/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp b/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp index a892689d8..b1227faf1 100644 --- a/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp +++ b/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp @@ -21,12 +21,12 @@ #include #include "dfx_test_util.h" +#include "kernel_snapshot_content_builder.h" #include "kernel_snapshot_parser.h" #include "kernel_snapshot_printer.h" #include "kernel_snapshot_processor_impl.h" #include "kernel_snapshot_reporter.h" #include "kernel_snapshot_trie.h" -#include "kernel_snapshot_util.h" using namespace testing::ext; using namespace std; @@ -510,27 +510,6 @@ HWTEST_F(KernelSnapshotTest, KernelSnapshotTest025, TestSize.Level2) GTEST_LOG_(INFO) << "KernelSnapshotTest025: end."; } -/** - * @tc.name: KernelSnapshotTest040 - * @tc.desc: test FilterEmptySection - * @tc.type: FUNC - */ -HWTEST_F(KernelSnapshotTest, KernelSnapshotTest040, TestSize.Level2) -{ - GTEST_LOG_(INFO) << "KernelSnapshotTest040: start."; - std::string secHead = "secHead"; - std::string secCont = ""; - std::string end = "end"; - - std::string res = KernelSnapshotUtil::FilterEmptySection(secHead, secCont, end); - ASSERT_EQ(res, ""); - - secCont = "secCont"; - res = KernelSnapshotUtil::FilterEmptySection(secHead, secCont, end); - ASSERT_EQ(res, "secHeadsecContend"); - GTEST_LOG_(INFO) << "KernelSnapshotTest040: end."; -} - /** * @tc.name: KernelSnapshotTest041 * @tc.desc: test SaveSnapshot @@ -655,5 +634,51 @@ HWTEST_F(KernelSnapshotTest, KernelSnapshotTest053, TestSize.Level2) GTEST_LOG_(INFO) << "KernelSnapshotTest053: end."; } + +/** + * @tc.name: KernelSnapshotTest054 + * @tc.desc: test generate summary local is true + * @tc.type: FUNC + */ +HWTEST_F(KernelSnapshotTest, KernelSnapshotTest054, TestSize.Level2) +{ + GTEST_LOG_(INFO) << "KernelSnapshotTest054: start."; + CrashMap output; + output[CrashSection::PID] = ""; + output[CrashSection::UID] = "1000"; + output[CrashSection::FAULT_STACK] = "[0000005b36f41a70][FP: 0000005b36fafbd0]"; + auto summary = KernelSnapshotContentBuilder(output, true).GenerateSummary(); + + EXPECT_TRUE(summary.find("Pid:") == std::string::npos); + EXPECT_TRUE(summary.find("Uid:") != std::string::npos); + EXPECT_TRUE(summary.find("FaultStack:") != std::string::npos); + + output[CrashSection::PID] = "123"; + summary = KernelSnapshotContentBuilder(output, true).GenerateSummary(); + EXPECT_TRUE(summary.find("Pid:") != std::string::npos); + + GTEST_LOG_(INFO) << "KernelSnapshotTest054: end."; +} + +/** + * @tc.name: KernelSnapshotTest055 + * @tc.desc: test test generate summary local is false + * @tc.type: FUNC + */ +HWTEST_F(KernelSnapshotTest, KernelSnapshotTest055, TestSize.Level2) +{ + GTEST_LOG_(INFO) << "KernelSnapshotTest055: start."; + CrashMap output = { + {CrashSection::UID, "1000"}, + {CrashSection::FAULT_STACK, "[0000005b36f41a70][FP: 0000005b36fafbd0]"} + }; + + auto summary = KernelSnapshotContentBuilder(output, false).GenerateSummary(); + + EXPECT_TRUE(summary.find("Uid:") != std::string::npos); + EXPECT_TRUE(summary.find("FaultStack:") == std::string::npos); + + GTEST_LOG_(INFO) << "KernelSnapshotTest055: end."; +} } // namespace HiviewDFX } // namepsace OHOS -- Gitee