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 std::unordered_map<std::string, std::unique_ptr<SymbolsFile>> symbolsFiles;
97 std::string symbolFilePath = PATH_RESOURCE_TEST_DWARF_DATA + TEST_DWARF_ELF;
98 symbolsFiles[symbolFilePath] = SymbolsFile::CreateSymbolsFile(SYMBOL_ELF_FILE, symbolFilePath);
99 auto& symbolsFile = symbolsFiles[symbolFilePath];
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(), GetThreadId(), symbolsFiles, runtime.get(), false);
105 MakeMaps(thread);
106 std::vector<CallFrame> callFrames;
107 CallStack callStack;
108 callStack.UnwindCallStack(thread, regs.data(), regs.size(), data.data(), data.size(), callFrames);
109 }
110 }
111 } // namespace NativeDaemon
112 } // namespace Developtools
113 } // namespace OHOS
114