From 9df26bf8b06249d2499e49d6ba2763f27eb44646 Mon Sep 17 00:00:00 2001 From: xlgitee Date: Tue, 15 Jul 2025 10:26:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=85=E6=A0=B8=E8=BD=AC?= =?UTF-8?q?=E5=82=A8=E8=A7=A3=E6=9E=90=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: I9a509104219a2341b1cdddc3ca211148b9e8e4b5 --- services/BUILD.gn | 1 + services/snapshot/kernel_snapshot_data.h | 3 +- services/snapshot/kernel_snapshot_parser.cpp | 56 ++++++++--------- services/snapshot/kernel_snapshot_parser.h | 5 +- services/snapshot/kernel_snapshot_trie.cpp | 61 +++++++++++++++++++ services/snapshot/kernel_snapshot_trie.h | 39 ++++++++++++ test/unittest/kernel_snapshot/BUILD.gn | 1 + .../kernel_snapshot/kernel_snapshot_test.cpp | 54 ++++++++++++++-- 8 files changed, 183 insertions(+), 37 deletions(-) create mode 100644 services/snapshot/kernel_snapshot_trie.cpp create mode 100644 services/snapshot/kernel_snapshot_trie.h diff --git a/services/BUILD.gn b/services/BUILD.gn index 1353fc784..af120826a 100644 --- a/services/BUILD.gn +++ b/services/BUILD.gn @@ -84,6 +84,7 @@ if (defined(ohos_lite)) { "./snapshot/kernel_snapshot_printer.cpp", "./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_data.h b/services/snapshot/kernel_snapshot_data.h index 1a289af37..32c5ee277 100644 --- a/services/snapshot/kernel_snapshot_data.h +++ b/services/snapshot/kernel_snapshot_data.h @@ -53,7 +53,8 @@ enum class SnapshotSection { CONTENT_OF_USER_STACK, BASE_ACTV_DUMPED, PROCESS_STATISTICS, - TRANSACTION_END + TRANSACTION_END, + INVALID_SECTION }; struct SnapshotSectionKeyword { diff --git a/services/snapshot/kernel_snapshot_parser.cpp b/services/snapshot/kernel_snapshot_parser.cpp index 5df2f30aa..063d963c1 100644 --- a/services/snapshot/kernel_snapshot_parser.cpp +++ b/services/snapshot/kernel_snapshot_parser.cpp @@ -47,6 +47,7 @@ CrashSection GetSnapshotMapCrashItem(SnapshotSection item) KernelSnapshotParser::KernelSnapshotParser() { InitializeParseTable(); + InitializeKeywordTrie(); } bool KernelSnapshotParser::PreProcessLine(std::string& line) const @@ -205,6 +206,13 @@ void KernelSnapshotParser::InitializeParseTable() }; } +void KernelSnapshotParser::InitializeKeywordTrie() +{ + for (const auto& item : SNAPSHOT_SECTION_KEYWORDS) { + snapshotTrie_.Insert(item.key, item.type); + } +} + void KernelSnapshotParser::ProcessSnapshotSection(const SnapshotCell& cell, CrashMap& output) { auto it = parseTable_.find(cell.sectionKey); @@ -217,9 +225,8 @@ void KernelSnapshotParser::ProcessSnapshotSection(const SnapshotCell& cell, Cras } bool KernelSnapshotParser::ProcessTransStart(const std::vector& lines, size_t& index, - std::list>& keywordList, CrashMap& output) + std::string keyword, CrashMap& output) { - const auto& keyword = keywordList.front().second; for (; index < lines.size(); index++) { if (StartsWith(lines[index], keyword)) { break; @@ -232,45 +239,34 @@ bool KernelSnapshotParser::ProcessTransStart(const std::vector& lin SnapshotCell cell {SnapshotSection::TRANSACTION_START, lines, index, index}; ProcessSnapshotSection(cell, output); index++; - keywordList.pop_front(); return true; } CrashMap KernelSnapshotParser::ParseSnapshotUnit(const std::vector& lines, size_t& index) { CrashMap output; - std::list> keywordList; - for (const auto& item : SNAPSHOT_SECTION_KEYWORDS) { - keywordList.emplace_back(item.type, item.key); - } - - if (!ProcessTransStart(lines, index, keywordList, output)) { + if (!ProcessTransStart(lines, index, SNAPSHOT_SECTION_KEYWORDS[0].key, output)) { return output; } // process other snapshot sections - size_t snapshotSecIndex = 0; - SnapshotSection snapshotSecKey; - bool isTransEnd = false; + size_t curSectionLineNum = 0; + SnapshotSection lastSectionKey = SnapshotSection::INVALID_SECTION; + for (; index < lines.size(); index++) { + SnapshotSection curSectionKey; + if (!snapshotTrie_.MatchPrefix(lines[index], curSectionKey)) { + continue; + } + if (curSectionLineNum == 0) { + lastSectionKey = curSectionKey; + curSectionLineNum = index; + continue; + } - for (; index < lines.size() && !isTransEnd; index++) { - for (auto it = keywordList.begin(); it != keywordList.end(); it++) { - if (!StartsWith(lines[index], it->second)) { - continue; - } - if (snapshotSecIndex == 0) { - snapshotSecIndex = index; - snapshotSecKey = it->first; - break; - } - SnapshotCell cell {snapshotSecKey, lines, snapshotSecIndex, index - 1}; - ProcessSnapshotSection(cell, output); - snapshotSecIndex = index; - snapshotSecKey = it->first; - if (it->first == SnapshotSection::TRANSACTION_END) { - isTransEnd = true; - } - keywordList.erase(it); + ProcessSnapshotSection({lastSectionKey, lines, curSectionLineNum, index - 1}, output); + lastSectionKey = curSectionKey; + curSectionLineNum = index; + if (lastSectionKey == SnapshotSection::TRANSACTION_END) { break; } } diff --git a/services/snapshot/kernel_snapshot_parser.h b/services/snapshot/kernel_snapshot_parser.h index 3ec780823..a0e4425e5 100644 --- a/services/snapshot/kernel_snapshot_parser.h +++ b/services/snapshot/kernel_snapshot_parser.h @@ -19,6 +19,7 @@ #include #include "i_kernel_snapshot_parser.h" +#include "kernel_snapshot_trie.h" namespace OHOS { namespace HiviewDFX { @@ -44,7 +45,7 @@ private: std::unordered_map ConvertThreadInfoToPairs(const std::string &line); bool ProcessTransStart(const std::vector& lines, size_t& index, - std::list>& keywordList, CrashMap& output); + std::string keyword, CrashMap& output); void ParseTransStart(const SnapshotCell& cell, CrashMap &output); void ParseThreadInfo(const SnapshotCell& cell, CrashMap &output); @@ -55,8 +56,10 @@ private: void ProcessSnapshotSection(const SnapshotCell& cell, CrashMap &output); void InitializeParseTable(); + void InitializeKeywordTrie(); using ParseFunction = void (KernelSnapshotParser::*)(const SnapshotCell&, CrashMap&); std::unordered_map parseTable_; + KernelSnapshotTrie snapshotTrie_; }; } // namespace HiviewDFX } // namespace OHOS diff --git a/services/snapshot/kernel_snapshot_trie.cpp b/services/snapshot/kernel_snapshot_trie.cpp new file mode 100644 index 000000000..ffe7d021b --- /dev/null +++ b/services/snapshot/kernel_snapshot_trie.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "kernel_snapshot_trie.h" + +namespace OHOS { +namespace HiviewDFX { + +KernelSnapshotTrie::KernelSnapshotTrie() : root_(new TrieNode()) +{ +} + +bool KernelSnapshotTrie::Insert(const std::string& key, SnapshotSection type) +{ + if (key.empty()) { + return false; + } + + TrieNode* currentNode = root_.get(); + for (char ch : key) { + if (currentNode->children.find(ch) == currentNode->children.end()) { + currentNode->children[ch] = std::unique_ptr(new TrieNode()); + } + currentNode = currentNode->children[ch].get(); + } + + currentNode->isEnd = true; + currentNode->sectionType = type; + return true; +} + +bool KernelSnapshotTrie::MatchPrefix(const std::string& key, SnapshotSection& type) const +{ + TrieNode* currentNode = root_.get(); + for (char ch : key) { + auto it = currentNode->children.find(ch); + if (it == currentNode->children.end()) { + return false; + } + currentNode = it->second.get(); + if (currentNode->isEnd) { + type = currentNode->sectionType; + return true; + } + } + return false; +} +} // namespace HiviewDFX +} // namespace OHOS diff --git a/services/snapshot/kernel_snapshot_trie.h b/services/snapshot/kernel_snapshot_trie.h new file mode 100644 index 000000000..1fddb06f2 --- /dev/null +++ b/services/snapshot/kernel_snapshot_trie.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef KERNEL_SNAPSHOT_TRIE_H +#define KERNEL_SNAPSHOT_TRIE_H + +#include "kernel_snapshot_data.h" +namespace OHOS { +namespace HiviewDFX { +class KernelSnapshotTrie { +public: + bool Insert(const std::string& key, SnapshotSection type); + bool MatchPrefix(const std::string& key, SnapshotSection& type) const; + KernelSnapshotTrie(); + KernelSnapshotTrie(const KernelSnapshotTrie&) = delete; + KernelSnapshotTrie& operator=(const KernelSnapshotTrie&) = delete; +private: + struct TrieNode { + bool isEnd = false; + SnapshotSection sectionType; + std::unordered_map> children; + }; + std::unique_ptr root_; +}; +} // namespace HiviewDFX +} // namespace OHOS +#endif diff --git a/test/unittest/kernel_snapshot/BUILD.gn b/test/unittest/kernel_snapshot/BUILD.gn index 1a798d140..5af60d522 100644 --- a/test/unittest/kernel_snapshot/BUILD.gn +++ b/test/unittest/kernel_snapshot/BUILD.gn @@ -47,6 +47,7 @@ if (defined(ohos_lite)) { "$faultloggerd_path/services/snapshot/kernel_snapshot_printer.cpp", "$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", ] diff --git a/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp b/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp index bb32534ac..a892689d8 100644 --- a/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp +++ b/test/unittest/kernel_snapshot/kernel_snapshot_test.cpp @@ -25,6 +25,7 @@ #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; @@ -485,12 +486,8 @@ HWTEST_F(KernelSnapshotTest, KernelSnapshotTest024, TestSize.Level2) }; CrashMap output; - std::list> keywordList; - for (const auto& item : SNAPSHOT_SECTION_KEYWORDS) { - keywordList.emplace_back(item.type, item.key); - } size_t index = 0; - parser.ProcessTransStart(lines, index, keywordList, output); + parser.ProcessTransStart(lines, index, SNAPSHOT_SECTION_KEYWORDS[0].key, output); ASSERT_EQ(output[CrashSection::TIME_STAMP], "1733329272590"); GTEST_LOG_(INFO) << "KernelSnapshotTest024: end."; } @@ -611,5 +608,52 @@ HWTEST_F(KernelSnapshotTest, KernelSnapshotTest051, TestSize.Level2) ASSERT_TRUE(ret); GTEST_LOG_(INFO) << "KernelSnapshotTest051: end."; } + +/** + * @tc.name: KernelSnapshotTest052 + * @tc.desc: test kernel snapshot trie insert + * @tc.type: FUNC + */ +HWTEST_F(KernelSnapshotTest, KernelSnapshotTest052, TestSize.Level2) +{ + GTEST_LOG_(INFO) << "KernelSnapshotTest052: start."; + KernelSnapshotTrie trie; + + bool ret = trie.Insert("", SnapshotSection::TRANSACTION_START); + EXPECT_EQ(ret, false); + + ret = trie.Insert("start", SnapshotSection::TRANSACTION_START); + EXPECT_EQ(ret, true); + + GTEST_LOG_(INFO) << "KernelSnapshotTest052: end."; +} +/** + * @tc.name: KernelSnapshotTest053 + * @tc.desc: test kernel snapshot trie match prefix + * @tc.type: FUNC + */ +HWTEST_F(KernelSnapshotTest, KernelSnapshotTest053, TestSize.Level2) +{ + GTEST_LOG_(INFO) << "KernelSnapshotTest053: start."; + KernelSnapshotTrie trie; + + for (const auto& item : SNAPSHOT_SECTION_KEYWORDS) { + trie.Insert(item.key, item.type); + } + + SnapshotSection type; + bool ret = trie.MatchPrefix(std::string(SNAPSHOT_SECTION_KEYWORDS[0].key), type); + EXPECT_EQ(ret, true); + EXPECT_EQ(type, SNAPSHOT_SECTION_KEYWORDS[0].type); + + trie.MatchPrefix(std::string(SNAPSHOT_SECTION_KEYWORDS[1].key) + "abc", type); + EXPECT_EQ(ret, true); + EXPECT_EQ(type, SNAPSHOT_SECTION_KEYWORDS[1].type); + + ret = trie.MatchPrefix(std::string("abc"), type); + EXPECT_EQ(ret, false); + + GTEST_LOG_(INFO) << "KernelSnapshotTest053: end."; +} } // namespace HiviewDFX } // namepsace OHOS -- Gitee