1 /*
2  * Copyright (c) 2024 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 <gtest/gtest.h>
17 #include "fp_unwinder.h"
18 #include "unwinder.h"
19 
20 using namespace testing;
21 using namespace testing::ext;
22 
23 namespace OHOS {
24 namespace HiviewDFX {
25 #undef LOG_DOMAIN
26 #undef LOG_TAG
27 #define LOG_TAG "DfxFpUnwinderTest"
28 #define LOG_DOMAIN 0xD002D11
29 
30 class FpUnwinderTest : public testing::Test {
31 public:
SetUpTestCase()32     static void SetUpTestCase() {}
TearDownTestCase()33     static void TearDownTestCase() {}
SetUp()34     void SetUp() {}
TearDown()35     void TearDown() {}
36 };
37 
38 /**
39  * @tc.name: FpUnwinderTest001
40  * @tc.desc: test fp unwinder Unwind interface
41  * @tc.type: FUNC
42  */
43 HWTEST_F(FpUnwinderTest, FpUnwinderTest001, TestSize.Level2)
44 {
45     GTEST_LOG_(INFO) << "FpUnwinderTest001: start.";
46 #if defined(__aarch64__)
47     uintptr_t regs[2]; // 2: pc and fp reg
48     FpUnwinder::GetPcFpRegs(regs);
49     uintptr_t pc = regs[0];
50     uintptr_t fp = regs[1];
51     const size_t maxSize = 32;
52     uintptr_t pcs[maxSize] = {0};
53     auto unwSz = FpUnwinder::GetPtr()->Unwind(pc, fp, pcs, maxSize);
54     ASSERT_GT(unwSz, 1);
55 
56     std::vector<DfxFrame> frames;
57     for (auto i = 0; i < unwSz; ++i) {
58         DfxFrame frame;
59         frame.index = i;
60         frame.pc = static_cast<uint64_t>(pcs[i]);
61         frames.emplace_back(frame);
62     }
63     ASSERT_GT(frames.size(), 1);
64     Unwinder::FillLocalFrames(frames);
65     GTEST_LOG_(INFO) << "FpUnwinderTest001: frames:\n" << Unwinder::GetFramesStr(frames);
66 #endif
67     GTEST_LOG_(INFO) << "FpUnwinderTest001: end.";
68 }
69 
70 /**
71  * @tc.name: FpUnwinderTest002
72  * @tc.desc: test fp unwinder UnwindSafe interface
73  * @tc.type: FUNC
74  */
75 HWTEST_F(FpUnwinderTest, FpUnwinderTest002, TestSize.Level2)
76 {
77     GTEST_LOG_(INFO) << "FpUnwinderTest002: start.";
78 #if defined(__aarch64__)
79     uintptr_t regs[2]; // 2: pc and fp reg
80     FpUnwinder::GetPcFpRegs(regs);
81     uintptr_t pc = regs[0];
82     uintptr_t fp = regs[1];
83     const size_t maxSize = 32;
84     uintptr_t pcs[maxSize] = {0};
85     auto unwSz = FpUnwinder::GetPtr()->UnwindSafe(pc, fp, pcs, maxSize);
86     ASSERT_GT(unwSz, 1);
87 
88     std::vector<DfxFrame> frames;
89     for (auto i = 0; i < unwSz; ++i) {
90         DfxFrame frame;
91         frame.index = i;
92         frame.pc = static_cast<uint64_t>(pcs[i]);
93         frames.emplace_back(frame);
94     }
95     ASSERT_GT(frames.size(), 1);
96     Unwinder::FillLocalFrames(frames);
97     GTEST_LOG_(INFO) << "FpUnwinderTest002: frames:\n" << Unwinder::GetFramesStr(frames);
98 #endif
99     GTEST_LOG_(INFO) << "FpUnwinderTest002: end.";
100 }
101 } // namespace HiviewDFX
102 } // namepsace OHOS