• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "symbols_file_test.h"
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 #include <hilog/log.h>
21 #include <random>
22 #include <unistd.h>
23 
24 using namespace testing::ext;
25 using namespace std;
26 using namespace OHOS::HiviewDFX;
27 
28 namespace OHOS {
29 namespace Developtools {
30 namespace HiPerf {
31 class SymbolsFileTest : public testing::Test {
32 public:
33     static void SetUpTestCase(void);
34     static void TearDownTestCase(void);
35     void SetUp();
36     void TearDown();
37     void CheckSymbols(const std::unique_ptr<SymbolsFile> &symbolsFile) const;
38     void PrintSymbols(const std::vector<DfxSymbol> &symbol) const;
39     bool KptrRestrict() const;
40 
LoadSymbols(SymbolsFileType symbolsFileType)41     std::unique_ptr<SymbolsFile> LoadSymbols(SymbolsFileType symbolsFileType)
42     {
43         std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(symbolsFileType);
44         EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
45         return symbolsFile;
46     }
47 
TestLoadSymbols(SymbolsFileType symbolsFileType,const std::string & path)48     bool TestLoadSymbols(SymbolsFileType symbolsFileType, const std::string &path)
49     {
50         std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(symbolsFileType);
51         EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
52         return symbolsFile->LoadSymbols(nullptr, path);
53     }
54     default_random_engine rnd_;
55 };
56 
SetUpTestCase()57 void SymbolsFileTest::SetUpTestCase() {}
58 
TearDownTestCase()59 void SymbolsFileTest::TearDownTestCase() {}
60 
SetUp()61 void SymbolsFileTest::SetUp() {}
62 
TearDown()63 void SymbolsFileTest::TearDown() {}
64 
KptrRestrict() const65 bool SymbolsFileTest::KptrRestrict() const
66 {
67     std::ifstream inputString(KPTR_RESTRICT, std::ios::in);
68     if (inputString) {
69         string kptrRestrict = "1";
70         inputString >> kptrRestrict;
71         if (kptrRestrict == "0") {
72             return false;
73         }
74     }
75     return true;
76 }
77 
CheckSymbols(const std::unique_ptr<SymbolsFile> & symbolsFile) const78 void SymbolsFileTest::CheckSymbols(const std::unique_ptr<SymbolsFile> &symbolsFile) const
79 {
80     auto symbols = symbolsFile->GetSymbols();
81     EXPECT_EQ(symbols.empty(), false);
82     ASSERT_GE(symbols.size(), 1u);
83     PrintSymbols(symbols);
84 
85     // first is 0
86     EXPECT_EQ(symbolsFile->GetSymbolWithVaddr(0x0).funcVaddr_, 0u);
87 
88     // last is IsValid
89     EXPECT_EQ(symbolsFile->GetSymbolWithVaddr(std::numeric_limits<uint64_t>::max()).IsValid(),
90               true);
91 
92     for (uint64_t pos = 0; pos < symbols.size(); ++pos) {
93         uint64_t vaddr = symbols[pos].funcVaddr_;
94         EXPECT_EQ(symbolsFile->GetSymbolWithVaddr(vaddr).funcVaddr_, vaddr);
95     }
96     for (auto symbol : symbols) {
97         if (symbol.name_.find("_Z") != std::string::npos) {
98             EXPECT_NE(symbol.demangle_.find("_Z"), 0u);
99         }
100     }
101 }
102 
PrintSymbols(const std::vector<DfxSymbol> & symbols) const103 void SymbolsFileTest::PrintSymbols(const std::vector<DfxSymbol> &symbols) const
104 {
105     size_t printNumber = 15;
106     if (printNumber > symbols.size())
107         printNumber = symbols.size();
108 
109     printf("first %zu:\n", printNumber);
110     for (size_t i = 0; i < printNumber; i++) {
111         printf("%s\n", symbols[i].ToDebugString().c_str());
112     }
113     if (printNumber < symbols.size()) {
114         printf("last %zu:\n", printNumber);
115         for (size_t i = printNumber; i > 0; i--) {
116             printf("%s\n", symbols[symbols.size() - i].ToDebugString().c_str());
117         }
118     }
119 }
120 
121 /**
122  * @tc.name: setSymbolsFilePath
123  * @tc.desc:
124  * @tc.type: FUNC
125  */
126 HWTEST_F(SymbolsFileTest, setSymbolsFilePath, TestSize.Level1)
127 {
128     auto symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
129     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_DATA_TEMP), true);
130     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_NOT_EXISTS), false);
131     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_DATA_TEMP_WINDOS), false);
132     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_ILLEGAL), false);
133     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
134     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA_NO_ENDPATH), true);
135 }
136 
137 /**
138  * @tc.name: setSymbolsFilePath
139  * @tc.desc:
140  * @tc.type: FUNC
141  */
142 HWTEST_F(SymbolsFileTest, setSymbolsFilePathVectorSuccess, TestSize.Level1)
143 {
144     auto symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
145     std::vector<std::string> symbolsSearchPaths;
146 
147     symbolsSearchPaths.clear();
148     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
149     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
150 
151     symbolsSearchPaths.clear();
152     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
153     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
154     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
155 
156     symbolsSearchPaths.clear();
157     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
158     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
159     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
160     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
161 }
162 
163 /**
164  * @tc.name: setSymbolsFilePath
165  * @tc.desc:
166  * @tc.type: FUNC
167  */
168 HWTEST_F(SymbolsFileTest, setSymbolsFilePathVectorFailed, TestSize.Level1)
169 {
170     auto symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
171     std::vector<std::string> symbolsSearchPaths;
172 
173     symbolsSearchPaths.clear();
174     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
175     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), false);
176 
177     symbolsSearchPaths.clear();
178     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
179     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
180     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), false);
181 
182     symbolsSearchPaths.clear();
183     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
184     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
185     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
186     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), false);
187 }
188 
189 /**
190  * @tc.name: setSymbolsFilePath
191  * @tc.desc:
192  * @tc.type: FUNC
193  */
194 HWTEST_F(SymbolsFileTest, setSymbolsFilePathVectorMixSucessed, TestSize.Level1)
195 {
196     auto symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
197     std::vector<std::string> symbolsSearchPaths;
198 
199     symbolsSearchPaths.clear();
200     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
201     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
202     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
203 
204     symbolsSearchPaths.clear();
205     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
206     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
207     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
208     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
209     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
210 
211     symbolsSearchPaths.clear();
212     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
213     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
214     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
215     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
216     symbolsSearchPaths.push_back(PATH_DATA_TEMP);
217     symbolsSearchPaths.push_back(PATH_NOT_EXISTS);
218     EXPECT_EQ(symbolsFile->setSymbolsFilePath(symbolsSearchPaths), true);
219 }
220 
TestLoadSymbols(SymbolsFileType symbolsFileType,const std::string & path)221 bool TestLoadSymbols(SymbolsFileType symbolsFileType, const std::string &path)
222 {
223     std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(symbolsFileType);
224     EXPECT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
225     return symbolsFile->LoadSymbols(nullptr, path);
226 }
227 
228 /**
229  * @tc.name: SymbolsFile Default Virtual
230  * @tc.desc:
231  * @tc.type: FUNC
232  */
233 HWTEST_F(SymbolsFileTest, SymbolsFileDefaultVirtual, TestSize.Level1)
234 {
235     std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE);
236     uint64_t value = 0;
237     ASSERT_EQ(symbolsFile->LoadDebugInfo(), false);
238     EXPECT_EQ(symbolsFile->GetSectionInfo("", value, value, value), false);
239 #ifndef __arm__
240     EXPECT_EQ(symbolsFile->GetHDRSectionInfo(value, value, value), false);
241 #endif
242 }
243 
244 /**
245  * @tc.name: LoaderKernelSymbols
246  * @tc.desc:
247  * @tc.type: FUNC
248  */
249 HWTEST_F(SymbolsFileTest, LoadKernelSymbols, TestSize.Level1)
250 {
251     if (access("/sys/kernel/notes", F_OK) != 0) {
252         printf("cannot access /sys/kernel/notes\n");
253         return;
254     }
255     // read from kernel runtime
256     std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_FILE);
257     ScopeDebugLevel tempLogLevel(LEVEL_VERBOSE);
258     ASSERT_EQ(symbolsFile->LoadSymbols(), true);
259 
260     const std::vector<DfxSymbol> &symbols = symbolsFile->GetSymbols();
261     EXPECT_EQ(symbols.empty(), false);
262 
263     std::string modulesMap = ReadFileToString("/proc/modules");
264     int lines = std::count(modulesMap.begin(), modulesMap.end(), '\n');
265     if (lines < 0) {
266         return;
267     }
268     std::set<std::string> modulesCount;
269     for (auto &symbol : symbols) {
270         if (symbol.module_.length()) {
271             modulesCount.emplace(symbol.module_);
272         }
273     }
274 
275     // add [kernel.kallsyms]
276     if (modulesCount.size() != lines + 1u) {
277         printf("warn: modulesCount != lines + 1, modulesCount: %zu\n", modulesCount.size());
278     }
279     if (HasFailure()) {
280         for (auto &module : modulesCount) {
281             printf("%s\n", module.c_str());
282         }
283     }
284 
285     // try vmlinux
286     EXPECT_EQ(TestLoadSymbols(SYMBOL_KERNEL_FILE, TEST_FILE_VMLINUX), true);
287     EXPECT_EQ(TestLoadSymbols(SYMBOL_KERNEL_FILE, TEST_FILE_VMLINUX_STRIPPED), true);
288     EXPECT_EQ(TestLoadSymbols(SYMBOL_KERNEL_FILE, TEST_FILE_VMLINUX_STRIPPED_NOBUILDID), true);
289     // will be load from runtime, still return true
290     EXPECT_EQ(TestLoadSymbols(SYMBOL_KERNEL_FILE, TEST_FILE_VMLINUX_STRIPPED_BROKEN), true);
291 }
292 
293 /**
294  * @tc.name: LoaderElfSymbols
295  * @tc.desc:
296  * @tc.type: FUNC
297  */
298 HWTEST_F(SymbolsFileTest, LoadElfSymbols, TestSize.Level1)
299 {
300     auto symbolsElfLoader = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
301     auto symbolsElfStrippedLoader = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
302     ScopeDebugLevel tempLogLevel(LEVEL_VERBOSE);
303 
304     EXPECT_EQ(symbolsElfLoader->LoadSymbols(), false);
305 
306     ASSERT_EQ(symbolsElfLoader->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
307     EXPECT_EQ(symbolsElfLoader->LoadSymbols(nullptr, TEST_FILE_ELF), true);
308     if (HasFailure()) {
309         PrintSymbols(symbolsElfLoader->GetSymbols());
310     }
311 
312     ASSERT_EQ(symbolsElfStrippedLoader->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
313     EXPECT_EQ(symbolsElfStrippedLoader->LoadSymbols(nullptr, TEST_FILE_ELF_STRIPPED), true);
314     if (HasFailure()) {
315         PrintSymbols(symbolsElfStrippedLoader->GetSymbols());
316     }
317     EXPECT_GT(symbolsElfLoader->GetSymbols().size(), symbolsElfStrippedLoader->GetSymbols().size());
318 
319     ASSERT_EQ(symbolsElfStrippedLoader->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
320     EXPECT_EQ(symbolsElfStrippedLoader->LoadSymbols(nullptr, TEST_FILE_ELF), true);
321     if (HasFailure()) {
322         PrintSymbols(symbolsElfStrippedLoader->GetSymbols());
323     }
324 
325     // no symbols not means failed.
326     EXPECT_EQ(TestLoadSymbols(SYMBOL_ELF_FILE, TEST_FILE_ELF_STRIPPED), true);
327 
328     // no build id not means failed.
329     EXPECT_EQ(TestLoadSymbols(SYMBOL_ELF_FILE, TEST_FILE_ELF_STRIPPED_NOBUILDID), true);
330 
331     EXPECT_EQ(TestLoadSymbols(SYMBOL_ELF_FILE, TEST_FILE_ELF_STRIPPED_BROKEN), false);
332 }
333 
334 /**
335  * @tc.name: GetSymbolWithVaddr
336  * @tc.desc:
337  * @tc.type: FUNC
338  */
339 HWTEST_F(SymbolsFileTest, GetSymbolWithVaddr, TestSize.Level1)
340 {
341     if (access("/sys/kernel/notes", F_OK) != 0) {
342         printf("cannot access /sys/kernel/notes\n");
343         return;
344     }
345 
346     auto symbols = SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_FILE);
347     if ((0 == getuid())) {
348         HLOGD("in root mode");
349         EXPECT_EQ(symbols->LoadSymbols(), true);
350         CheckSymbols(symbols);
351     } else {
352         EXPECT_EQ(symbols->LoadSymbols(), true);
353         if (!KptrRestrict()) {
354             HLOGD("NOT KptrRestrict");
355             if (!symbols->GetSymbols().empty()) {
356                 CheckSymbols(symbols);
357             } else {
358                 printf("we found this issue in linux-5.10\n");
359             }
360         } else {
361             HLOGD("KptrRestrict");
362             ASSERT_EQ(symbols->GetSymbols().empty(), true);
363         }
364     }
365 }
366 
367 /**
368  * @tc.name: GetSymbolWithVaddr
369  * @tc.desc:
370  * @tc.type: FUNC
371  */
372 HWTEST_F(SymbolsFileTest, GetSymbolWithVaddr2, TestSize.Level1)
373 {
374     auto elfSymbols = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
375     ASSERT_EQ(elfSymbols->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
376     EXPECT_EQ(elfSymbols->LoadSymbols(nullptr, TEST_FILE_ELF), true);
377     ASSERT_EQ(elfSymbols->GetSymbols().empty(), false);
378 
379     /*
380         part of elf32_test's symbols
381         vaddr(hex)  size(dec)   name
382         00001000    0           _init
383         00001030    0
384         00001320    58           _start
385         00001512    27          main
386         0000145d    124         TestGlobalChildFunction
387         000014d9    57          TestGlobalParentFunction
388         // last one
389         00001b38    0           _fini
390 
391         part of elf_test's symbols
392         vaddr(hex)          size(dec)   name
393         0000000000002000    0           _init
394         0000000000002020    0
395         00000000000022f0    47         _start
396         0000000000002478    15          main
397         00000000000023d9    110         TestGlobalChildFunction
398         0000000000002447    49          TestGlobalParentFunction
399         //last one
400         0000000000002aa8    0           _fini
401     */
402 #ifdef __arm__
403     ScopeDebugLevel tempLogLevel(LEVEL_MUCH, true);
404     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00001320).GetName(), "_start");
405     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00001359).GetName(), "_start");
406     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00001512).GetName(), "main");
407     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x0000152c).GetName(), "main");
408     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x0000145d).GetName(), "TestGlobalChildFunction");
409     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x000014d9).GetName(), "TestGlobalParentFunction");
410 #else
411     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x000022f0).GetName(), "_start");
412     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x0000231e).GetName(), "_start");
413     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00002478).GetName(), "main");
414     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00002486).GetName(), "main");
415     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x000023d9).GetName(), "TestGlobalChildFunction");
416     EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(0x00002447).GetName(), "TestGlobalParentFunction");
417 #endif
418     if (HasFailure()) {
419         PrintSymbols(elfSymbols->GetSymbols());
420     }
421 }
422 
423 /**
424  * @tc.name: GetSymbolWithVaddr
425  * @tc.desc:
426  * @tc.type: FUNC
427  */
428 HWTEST_F(SymbolsFileTest, GetSymbolWithVaddrFullMatch, TestSize.Level1)
429 {
430     auto elfSymbols = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
431     ASSERT_EQ(elfSymbols->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
432     if (elfSymbols->LoadSymbols(nullptr, TEST_SYMBOLS_FILE_ELF)) {
433         ASSERT_EQ(elfSymbols->GetSymbols().empty(), false);
434         /*
435             nm -C --defined-only symbols_file_test_elf64
436             addr = 1000 mangle name = _init
437             addr = 1040 mangle name = _start
438             addr = 1070 mangle name = deregister_tm_clones
439             addr = 10a0 mangle name = register_tm_clones
440             addr = 10e0 mangle name = __do_global_dtors_aux
441             addr = 1120 mangle name = frame_dummy
442             addr = 1129 mangle name = main
443             addr = 1140 mangle name = __libc_csu_init
444             addr = 11b0 mangle name = __libc_csu_fini
445 
446             //last one
447             addr = 11b8 mangle name = _fini
448 
449             nm -C --defined-only symbols_file_test_elf32
450             00001000 t _init
451             00001070 T _start
452             000010c0 t deregister_tm_clones
453             00001100 t register_tm_clones
454             00001150 t __do_global_dtors_aux
455             000011a0 t frame_dummy
456             000011ad T main
457             000011d0 T __libc_csu_init
458             00001240 T __libc_csu_fini
459 
460             // last one
461             0000124c T _fini
462         */
463 #ifdef __arm__
464         enum SymbolAddr : uint64_t {
465             PLT = 0X1030U,
466             START = 0X1070U,
467             THUNK_AX = 0X10B0U,
468             DEREG = 0X10C0U,
469             REG = 0X1100U,
470             AUX = 0X1150U,
471             FRAME = 0X11A0U,
472             THUNK_DX = 0X11A9U,
473             MAIN = 0X11ADU,
474             THUNK_BX = 0X11C5U,
475             CSU_INIT = 0X11D0U,
476             CSU_FINI = 0X1240U,
477             THUNK_BP = 0X1245U,
478         };
479 #else
480         enum SymbolAddr : uint64_t {
481             PLT = 0X1020U,
482             START = 0X1040U,
483             DEREG = 0X1070U,
484             REG = 0X10A0U,
485             AUX = 0X10E0U,
486             FRAME = 0X1120U,
487             MAIN = 0X1129U,
488             CSU_INIT = 0X1140U,
489             CSU_FINI = 0X11B0U,
490         };
491 #endif
492 #ifdef __arm__
493         for (uint64_t addr = SymbolAddr::START; addr < SymbolAddr::THUNK_AX; ++addr) {
494 #else
495         for (uint64_t addr = SymbolAddr::START; addr < SymbolAddr::START; ++addr) {
496 #endif
497             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
498                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "_start");
499             }
500         }
501         for (uint64_t addr = SymbolAddr::DEREG; addr < SymbolAddr::REG; ++addr) {
502             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
503                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "deregister_tm_clones");
504             }
505         }
506         for (uint64_t addr = SymbolAddr::REG; addr < SymbolAddr::AUX; ++addr) {
507             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
508                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "register_tm_clones");
509             }
510         }
511         for (uint64_t addr = SymbolAddr::AUX; addr < SymbolAddr::FRAME; ++addr) {
512             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
513                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "__do_global_dtors_aux");
514             }
515         }
516 #ifdef __arm__
517         for (uint64_t addr = SymbolAddr::FRAME; addr < SymbolAddr::THUNK_DX; ++addr) {
518 #else
519         for (uint64_t addr = SymbolAddr::FRAME; addr < SymbolAddr::MAIN; ++addr) {
520 #endif
521             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
522                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "frame_dummy");
523             }
524         }
525 #ifdef __arm__
526         for (uint64_t addr = SymbolAddr::MAIN; addr < SymbolAddr::THUNK_BX; ++addr) {
527 #else
528         for (uint64_t addr = SymbolAddr::MAIN; addr < SymbolAddr::CSU_INIT; ++addr) {
529 #endif
530             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
531                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "main");
532             }
533         }
534         for (uint64_t addr = SymbolAddr::CSU_INIT; addr < SymbolAddr::CSU_FINI; ++addr) {
535             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
536                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "__libc_csu_init");
537             }
538         }
539 #ifdef __arm__
540         for (uint64_t addr = SymbolAddr::CSU_FINI; addr < SymbolAddr::THUNK_BP; ++addr) {
541             if (elfSymbols->GetSymbolWithVaddr(addr).IsValid()) {
542                 EXPECT_EQ(elfSymbols->GetSymbolWithVaddr(addr).demangle_, "__libc_csu_fini");
543             }
544         }
545 #endif
546         if (HasFailure()) {
547             PrintSymbols(elfSymbols->GetSymbols());
548         }
549     }
550 }
551 
552 /**
553  * @tc.name: GetVaddrInSymbols
554  * @tc.desc:
555  * @tc.type: FUNC
556  */
557 HWTEST_F(SymbolsFileTest, GetVaddrInSymbols, TestSize.Level1)
558 {
559     /*
560         00200000-002c5000 r--p 00000000 08:02 46400311
561         002c5000-00490000 r-xp 000c5000 08:02 4640031
562 
563         [14] .text             PROGBITS         00000000002c5000  000c5000
564 
565         if ip is 0x46e6ab
566         1. find the map range is 002c5000-00490000
567         2. ip - map start(002c5000) = map section offset
568         3. map section offset + map page offset(000c5000) = elf file offset
569         4. elf file offset - exec file offset(000c5000)
570             = ip offset (ip always in exec file offset)
571         5. ip offset + exec begin vaddr(2c5000) = virtual ip in elf
572     */
573     auto elfSymbols = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
574     elfSymbols->textExecVaddrFileOffset_ = 0x000c5000;
575     elfSymbols->textExecVaddr_ = 0x002c5000;
576 
577     // most easy case
578     EXPECT_EQ(elfSymbols->GetVaddrInSymbols(0x002c5123, 0x002c5000, 0x000c5000), 0x002c5123U);
579 
580     // ip and map both change
581     EXPECT_EQ(elfSymbols->GetVaddrInSymbols(0xFF2c5123, 0xFF2c5000, 0x000c5000), 0x002c5123U);
582     EXPECT_EQ(elfSymbols->GetVaddrInSymbols(0x00000123, 0x00000000, 0x000c5000), 0x002c5123U);
583 
584     // map page and offset change
585     EXPECT_EQ(elfSymbols->GetVaddrInSymbols(0x002ca123, 0x002c5000, 0x000c0000), 0x002c5123U);
586     EXPECT_EQ(elfSymbols->GetVaddrInSymbols(0x002c4123, 0x002c5000, 0x000c6000), 0x002c5123U);
587 
588     // kernel dont care offset
589     auto kernelSymbols = SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_FILE);
590     EXPECT_EQ(kernelSymbols->GetVaddrInSymbols(0x001234, 0x002c5000, 0x000c5000), 0x001234U);
591 }
592 
593 /**
594  * @tc.name: FindSymbolFile
595  * @tc.desc:
596  * @tc.type: FUNC
597  */
598 HWTEST_F(SymbolsFileTest, FindSymbolFile, TestSize.Level1)
599 {
600     auto symbols = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
601 
602     std::vector<std::string> symbolsFileSearchPaths;
603     std::string symboleFilePath;
604 
605     symboleFilePath = TEST_FILE_VMLINUX;
606     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), true);
607 
608     symbolsFileSearchPaths.emplace_back(PATH_RESOURCE_TEST_DATA);
609     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), false);
610 
611     symbolsFileSearchPaths.clear();
612     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), true);
613 
614     symboleFilePath = PATH_RESOURCE_TEST_DATA + TEST_FILE_VMLINUX;
615     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), false);
616 
617     symbolsFileSearchPaths.emplace_back(PATH_RESOURCE_TEST_DATA);
618     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), false);
619 
620     symboleFilePath = TEST_FILE_ELF;
621     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), false);
622 
623     symbolsFileSearchPaths.clear();
624     EXPECT_EQ(symbols->FindSymbolFile(symbolsFileSearchPaths, symboleFilePath).empty(), true);
625 }
626 
627 /**
628  * @tc.name: GetBuildId
629  * @tc.desc:
630  * @tc.type: FUNC
631  */
632 HWTEST_F(SymbolsFileTest, GetBuildId, TestSize.Level1)
633 {
634     std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
635     // empty elf
636     EXPECT_EQ(symbolsFile->GetBuildId().empty(), true);
637     // set search path
638     ASSERT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
639 
640     symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
641     ASSERT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
642     // kernel elf
643     EXPECT_EQ(symbolsFile->LoadSymbols(nullptr, TEST_FILE_VMLINUX), true);
644     EXPECT_EQ(symbolsFile->GetBuildId().empty(), false);
645 
646     symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
647     ASSERT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
648     // stripped elf
649     EXPECT_EQ(symbolsFile->LoadSymbols(nullptr, TEST_FILE_ELF), true);
650     EXPECT_EQ(symbolsFile->GetBuildId().empty(), false);
651 
652     symbolsFile = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE);
653     ASSERT_EQ(symbolsFile->setSymbolsFilePath(PATH_RESOURCE_TEST_DATA), true);
654     // stripped elf
655     EXPECT_EQ(symbolsFile->LoadSymbols(nullptr, TEST_FILE_ELF_STRIPPED), true);
656     EXPECT_EQ(symbolsFile->GetBuildId().empty(), false);
657 }
658 
659 struct sectionInfo {
660     const std::string name;
661     uint64_t addr;
662     uint64_t size;
663     uint64_t offset;
664 };
665 
666 /**
667  * @tc.name: GetSectionInfo
668  * @tc.desc:
669  * @tc.type: FUNC
670  */
671 HWTEST_F(SymbolsFileTest, GetSectionInfo, TestSize.Level1)
672 {
673     std::unique_ptr<SymbolsFile> symbolsFile =
674         SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE, TEST_FILE_ELF_FULL_PATH);
675     ASSERT_EQ(symbolsFile->LoadDebugInfo(), true);
676     ASSERT_EQ(symbolsFile->LoadSymbols(), true);
677 
678     /*
679     from readelf -e elf32_test
680     32bit
681     [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
682     [ 0]                   NULL            00000000 000000 000000 00      0   0  0
683     [ 1] .interp           PROGBITS        000001b4 0001b4 000013 00   A  0   0  1
684     [ 2] .note.gnu.build-i NOTE            000001c8 0001c8 000024 00   A  0   0  4
685     [16] .text             PROGBITS        00001320 001320 000818 00  AX  0   0 16
686     [19] .eh_frame_hdr     PROGBITS        00002034 002034 0000dc 00   A  0   0  4
687     [20] .eh_frame         PROGBITS        00002110 002110 0003a0 00   A  0   0  4
688     [29] .symtab           SYMTAB          00000000 003034 000710 10     30  50  4
689     [30] .strtab           STRTAB          00000000 003744 000c3d 00      0   0  1
690     [31] .shstrtab         STRTAB          00000000 004381 00012a 00      0   0  1
691 
692     from readelf -e elf_test
693     64bit
694     Section Headers:
695     [Nr] Name              Type             Address           Offset
696         Size              EntSize          Flags  Link  Info  Align
697     [ 0]                   NULL             0000000000000000  00000000
698         0000000000000000  0000000000000000           0     0     0
699     [ 1] .interp           PROGBITS         0000000000000318  00000318
700         000000000000001c  0000000000000000   A       0     0     1
701     [ 2] .note.gnu.propert NOTE             0000000000000338  00000338
702         0000000000000020  0000000000000000   A       0     0     8
703     [16] .text             PROGBITS         00000000000022f0  000022f0
704         00000000000007b5  0000000000000000  AX       0     0     16
705     [19] .eh_frame_hdr     PROGBITS         0000000000003034  00003034
706         00000000000000bc  0000000000000000   A       0     0     4
707     [20] .eh_frame         PROGBITS         00000000000030f0  000030f0
708         0000000000000320  0000000000000000   A       0     0     8
709     [29] .symtab           SYMTAB           0000000000000000  00004040
710         00000000000009f0  0000000000000018          30    50     8
711     [30] .strtab           STRTAB           0000000000000000  00004a30
712         0000000000000bbb  0000000000000000           0     0     1
713     [31] .shstrtab         STRTAB           0000000000000000  000055eb
714         000000000000012c  0000000000000000           0     0     1
715     */
716 #ifdef __arm__
717     const std::vector<sectionInfo> sectionCheckList = {
718         {".note.gnu.build-id", 0x000001c8, 0x000024, 0x0001c8},
719         {".text", 0x00001320, 0x000818, 0x001320},
720         {".eh_frame_hdr", 0x00002034, 0x0000dc, 0x002034},
721         {".eh_frame", 0x00002110, 0x0003a0, 0x002110},
722         {".symtab", 0x00000000, 0x000710, 0x003034},
723         {".strtab", 0x00000000, 0x000c3d, 0x003744},
724     };
725 #else
726     const std::vector<sectionInfo> sectionCheckList = {
727         {".note.gnu.build-id", 0x0000000000000358, 0x0000000000000024, 0x00000358},
728         {".text", 0x00000000000022f0, 0x00000000000007b5, 0x000022f0},
729         {".eh_frame_hdr", 0x0000000000003034, 0x00000000000000bc, 0x00003034},
730         {".eh_frame", 0x00000000000030f0, 0x0000000000000320, 0x000030f0},
731         {".symtab", 0x00000000, 0x00000000000009f0, 0x00004040},
732         {".strtab", 0x00000000, 0x0000000000000bbb, 0x00004a30},
733     };
734 #endif
735     for (sectionInfo info : sectionCheckList) {
736         uint64_t addr;
737         uint64_t size;
738         uint64_t offset;
739         EXPECT_EQ(symbolsFile->GetSectionInfo(info.name, addr, size, offset), true);
740         EXPECT_EQ(addr, info.addr);
741         EXPECT_EQ(size, info.size);
742         EXPECT_EQ(offset, info.offset);
743         if (HasFailure()) {
744             printf("sectionInfo check failed at '%s', %" PRIx64 ",%" PRIx64 ",%" PRIx64 "\n",
745                    info.name.c_str(), info.addr, info.size, info.offset);
746         }
747     }
748 }
749 
750 #ifndef __arm__
751 /**
752  * @tc.name: GetHDRSectionInfo
753  * @tc.desc:
754  * @tc.type: FUNC
755  */
756 HWTEST_F(SymbolsFileTest, GetHDRSectionInfo, TestSize.Level1)
757 {
758     std::unique_ptr<SymbolsFile> symbolsFile =
759         SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE, TEST_FILE_ELF_FULL_PATH);
760 
761     ASSERT_EQ(symbolsFile->LoadSymbols(), true);
762     ASSERT_EQ(symbolsFile->LoadDebugInfo(), true);
763 
764     uint64_t ehFrameHdrElfOffset;
765     uint64_t fdeTableElfOffset;
766     uint64_t fdeTableSize;
767 
768     /*
769         readelf -e elf32_test | grep .eh_frame_hdr
770         [19] .eh_frame_hdr     PROGBITS        00002034 002034 0000dc 00   A  0   0  4
771 
772         readelf --debug-dump=frames elf32_test | grep FDE | wc -l
773         26
774 
775         readelf -e elf_test | grep .eh_frame_hdr
776         [19] .eh_frame_hdr     PROGBITS         0000000000003034  00003034
777 
778         readelf --debug-dump=frames elf_test | grep FDE | wc -l
779         22
780     */
781     symbolsFile->GetHDRSectionInfo(ehFrameHdrElfOffset, fdeTableElfOffset, fdeTableSize);
782 
783     EXPECT_EQ(ehFrameHdrElfOffset, 0x00003034u);
784     EXPECT_EQ(fdeTableSize, 22U);
785 }
786 
787 /**
788  * @tc.name: GetHDRSectionInfo
789  * @tc.desc:
790  * @tc.type: FUNC
791  */
792 HWTEST_F(SymbolsFileTest, GetHDRSectionInfoStripped, TestSize.Level1)
793 {
794     std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::CreateSymbolsFile(
795         SYMBOL_ELF_FILE, PATH_RESOURCE_TEST_DATA + TEST_FILE_ELF_STRIPPED_NOEFHDR);
796 
797     ASSERT_EQ(symbolsFile->LoadDebugInfo(), true);
798 
799     uint64_t ehFrameHdrElfOffset;
800     uint64_t fdeTableElfOffset;
801     uint64_t fdeTableSize;
802 
803     symbolsFile->GetHDRSectionInfo(ehFrameHdrElfOffset, fdeTableElfOffset, fdeTableSize);
804     uint64_t addr = 0;
805     uint64_t size = 0;
806     uint64_t offset = 0;
807     EXPECT_EQ(symbolsFile->GetSectionInfo(EH_FRAME_HR, addr, size, offset), false);
808     EXPECT_EQ(offset, 0U);
809     EXPECT_EQ(size, 0U);
810     EXPECT_EQ(addr, 0U);
811 }
812 #endif
813 
814 /**
815  * @tc.name: CreateSymbolsFile
816  * @tc.desc:
817  * @tc.type: FUNC
818  */
819 HWTEST_F(SymbolsFileTest, CreateSymbolsFile, TestSize.Level1)
820 {
821     EXPECT_NE(SymbolsFile::CreateSymbolsFile(), nullptr);
822     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_FILE), nullptr);
823     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_KERNEL_MODULE_FILE), nullptr);
824     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE), nullptr);
825     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_JAVA_FILE), nullptr);
826     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_JS_FILE), nullptr);
827     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SYMBOL_UNKNOW_FILE), nullptr);
828     EXPECT_NE(SymbolsFile::CreateSymbolsFile(SymbolsFileType(-1)), nullptr);
829     EXPECT_EQ(SymbolsFile::CreateSymbolsFile(SymbolsFileType(-2))->symbolFileType_,
830               SYMBOL_UNKNOW_FILE);
831 
832     EXPECT_EQ(SymbolsFile::CreateSymbolsFile(KERNEL_MMAP_NAME)->symbolFileType_,
833               SYMBOL_KERNEL_FILE);
834     EXPECT_EQ(SymbolsFile::CreateSymbolsFile(TEST_FILE_ELF_FULL_PATH)->symbolFileType_,
835               SYMBOL_ELF_FILE);
836 }
837 
838 /**
839  * @tc.name: LoadSymbolsFromSaved
840  * @tc.desc:
841  * @tc.type: FUNC
842  */
843 HWTEST_F(SymbolsFileTest, LoadSymbolsFromSaved, TestSize.Level1)
844 {
845     SymbolFileStruct sfs;
846     for (unsigned int type = 0; type < SYMBOL_UNKNOW_FILE; type++) {
847         sfs.filePath_ = std::to_string(rnd_());
848         sfs.symbolType_ = type;
849         sfs.textExecVaddrFileOffset_ = rnd_();
850         sfs.textExecVaddr_ = rnd_();
851         sfs.buildId_ = std::to_string(rnd_());
852         int nameIndex = 0;
853         // after LoadSymbolsFromSaved it will sort from low to high
854         // so we make a order item to test
855         constexpr int rndMax = 10000;
856         std::uniform_int_distribution<int> rndLimi(0, rndMax);
857         sfs.symbolStructs_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
858                                         std::to_string(nameIndex));
859         nameIndex++;
860         sfs.symbolStructs_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
861                                         std::to_string(nameIndex));
862         nameIndex++;
863         sfs.symbolStructs_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
864                                         std::to_string(nameIndex));
865         nameIndex++;
866 
867         // setup the min vaddr
868 
869         std::unique_ptr<SymbolsFile> symbolsFile = SymbolsFile::LoadSymbolsFromSaved(sfs);
870 
871         EXPECT_EQ(symbolsFile->filePath_, sfs.filePath_);
872         EXPECT_EQ(symbolsFile->symbolFileType_, sfs.symbolType_);
873         EXPECT_EQ(symbolsFile->textExecVaddr_, sfs.textExecVaddr_);
874         EXPECT_EQ(symbolsFile->textExecVaddrFileOffset_, sfs.textExecVaddrFileOffset_);
875         EXPECT_EQ(symbolsFile->GetBuildId(), sfs.buildId_);
876         EXPECT_EQ(symbolsFile->GetSymbols().size(), sfs.symbolStructs_.size());
877 
878         for (DfxSymbol symbol : symbolsFile->GetSymbols()) {
879             SymbolStruct symbolStruct = sfs.symbolStructs_.front();
880             EXPECT_EQ(symbol.funcVaddr_, symbolStruct.vaddr_);
881             EXPECT_EQ(symbol.size_, symbolStruct.len_);
882             EXPECT_EQ(symbol.name_, symbolStruct.symbolName_);
883             sfs.symbolStructs_.erase(sfs.symbolStructs_.begin());
884         }
885     }
886 }
887 
888 /**
889  * @tc.name: exportSymbolToFileFormatMatched
890  * @tc.desc:
891  * @tc.type: FUNC
892  */
893 HWTEST_F(SymbolsFileTest, exportSymbolToFileFormatMatched, TestSize.Level1)
894 {
895     for (int type = 0; type < SYMBOL_UNKNOW_FILE; type++) {
896         auto symbolsFile = SymbolsFile::CreateSymbolsFile();
897         symbolsFile->filePath_ = std::to_string(rnd_());
898         symbolsFile->symbolFileType_ = static_cast<SymbolsFileType>(type);
899         symbolsFile->textExecVaddrFileOffset_ = rnd_();
900         symbolsFile->buildId_ = std::to_string(rnd_());
901         int nameIndex = 0;
902         // after LoadSymbolsFromSaved it will sort from low to high
903         // so we make a order item to test
904         constexpr int rndMax = 10000;
905         std::uniform_int_distribution<int> rndLimi(0, rndMax);
906         symbolsFile->symbols_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
907                                            std::to_string(nameIndex), symbolsFile->filePath_);
908         nameIndex++;
909         symbolsFile->symbols_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
910                                            std::to_string(nameIndex), symbolsFile->filePath_);
911         nameIndex++;
912         symbolsFile->symbols_.emplace_back(rndLimi(rnd_) + nameIndex * rndMax, rnd_(),
913                                            std::to_string(nameIndex), symbolsFile->filePath_);
914         nameIndex++;
915 
916         // setup the min vaddr
917         symbolsFile->textExecVaddr_ = std::numeric_limits<uint64_t>::max();
918 
919         for (auto &symbol : symbolsFile->symbols_) {
920             symbolsFile->textExecVaddr_ = std::min(symbol.funcVaddr_, symbolsFile->textExecVaddr_);
921         }
922 
923         // access last one to make it as matched.
924         uint64_t matchedVaddr = symbolsFile->symbols_.back().funcVaddr_;
925         auto symbol = symbolsFile->GetSymbolWithVaddr(matchedVaddr);
926         EXPECT_EQ(symbol.funcVaddr_, matchedVaddr);
927         if (HasFailure()) {
928             PrintSymbols(symbolsFile->GetSymbols());
929         }
930 
931         SymbolFileStruct sfs {};
932         symbolsFile->ExportSymbolToFileFormat(sfs);
933 
934         EXPECT_EQ(symbolsFile->symbolFileType_, sfs.symbolType_);
935         EXPECT_EQ(symbolsFile->textExecVaddrFileOffset_, sfs.textExecVaddrFileOffset_);
936         EXPECT_EQ(symbolsFile->GetBuildId(), sfs.buildId_);
937 
938         // matched one should be remove
939         EXPECT_EQ(sfs.symbolStructs_.size(), 1u);
940         for (SymbolStruct symbolStruct : sfs.symbolStructs_) {
941             // nomore found for matched vaddr
942             EXPECT_EQ(symbolStruct.vaddr_, matchedVaddr);
943         }
944     }
945 }
946 
947 /**
948  * @tc.name: UpdateBuildIdIfMatch
949  * @tc.desc:
950  * @tc.type: FUNC
951  */
952 HWTEST_F(SymbolsFileTest, UpdateBuildIdIfMatch, TestSize.Level1)
953 {
954     auto file = SymbolsFile::CreateSymbolsFile();
955     file->buildId_ = "123";
956     file->UpdateBuildIdIfMatch("456");
957     EXPECT_STREQ(file->buildId_.c_str(), "123");
958     EXPECT_STRNE(file->buildId_.c_str(), "456");
959 }
960 } // namespace HiPerf
961 } // namespace Developtools
962 } // namespace OHOS
963