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 */
HWTEST_F(FpUnwinderTest, FpUnwinderTest001, TestSize.Level2)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 */
HWTEST_F(FpUnwinderTest, FpUnwinderTest002, TestSize.Level2)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