• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 <ctime>
18 #include <securec.h>
19 #include <string>
20 #include <vector>
21 #include "dfx_ptrace.h"
22 #include "dfx_regs.h"
23 
24 using namespace OHOS::HiviewDFX;
25 using namespace testing::ext;
26 using namespace std;
27 
28 namespace OHOS {
29 namespace HiviewDFX {
30 class DfxRegsTest : public testing::Test {
31 public:
SetUpTestCase(void)32     static void SetUpTestCase(void) {}
TearDownTestCase(void)33     static void TearDownTestCase(void) {}
SetUp()34     void SetUp() {}
TearDown()35     void TearDown() {}
36 };
37 
38 namespace {
39 /**
40  * @tc.name: DfxRegsTest001
41  * @tc.desc: test DfxRegs SetRegsData & GetRegsData functions
42  * @tc.type: FUNC
43  */
44 HWTEST_F(DfxRegsTest, DfxRegsTest001, TestSize.Level2)
45 {
46     GTEST_LOG_(INFO) << "DfxRegsTest001: start.";
47     auto dfxRegs = DfxRegs::Create();
48     ASSERT_NE(dfxRegs, nullptr);
49     std::vector<uintptr_t> setRegs {};
50     for (size_t i = 0; i < 10; i++) { // test 10 regs
51         setRegs.push_back(i);
52     }
53     dfxRegs->SetRegsData(setRegs);
54     auto getRegs = dfxRegs->GetRegsData();
55     ASSERT_EQ(setRegs, getRegs);
56 
57     uintptr_t regsData[REG_LAST] = { 0 };
58     dfxRegs->SetRegsData(regsData, REG_LAST);
59     getRegs = dfxRegs->GetRegsData();
60     for (size_t i = 0; i < getRegs.size(); i++) {
61         ASSERT_EQ(regsData[i], getRegs[i]);
62     }
63 
64     GTEST_LOG_(INFO) << "DfxRegsTest001: end.";
65 }
66 
67 /**
68  * @tc.name: DfxRegsTest002
69  * @tc.desc: test DfxRegs GetSpecialRegisterName
70  * @tc.type: FUNC
71  */
72 HWTEST_F(DfxRegsTest, DfxRegsTest002, TestSize.Level2)
73 {
74     GTEST_LOG_(INFO) << "DfxRegsTest002: start.";
75     auto dfxRegs = DfxRegs::Create();
76     uintptr_t val = 0x00000001;
77     dfxRegs->SetPc(val);
78     ASSERT_EQ(dfxRegs->GetPc(), val);
79     auto name = dfxRegs->GetSpecialRegsName(val);
80     ASSERT_EQ(name, "pc");
81 
82     val = 0x00000002;
83     dfxRegs->SetSp(val);
84     ASSERT_EQ(dfxRegs->GetSp(), val);
85     ASSERT_EQ(dfxRegs->GetSpecialRegsName(val), "sp");
86     ASSERT_EQ((*dfxRegs.get())[REG_SP], val);
87     ASSERT_GT(dfxRegs->RegsSize(), 0U);
88     uintptr_t *regVal = &val;
89     dfxRegs->SetReg(0, regVal);
90     ASSERT_EQ((*dfxRegs.get())[0], *regVal);
91     uintptr_t fp = 0x00000001;
92     uintptr_t lr = 0x00000002;
93     uintptr_t sp = 0x00000003;
94     uintptr_t pc = 0x00000004;
95     dfxRegs->SetSpecialRegs(fp, lr, sp, pc);
96 #if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
97     ASSERT_EQ(dfxRegs->GetSpecialRegsName(lr), "lr");
98     ASSERT_EQ(dfxRegs->GetSpecialRegsName(fp), "fp");
99     ASSERT_EQ(dfxRegs->GetSpecialRegsName(0x0), "");
100 #endif
101     ASSERT_EQ(dfxRegs->GetSpecialRegsName(pc), "pc");
102     ASSERT_EQ(dfxRegs->GetSpecialRegsName(sp), "sp");
103     uintptr_t fpGet;
104     uintptr_t lrGet;
105     uintptr_t spGet;
106     uintptr_t pcGet;
107     dfxRegs->GetSpecialRegs(fpGet, lrGet, spGet, pcGet);
108 #if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
109     ASSERT_EQ(fp, fpGet);
110     ASSERT_EQ(lr, lrGet);
111 #endif
112     ASSERT_EQ(sp, spGet);
113     ASSERT_EQ(pc, pcGet);
114     ASSERT_FALSE(dfxRegs->PrintRegs().empty());
115     ASSERT_FALSE(dfxRegs->PrintSpecialRegs().empty());
116 #if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
117     ASSERT_EQ(dfxRegs->GetSpecialRegsNameByIndex(REG_FP), "fp");
118     ASSERT_EQ(dfxRegs->GetSpecialRegsNameByIndex(REG_LR), "lr");
119 #endif
120     ASSERT_EQ(dfxRegs->GetSpecialRegsNameByIndex(REG_PC), "pc");
121     ASSERT_EQ(dfxRegs->GetSpecialRegsNameByIndex(REG_SP), "sp");
122     GTEST_LOG_(INFO) << "DfxRegsTest002: end.";
123 }
124 
125 /**
126  * @tc.name: DfxRegsTest003
127  * @tc.desc: test DfxRegs CreateFromUcontext
128  * @tc.type: FUNC
129  */
130 HWTEST_F(DfxRegsTest, DfxRegsTest003, TestSize.Level2)
131 {
132     GTEST_LOG_(INFO) << "DfxRegsTest003: start.";
133 
134     ucontext_t context;
135 #if defined(__arm__)
136     context.uc_mcontext.arm_r0 = 0; // 0 : the 1st register of arm
137     context.uc_mcontext.arm_r1 = 1; // 1 : the 2st register of arm
138     context.uc_mcontext.arm_r2 = 2; // 2 : the 3st register of arm
139     context.uc_mcontext.arm_r3 = 3; // 3 : the 4st register of arm
140     context.uc_mcontext.arm_r4 = 4; // 4 : the 5st register of arm
141     context.uc_mcontext.arm_r5 = 5; // 5 : the 6st register of arm
142     context.uc_mcontext.arm_r6 = 6; // 6 : the 7st register of arm
143     context.uc_mcontext.arm_r7 = 7; // 7 : the 8st register of arm
144     context.uc_mcontext.arm_r8 = 8; // 8 : the 9st register of arm
145     context.uc_mcontext.arm_r9 = 9; // 9 : the 10st register of arm
146     context.uc_mcontext.arm_r10 = 10; // 10 : the 11st register of arm
147     context.uc_mcontext.arm_fp = 11; // 11 : the 12st register of arm
148     context.uc_mcontext.arm_ip = 12; // 12 : the 13st register of arm
149     context.uc_mcontext.arm_sp = 13; // 13 : the 14st register of arm
150     context.uc_mcontext.arm_lr = 14; // 14 : the 15st register of arm
151     context.uc_mcontext.arm_pc = 15; // 15 : the 16st register of arm
152 #elif defined(__aarch64__)
153     for (int i = 0; i < 31; i++) {
154         context.uc_mcontext.regs[i] = i;
155     }
156     context.uc_mcontext.sp = 31; // 31 : the 32st register of aarch64
157     context.uc_mcontext.pc = 32; // 32 : the 33st register of aarch64
158 #elif defined(__x86_64__)
159     context.uc_mcontext.gregs[REG_RAX] = 0; // 0 : the 1st register of x86_64
160     context.uc_mcontext.gregs[REG_RDX] = 1; // 1 : the 2st register of x86_64
161     context.uc_mcontext.gregs[REG_RCX] = 2; // 2 : the 3st register of x86_64
162     context.uc_mcontext.gregs[REG_RBX] = 3; // 3 : the 4st register of x86_64
163     context.uc_mcontext.gregs[REG_RSI] = 4; // 4 : the 5st register of x86_64
164     context.uc_mcontext.gregs[REG_RDI] = 5; // 5 : the 6st register of x86_64
165     context.uc_mcontext.gregs[REG_RBP] = 6; // 6 : the 7st register of x86_64
166     context.uc_mcontext.gregs[REG_RSP] = 7; // 7 : the 8st register of x86_64
167     context.uc_mcontext.gregs[REG_R8] = 8; // 8 : the 9st register of x86_64
168     context.uc_mcontext.gregs[REG_R9] = 9; // 9 : the 10st register of x86_64
169     context.uc_mcontext.gregs[REG_R10] = 10; // 10 : the 11st register of x86_64
170     context.uc_mcontext.gregs[REG_R11] = 11; // 11 : the 12st register of x86_64
171     context.uc_mcontext.gregs[REG_R12] = 12; // 12 : the 13st register of x86_64
172     context.uc_mcontext.gregs[REG_R13] = 13; // 13 : the 14st register of x86_64
173     context.uc_mcontext.gregs[REG_R14] = 14; // 14 : the 15st register of x86_64
174     context.uc_mcontext.gregs[REG_R15] = 15; // 15 : the 16st register of x86_64
175     context.uc_mcontext.gregs[REG_RIP] = 16; // 16 : the 17st register of x86_64
176 #endif
177     auto dfxRegs = DfxRegs::CreateFromUcontext(context);
178     for (size_t i = 0; i < REG_LAST; i++) {
179         ASSERT_EQ((*dfxRegs.get())[i], i);
180     }
181     GTEST_LOG_(INFO) << "DfxRegsTest003: end.";
182 }
183 
184 /**
185  * @tc.name: DfxRegsTest004
186  * @tc.desc: test DfxRegs SetFromQutMiniRegs SetFromFpMiniRegs
187  * @tc.type: FUNC
188  */
189 HWTEST_F(DfxRegsTest, DfxRegsTest004, TestSize.Level2)
190 {
191     GTEST_LOG_(INFO) << "DfxRegsTest004: start.";
192 #if defined(__arm__)
193     uintptr_t pushRegs[QUT_MINI_REGS_SIZE];
194     for (size_t i = 0; i < QUT_MINI_REGS_SIZE; ++i) {
195         pushRegs[i] = i + 1;
196     }
197     uintptr_t qutRegs[QUT_MINI_REGS_SIZE] = {REG_ARM_R4, REG_ARM_R7, REG_ARM_R10, REG_ARM_R11,
198         REG_SP, REG_PC, REG_LR};
199     uintptr_t fpRegs[FP_MINI_REGS_SIZE] = {REG_ARM_R7, REG_FP, REG_SP, REG_PC};
200     auto dfxregsArm = std::make_shared<DfxRegsArm>();
201     dfxregsArm->SetFromQutMiniRegs(pushRegs, QUT_MINI_REGS_SIZE);
202     for (size_t i = 0; i < sizeof(qutRegs) / sizeof(qutRegs[0]); ++i) {
203         ASSERT_EQ((*dfxregsArm.get())[qutRegs[i]], pushRegs[i]);
204     }
205     dfxregsArm->SetFromFpMiniRegs(pushRegs, FP_MINI_REGS_SIZE);
206     for (size_t i = 0; i < sizeof(fpRegs) / sizeof(fpRegs[0]); ++i) {
207         ASSERT_EQ((*dfxregsArm.get())[fpRegs[i]], pushRegs[i]);
208     }
209 
210 #elif defined(__aarch64__)
211     uintptr_t pushRegs[QUT_MINI_REGS_SIZE];
212     for (size_t i = 0; i < QUT_MINI_REGS_SIZE; ++i) {
213         pushRegs[i] = i;
214     }
215     uintptr_t qutRegs[QUT_MINI_REGS_SIZE] = {REG_AARCH64_X0, REG_AARCH64_X20, REG_AARCH64_X28,
216         REG_FP, REG_SP, REG_AARCH64_PC, REG_LR};
217     uintptr_t fpRegs[FP_MINI_REGS_SIZE] = {REG_FP, REG_LR, REG_SP, REG_PC};
218     auto dfxregsArm64 = std::make_shared<DfxRegsArm64>();
219     dfxregsArm64->SetFromQutMiniRegs(pushRegs, QUT_MINI_REGS_SIZE);
220     for (size_t i = 1; i < sizeof(qutRegs) / sizeof(qutRegs[0]); ++i) {
221         ASSERT_EQ((*dfxregsArm64.get())[qutRegs[i]], pushRegs[i]);
222     }
223     dfxregsArm64->SetFromFpMiniRegs(pushRegs, FP_MINI_REGS_SIZE);
224     for (size_t i = 0; i < sizeof(fpRegs) / sizeof(fpRegs[0]); ++i) {
225         ASSERT_EQ((*dfxregsArm64.get())[fpRegs[i]], pushRegs[i]);
226     }
227 #endif
228     GTEST_LOG_(INFO) << "DfxRegsTest004: end.";
229 }
230 
231 /**
232  * @tc.name: DfxRegsTest005
233  * @tc.desc: test DfxRegs CreateFromRegs
234  * @tc.type: FUNC
235  */
236 HWTEST_F(DfxRegsTest, DfxRegsTest005, TestSize.Level2)
237 {
238     GTEST_LOG_(INFO) << "DfxRegsTest005: start.";
239 #if defined(__arm__)
240     uintptr_t regs[QUT_MINI_REGS_SIZE];
241     for (size_t i = 0; i < QUT_MINI_REGS_SIZE; ++i) {
242         regs[i] = i + 1;
243     }
244     uintptr_t minimal[QUT_MINI_REGS_SIZE] = {REG_ARM_R4, REG_ARM_R7, REG_ARM_R10, REG_ARM_R11,
245         REG_SP, REG_PC, REG_LR};
246     uintptr_t framePointer[FP_MINI_REGS_SIZE] = {REG_ARM_R7, REG_FP, REG_SP, REG_PC};
247     auto dfxRegs = DfxRegs::CreateFromRegs(UnwindMode::FRAMEPOINTER_UNWIND, regs, sizeof(regs) / sizeof(regs[0]));
248     for (size_t i = 0; i < sizeof(framePointer) / sizeof(framePointer[0]); ++i) {
249         ASSERT_EQ((*dfxRegs.get())[framePointer[i]], regs[i]);
250     }
251     dfxRegs = DfxRegs::CreateFromRegs(UnwindMode::MINIMAL_UNWIND, regs, sizeof(regs) / sizeof(regs[0]));
252     for (size_t i = 0; i < sizeof(minimal) / sizeof(minimal[0]); ++i) {
253         ASSERT_EQ((*dfxRegs.get())[minimal[i]], regs[i]);
254     }
255 
256 #elif defined(__aarch64__)
257     uintptr_t regs[QUT_MINI_REGS_SIZE];
258     for (size_t i = 0; i < QUT_MINI_REGS_SIZE; ++i) {
259         regs[i] = i;
260     }
261     uintptr_t minimal[QUT_MINI_REGS_SIZE] = {REG_AARCH64_X0, REG_AARCH64_X20, REG_AARCH64_X28,
262         REG_FP, REG_SP, REG_PC, REG_LR};
263     uintptr_t framePointer[FP_MINI_REGS_SIZE] = {REG_FP, REG_LR, REG_SP, REG_PC};
264     auto dfxRegs = DfxRegs::CreateFromRegs(UnwindMode::FRAMEPOINTER_UNWIND, regs, sizeof(regs) / sizeof(regs[0]));
265     for (size_t i = 1; i < sizeof(framePointer) / sizeof(framePointer[0]); ++i) {
266         ASSERT_EQ((*dfxRegs.get())[framePointer[i]], regs[i]);
267     }
268     dfxRegs = DfxRegs::CreateFromRegs(UnwindMode::MINIMAL_UNWIND, regs, sizeof(regs) / sizeof(regs[0]));
269     for (size_t i = 0; i < sizeof(minimal) / sizeof(minimal[0]); ++i) {
270         ASSERT_EQ((*dfxRegs.get())[minimal[i]], regs[i]);
271     }
272 #endif
273     GTEST_LOG_(INFO) << "DfxRegsTest005: end.";
274 }
275 
276 
277 /**
278  * @tc.name: DfxRegsTest006
279  * @tc.desc: test DfxRegs CreateRemoteRegs
280  * @tc.type: FUNC
281  */
282 HWTEST_F(DfxRegsTest, DfxRegsTest006, TestSize.Level2)
283 {
284     GTEST_LOG_(INFO) << "DfxRegsTest006: start.";
285     static pid_t pid = getpid();
286     pid_t child = fork();
287     if (child == 0) {
288         DfxPtrace::Attach(pid);
289         auto dfxRegs = DfxRegs::CreateRemoteRegs(pid);
290         constexpr size_t maxIdx = 100;
291         ASSERT_NE(dfxRegs->GetReg(0), nullptr);
292         ASSERT_EQ(dfxRegs->GetReg(maxIdx), nullptr);
293         uintptr_t value = 0;
294         dfxRegs->SetReg(maxIdx, &value);
295 #if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
296         uintptr_t fp = 0x80;
297         dfxRegs->SetFp(fp);
298         ASSERT_EQ(dfxRegs->GetFp(), fp);
299 #endif
300         DfxPtrace::Detach(pid);
301         _exit(0);
302     }
303     int status;
304     int ret = wait(&status);
305     ASSERT_EQ(status, 0);
306     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
307     GTEST_LOG_(INFO) << "DfxRegsTest006: end.";
308 }
309 }
310 } // namespace HiviewDFX
311 } // namespace OHOS
312