• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #include <gtest/gtest.h>
16 
17 #include <cstdio>
18 #include <dlfcn.h>
19 #include <cstdint>
20 
21 #include "dfx_maps.h"
22 #include "dfx_memory.h"
23 #include "dfx_ptrace.h"
24 #include "dfx_regs.h"
25 #include "dfx_regs_get.h"
26 #include "dfx_test_util.h"
27 #include "unwind_context.h"
28 #include "unwind_define.h"
29 #include "unwind_entry_parser_factory.h"
30 
31 
32 using namespace testing;
33 using namespace testing::ext;
34 using namespace std;
35 
36 namespace OHOS {
37 namespace HiviewDFX {
38 class UnwindEntryParserTest : public testing::Test {
39 public:
SetUpTestCase()40     static void SetUpTestCase() {}
TearDownTestCase()41     static void TearDownTestCase() {}
SetUp()42     void SetUp() {}
TearDown()43     void TearDown() {}
44 };
45 
46 /**
47  * @tc.name: UnwindEntryParser001
48  * @tc.desc: test UnwindEntryParser in local case
49  * @tc.type: FUNC
50  */
51 HWTEST_F(UnwindEntryParserTest, UnwindEntryParseTest001, TestSize.Level2)
52 {
53     GTEST_LOG_(INFO) << "UnwindEntryParser001: start.";
54     auto regs = DfxRegs::Create();
55     auto regsData = regs->RawData();
56     GetLocalRegs(regsData);
57     UnwindContext context;
58     auto memory = std::make_shared<DfxMemory>(UNWIND_TYPE_LOCAL);
59     memory->SetCtx(&context);
60     UnwindTableInfo uti;
61     ASSERT_TRUE(memory->FindUnwindTable(regs->GetPc(), uti) == UNW_ERROR_NONE);
62     auto unwindEntryParser = UnwindEntryParserFactory::CreateUnwindEntryParser(memory);
63     std::shared_ptr<RegLocState> rs = std::make_shared<RegLocState>();
64     ASSERT_TRUE(unwindEntryParser->Step(regs->GetPc(), uti, rs));
65     GTEST_LOG_(INFO) << "UnwindEntryParser001: end.";
66 }
67 
68 /**
69  * @tc.name: UnwindEntryParser002
70  * @tc.desc: test UnwindEntryParser in remote case
71  * @tc.type: FUNC
72  */
73 HWTEST_F(UnwindEntryParserTest, UnwindEntryParseTest002, TestSize.Level2)
74 {
75     GTEST_LOG_(INFO) << "UnwindEntryParser002: start.";
76     pid_t childPid = fork();
77     if (childPid != 0) {
78         ASSERT_TRUE(DfxPtrace::Attach(childPid));
79         auto regs = DfxRegs::CreateRemoteRegs(childPid);
80         UnwindContext context;
81         context.pid = childPid;
82         context.regs = regs;
83         context.maps = DfxMaps::Create(childPid);
84         auto memory = std::make_shared<DfxMemory>(UNWIND_TYPE_REMOTE);
85         memory->SetCtx(&context);
86         std::shared_ptr<DfxMap> map = nullptr;
87         uintptr_t pc = regs->GetPc();
88         ASSERT_TRUE(memory->GetMapByPc(pc, map) == UNW_ERROR_NONE);
89         UnwindTableInfo uti;
90         ASSERT_TRUE(memory->FindUnwindTable(pc, uti) == UNW_ERROR_NONE);
91         auto unwindEntryParser = UnwindEntryParserFactory::CreateUnwindEntryParser(memory);
92         std::shared_ptr<RegLocState> rs = std::make_shared<RegLocState>();
93         ASSERT_TRUE(unwindEntryParser->Step(pc, uti, rs));
94         DfxPtrace::Detach(childPid);
95     } else {
96         const int sleepTime = 2;
97         sleep(sleepTime);
98         _exit(0);
99     }
100     GTEST_LOG_(INFO) << "UnwindEntryParser002: end.";
101 }
102 
103 /**
104  * @tc.name: UnwindEntryParser003
105  * @tc.desc: test UnwindEntryParser in abnomal case
106  * @tc.type: FUNC
107  */
108 HWTEST_F(UnwindEntryParserTest, UnwindEntryParseTest003, TestSize.Level2)
109 {
110     GTEST_LOG_(INFO) << "UnwindEntryParser003: start.";
111     std::shared_ptr <DfxMemory> memory = nullptr;
112     int pc = 0;
113     auto unwindEntryParser = UnwindEntryParserFactory::CreateUnwindEntryParser(memory);
114     std::shared_ptr<RegLocState> rs = std::make_shared<RegLocState>();
115     UnwindTableInfo uti;
116     ASSERT_FALSE(unwindEntryParser->Step(pc, uti, rs));
117     GTEST_LOG_(INFO) << "UnwindEntryParser003: end.";
118 }
119 
120 /**
121  * @tc.name: UnwindEntryParser004
122  * @tc.desc: test UnwindEntryParser in abnomal pc case
123  * @tc.type: FUNC
124  */
125 HWTEST_F(UnwindEntryParserTest, UnwindEntryParseTest004, TestSize.Level2)
126 {
127     GTEST_LOG_(INFO) << "UnwindEntryParser004: start.";
128     pid_t childPid = fork();
129     if (childPid != 0) {
130         ASSERT_TRUE(DfxPtrace::Attach(childPid));
131         auto regs = DfxRegs::CreateRemoteRegs(childPid);
132         UnwindContext context;
133         context.pid = childPid;
134         context.regs = regs;
135         context.maps = DfxMaps::Create(childPid);
136         auto memory = std::make_shared<DfxMemory>(UNWIND_TYPE_REMOTE);
137         memory->SetCtx(&context);
138         uintptr_t pc = regs->GetPc();
139         std::shared_ptr<DfxMap> map = nullptr;
140         ASSERT_TRUE(memory->GetMapByPc(pc, map) == UNW_ERROR_NONE);
141         UnwindTableInfo uti;
142         ASSERT_TRUE(memory->FindUnwindTable(pc, uti) == UNW_ERROR_NONE);
143         auto unwindEntryParser = UnwindEntryParserFactory::CreateUnwindEntryParser(memory);
144         std::shared_ptr<RegLocState> rs = std::make_shared<RegLocState>();
145         ASSERT_FALSE(unwindEntryParser->Step(0, uti, rs));
146         DfxPtrace::Detach(childPid);
147     } else {
148         const int sleepTime = 2;
149         sleep(sleepTime);
150         _exit(0);
151     }
152     GTEST_LOG_(INFO) << "UnwindEntryParser004: end.";
153 }
154 
155 /**
156  * @tc.name: UnwindEntryParser005
157  * @tc.desc: test UnwindEntryParser in abnomal UnwindTableInfo case
158  * @tc.type: FUNC
159  */
160 HWTEST_F(UnwindEntryParserTest, UnwindEntryParseTest005, TestSize.Level2)
161 {
162     GTEST_LOG_(INFO) << "UnwindEntryParser005: start.";
163     pid_t childPid = fork();
164     if (childPid != 0) {
165         ASSERT_TRUE(DfxPtrace::Attach(childPid));
166         auto regs = DfxRegs::CreateRemoteRegs(childPid);
167         UnwindContext context;
168         context.pid = childPid;
169         context.regs = regs;
170         context.maps = DfxMaps::Create(childPid);
171         auto memory = std::make_shared<DfxMemory>(UNWIND_TYPE_REMOTE);
172         memory->SetCtx(&context);
173         auto unwindEntryParser = UnwindEntryParserFactory::CreateUnwindEntryParser(memory);
174         UnwindTableInfo uti;
175         std::shared_ptr<RegLocState> rs = std::make_shared<RegLocState>();
176         ASSERT_FALSE(unwindEntryParser->Step(regs->GetPc(), uti, rs));
177         DfxPtrace::Detach(childPid);
178     } else {
179         const int sleepTime = 2;
180         sleep(sleepTime);
181         _exit(0);
182     }
183     GTEST_LOG_(INFO) << "UnwindEntryParser005: end.";
184 }
185 }
186 }