• 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 "callstack_test.h"
17 #include "virtual_runtime.h"
18 #include "get_thread_id.h"
19 using namespace testing::ext;
20 using namespace std;
21 using namespace OHOS::HiviewDFX;
22 namespace OHOS {
23 namespace Developtools {
24 namespace NativeDaemon {
25 class CallStackTest : public testing::Test {
26 public:
27     static void SetUpTestCase(void);
28     static void TearDownTestCase(void);
29     void SetUp();
30     void TearDown();
31     default_random_engine rnd_;
32 };
33 
SetUpTestCase()34 void CallStackTest::SetUpTestCase() {}
35 
TearDownTestCase()36 void CallStackTest::TearDownTestCase() {}
37 
SetUp()38 void CallStackTest::SetUp() {}
39 
TearDown()40 void CallStackTest::TearDown() {}
41 
42 /**
43  * @tc.name: LibUnwindEmptyFunc
44  * @tc.desc:
45  * @tc.type: FUNC
46  */
47 HWTEST_F(CallStackTest, LibUnwindEmptyFunc, TestSize.Level1)
48 {
49     CallStack callStack = {};
50     unw_addr_space_t as = {};
51     unw_word_t word = {};
52     unw_word_t *wordPtr = {};
53     void *voidPtr = {};
54     char *buf = {};
55     size_t size = {};
56     unw_proc_info_t pi = {};
57     unw_regnum_t rn = {};
58     unw_fpreg_t fp = {};
59     unw_cursor_t t = {};
60     EXPECT_LE(CallStack::getProcName(as, word, buf, size, wordPtr, voidPtr), 0);
61     CallStack::PutUnwindInfo(as, &pi, voidPtr);
62     EXPECT_LE(CallStack::AccessFpreg(as, rn, &fp, 0, voidPtr), 0);
63     EXPECT_LE(CallStack::Resume(as, &t, voidPtr), 0);
64 }
65 
66 /**
67  * @tc.name: GetUnwErrorName
68  * @tc.desc:
69  * @tc.type: FUNC
70  */
71 HWTEST_F(CallStackTest, GetUnwErrorName, TestSize.Level1)
72 {
73     EXPECT_STREQ(CallStack::GetUnwErrorName(UNW_ENOINFO).c_str(), "UNKNOW_UNW_ERROR");
74     EXPECT_STRNE(CallStack::GetUnwErrorName(-UNW_ENOINFO).c_str(), "UNKNOW_UNW_ERROR");
75 }
76 
77 /**
78  * @tc.name: UnwindCallStack
79  * @tc.desc:
80  * @tc.type: FUNC
81  */
82 HWTEST_F(CallStackTest, UnwindCallStack, TestSize.Level1)
83 {
84 #if is_linux
85     return;
86 #endif
87 
88     std::vector<u64> regs;
89     std::vector<u8> data;
90     LoadFromFile(PATH_RESOURCE_TEST_DWARF_DATA + TEST_DWARF_USER_REGS_0, regs);
91     LoadFromFile(PATH_RESOURCE_TEST_DWARF_DATA + TEST_DWARF_USER_DATA_0, data);
92     if (regs.size() > 0 and data.size() > 0) {
93 #ifdef __arm__
94         ASSERT_EQ(regs.size(), 16u);
95 #endif
96 
97     std::set<std::unique_ptr<SymbolsFile>, CCompareSymbolsFile> symbolsFiles;
98     auto &symbolsFile = *symbolsFiles.insert(SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE,
99         PATH_RESOURCE_TEST_DWARF_DATA + TEST_DWARF_ELF)).first;
100     ASSERT_EQ(symbolsFile->LoadSymbols(), true);
101     // fix the name
102     symbolsFile->filePath_ = TEST_DWARF_MMAP.front().fileName;
103     std::shared_ptr<VirtualRuntime> runtime = std::make_shared<VirtualRuntime>();
104     VirtualThread thread(getpid(), get_thread_id(), symbolsFiles, runtime.get(), false);
105     MakeMaps(thread);
106     std::vector<CallFrame> callFrames;
107     CallStack callStack;
108 
109     u64* sppcRegs = new u64[2];
110     sppcRegs[0] = regs[PERF_REG_ARM_SP_IDX];
111     sppcRegs[1] = regs[PERF_REG_ARM_PC_IDX];
112     callStack.UnwindCallStack(thread, sppcRegs, 2, data.data(), data.size(),
113                                   callFrames);
114     delete[] sppcRegs;
115     sppcRegs = nullptr;
116 #ifdef __arm__
117         ASSERT_LE(TEST_DWARF_FRAMES.size(), callFrames.size());
118         for (size_t i = 0; i < TEST_DWARF_FRAMES.size(); i++) {
119             EXPECT_EQ(TEST_DWARF_FRAMES[i].ip, callFrames[i].ip_);
120             EXPECT_EQ(TEST_DWARF_FRAMES[i].sp, callFrames[i].sp_);
121         }
122 #endif
123     }
124 }
125 } // namespace NativeDaemon
126 } // namespace Developtools
127 } // namespace OHOS
128