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