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
20using namespace testing;
21using namespace testing::ext;
22
23namespace OHOS {
24namespace HiviewDFX {
25#undef LOG_DOMAIN
26#undef LOG_TAG
27#define LOG_TAG "DfxFpUnwinderTest"
28#define LOG_DOMAIN 0xD002D11
29
30class FpUnwinderTest : public testing::Test {
31public:
32    static void SetUpTestCase() {}
33    static void TearDownTestCase() {}
34    void SetUp() {}
35    void TearDown() {}
36};
37
38/**
39 * @tc.name: FpUnwinderTest001
40 * @tc.desc: test fp unwinder Unwind interface
41 * @tc.type: FUNC
42 */
43HWTEST_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 */
75HWTEST_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