• 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 
22 #include "dfx_memory.h"
23 #include "dfx_regs.h"
24 #include "dfx_regs_get.h"
25 #include "dfx_ptrace.h"
26 #include "dwarf_define.h"
27 #include "stack_util.h"
28 
29 using namespace OHOS::HiviewDFX;
30 using namespace testing::ext;
31 using namespace std;
32 
33 namespace OHOS {
34 namespace HiviewDFX {
35 class DfxMemoryTest : public testing::Test {
36 public:
SetUpTestCase(void)37     static void SetUpTestCase(void) {}
TearDownTestCase(void)38     static void TearDownTestCase(void) {}
SetUp()39     void SetUp() {}
TearDown()40     void TearDown() {}
41 };
42 
43 namespace {
44 /**
45  * @tc.name: DfxMemoryTest001
46  * @tc.desc: test DfxMemory class ReadReg
47  * @tc.type: FUNC
48  */
49 HWTEST_F(DfxMemoryTest, DfxMemoryTest001, TestSize.Level2)
50 {
51     GTEST_LOG_(INFO) << "DfxMemoryTest001: start.";
52     uintptr_t regs[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
53     UnwindContext ctx;
54     ctx.regs = DfxRegs::CreateFromRegs(UnwindMode::DWARF_UNWIND, regs);
55     auto acc = std::make_shared<DfxAccessorsLocal>();
56     auto memory = std::make_shared<DfxMemory>(acc);
57     memory->SetCtx(&ctx);
58     uintptr_t value;
59     bool ret = memory->ReadReg(0, &value);
60     EXPECT_EQ(true, ret) << "DfxMemoryTest001: ret" << ret;
61     EXPECT_EQ(static_cast<uintptr_t>(0x1), value) << "DfxMemoryTest001: value" << value;
62     GTEST_LOG_(INFO) << "DfxMemoryTest001: end.";
63 }
64 
65 /**
66  * @tc.name: DfxMemoryTest002
67  * @tc.desc: test DfxMemory class Read
68  * @tc.type: FUNC
69  */
70 HWTEST_F(DfxMemoryTest, DfxMemoryTest002, TestSize.Level2)
71 {
72     GTEST_LOG_(INFO) << "DfxMemoryTest002: start.";
73     uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
74 
75     uintptr_t addr = (uintptr_t)(&values[0]);
76     uintptr_t value;
77     auto acc = std::make_shared<DfxAccessorsLocal>();
78     auto memory = std::make_shared<DfxMemory>(acc);
79     bool ret = memory->ReadUptr(addr, &value, false);
80     EXPECT_EQ(true, ret) << "DfxMemoryTest002: ret:" << ret;
81 
82 
83     uint64_t tmp;
84     memory->Read(addr, &tmp, sizeof(uint8_t), false);
85     ASSERT_EQ(tmp, 0x01);
86 
87     memory->Read(addr, &tmp, sizeof(uint16_t), false);
88     ASSERT_EQ(tmp, 0x0201);
89 
90     memory->Read(addr, &tmp, sizeof(uint32_t), false);
91     ASSERT_EQ(tmp, 0x04030201);
92 
93     memory->Read(addr, &tmp, sizeof(uint64_t), false);
94     ASSERT_EQ(tmp, 0x0807060504030201);
95 
96     GTEST_LOG_(INFO) << "DfxMemoryTest002: end.";
97 }
98 
99 /**
100  * @tc.name: DfxMemoryTest003
101  * @tc.desc: test DfxMemory class Read
102  * @tc.type: FUNC
103  */
104 HWTEST_F(DfxMemoryTest, DfxMemoryTest003, TestSize.Level2)
105 {
106     GTEST_LOG_(INFO) << "DfxMemoryTest003: start.";
107     uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
108     UnwindContext ctx;
109     auto acc = std::make_shared<DfxAccessorsLocal>();
110     ASSERT_EQ(GetSelfStackRange(ctx.stackBottom, ctx.stackTop), 0);
111     auto memory = std::make_shared<DfxMemory>(acc);
112     memory->SetCtx(&ctx);
113     uintptr_t addr = (uintptr_t)(&values[0]);
114     uintptr_t value;
115     ASSERT_TRUE(memory->ReadUptr(addr, &value, false));
116 #if defined(__arm__)
117     ASSERT_EQ(value, 0x04030201);
118 #elif defined(__aarch64__)
119     ASSERT_EQ(value, 0x0807060504030201);
120 #endif
121 
122     uint64_t tmp;
123     ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint8_t), false));
124     ASSERT_EQ(tmp, 0x01);
125 
126     ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint16_t), false));
127     ASSERT_EQ(tmp, 0x0201);
128 
129     ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint32_t), false));
130     ASSERT_EQ(tmp, 0x04030201);
131 
132     ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint64_t), false));
133     ASSERT_EQ(tmp, 0x0807060504030201);
134 
135     GTEST_LOG_(INFO) << "DfxMemoryTest003: end.";
136 }
137 
138 /**
139  * @tc.name: DfxMemoryTest004
140  * @tc.desc: test DfxMemory class Read
141  * @tc.type: FUNC
142  */
143 HWTEST_F(DfxMemoryTest, DfxMemoryTest004, TestSize.Level2)
144 {
145     GTEST_LOG_(INFO) << "DfxMemoryTest004: start.";
146     uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
147     UnwindContext ctx;
148     auto acc = std::make_shared<DfxAccessorsLocal>();
149     ASSERT_EQ(GetSelfStackRange(ctx.stackBottom, ctx.stackTop), 0);
150     auto memory = std::make_shared<DfxMemory>(acc);
151     memory->SetCtx(&ctx);
152     uintptr_t addr = (uintptr_t)(&values[0]);
153     uint8_t tmp8;
154     ASSERT_TRUE(memory->ReadU8(addr, &tmp8, false));
155     ASSERT_EQ(tmp8, 0x01);
156     uint16_t tmp16;
157     ASSERT_TRUE(memory->ReadU16(addr, &tmp16, false));
158     ASSERT_EQ(tmp16, 0x0201);
159     uint32_t tmp32;
160     ASSERT_TRUE(memory->ReadU32(addr, &tmp32, false));
161     ASSERT_EQ(tmp32, 0x04030201);
162     uint64_t tmp64;
163     ASSERT_TRUE(memory->ReadU64(addr, &tmp64, false));
164     ASSERT_EQ(tmp64, 0x0807060504030201);
165     GTEST_LOG_(INFO) << "DfxMemoryTest004: end.";
166 }
167 
168 /**
169  * @tc.name: DfxMemoryTest005
170  * @tc.desc: test DfxMemory class Read
171  * @tc.type: FUNC
172  */
173 HWTEST_F(DfxMemoryTest, DfxMemoryTest005, TestSize.Level2)
174 {
175     GTEST_LOG_(INFO) << "DfxMemoryTest005: start.";
176     uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
177     UnwindContext ctx;
178     auto acc = std::make_shared<DfxAccessorsLocal>();
179     ASSERT_EQ(GetSelfStackRange(ctx.stackBottom, ctx.stackTop), 0);
180     auto memory = std::make_shared<DfxMemory>(acc);
181     memory->SetCtx(&ctx);
182     uintptr_t addr = (uintptr_t)(&values[0]);
183     uintptr_t valuePrel32;
184     ASSERT_TRUE(memory->ReadPrel31(addr, &valuePrel32));
185     ASSERT_EQ(valuePrel32, 0x04030201 + addr);
186     char testStr[] = "Test ReadString Func";
187     std::string resultStr;
188     uintptr_t addrStr = (uintptr_t)(&testStr[0]);
189     ASSERT_TRUE(memory->ReadString(addrStr, &resultStr, sizeof(testStr)/sizeof(char), false));
190     ASSERT_EQ(testStr, resultStr);
191     ASSERT_EQ(memory->ReadUleb128(addr), 1U);
192     ASSERT_EQ(memory->ReadSleb128(addr), 2);
193     GTEST_LOG_(INFO) << "DfxMemoryTest005: end.";
194 }
195 
196 /**
197  * @tc.name: DfxMemoryTest006
198  * @tc.desc: test DfxMemory class Read
199  * @tc.type: FUNC
200  */
201 HWTEST_F(DfxMemoryTest, DfxMemoryTest006, TestSize.Level2)
202 {
203     GTEST_LOG_(INFO) << "DfxMemoryTest006: start.";
204     UnwindContext ctx;
205     auto acc = std::make_shared<DfxAccessorsLocal>();
206     ASSERT_EQ(GetSelfStackRange(ctx.stackBottom, ctx.stackTop), 0);
207     auto memory = std::make_shared<DfxMemory>(acc);
208     memory->SetCtx(&ctx);
209     ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_absptr), sizeof(uintptr_t));
210     ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata1), 1);
211     ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata2), 2);
212     ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata4), 4);
213     ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata8), 8);
214     GTEST_LOG_(INFO) << "DfxMemoryTest006: end.";
215 }
216 
217 /**
218  * @tc.name: DfxMemoryTest007
219  * @tc.desc: test DfxMemory class ReadReg in remote case
220  * @tc.type: FUNC
221  */
222 HWTEST_F(DfxMemoryTest, DfxMemoryTest007, TestSize.Level2)
223 {
224     GTEST_LOG_(INFO) << "DfxMemoryTest007: start.";
225     uintptr_t regs[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
226     UnwindContext ctx;
227     ctx.regs = DfxRegs::CreateFromRegs(UnwindMode::DWARF_UNWIND, regs);
228     auto acc = std::make_shared<DfxAccessorsRemote>();
229     auto memory = std::make_shared<DfxMemory>(acc);
230     memory->SetCtx(&ctx);
231     uintptr_t value;
232     bool ret = memory->ReadReg(0, &value);
233     EXPECT_EQ(true, ret) << "DfxMemoryTest007: ret" << ret;
234     EXPECT_EQ(static_cast<uintptr_t>(0x1), value) << "DfxMemoryTest007: value" << value;
235     GTEST_LOG_(INFO) << "DfxMemoryTest007: end.";
236 }
237 /**
238  * @tc.name: DfxMemoryTest008
239  * @tc.desc: test DfxMemory class Read in remote case
240  * @tc.type: FUNC
241  */
242 HWTEST_F(DfxMemoryTest, DfxMemoryTest008, TestSize.Level2)
243 {
244     GTEST_LOG_(INFO) << "DfxMemoryTest008: start.";
245     static pid_t pid = getpid();
246     uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
247     pid_t child = fork();
248     if (child == 0) {
249         GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
250         DfxPtrace::Attach(pid);
251         uintptr_t value;
252         UnwindContext ctx;
253         ctx.pid = pid;
254         auto acc = std::make_shared<DfxAccessorsRemote>();
255         auto memory = std::make_shared<DfxMemory>(acc);
256         memory->SetCtx(&ctx);
257         uintptr_t addr = (uintptr_t)(&values[0]);
258         bool ret = memory->ReadUptr(addr, &value, false);
259         EXPECT_EQ(true, ret) << "DfxMemoryTest008: ret:" << ret;
260         uint64_t tmp;
261         memory->Read(addr, &tmp, sizeof(uint8_t), false);
262         EXPECT_EQ(tmp, 0x01);
263 
264         memory->Read(addr, &tmp, sizeof(uint16_t), false);
265         EXPECT_EQ(tmp, 0x0201);
266 
267         memory->Read(addr, &tmp, sizeof(uint32_t), false);
268         EXPECT_EQ(tmp, 0x04030201);
269 
270         memory->Read(addr, &tmp, sizeof(uint64_t), false);
271         EXPECT_EQ(tmp, 0x0807060504030201);
272         DfxPtrace::Detach(pid);
273         _exit(0);
274     }
275     int status;
276     int ret = wait(&status);
277     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
278     GTEST_LOG_(INFO) << "DfxMemoryTest008: end.";
279 }
280 
281 /**
282  * @tc.name: DfxMemoryTest009
283  * @tc.desc: test DfxMemory class Read in remote case
284  * @tc.type: FUNC
285  */
286 HWTEST_F(DfxMemoryTest, DfxMemoryTest009, TestSize.Level2)
287 {
288     GTEST_LOG_(INFO) << "DfxMemoryTest009: start.";
289     static pid_t pid = getpid();
290     uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
291     pid_t child = fork();
292     if (child == 0) {
293         GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
294         DfxPtrace::Attach(pid);
295         UnwindContext ctx;
296         ctx.pid = pid;
297         auto acc = std::make_shared<DfxAccessorsRemote>();
298         auto memory = std::make_shared<DfxMemory>(acc);
299         memory->SetCtx(&ctx);
300         uintptr_t addr = (uintptr_t)(&values[0]);
301         uintptr_t value;
302         ASSERT_TRUE(memory->ReadUptr(addr, &value, false));
303 #if defined(__arm__)
304         ASSERT_EQ(value, 0x04030201);
305 #elif defined(__aarch64__)
306         ASSERT_EQ(value, 0x0807060504030201);
307 #endif
308 
309         uint64_t tmp;
310         ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint8_t), false));
311         ASSERT_EQ(tmp, 0x01);
312 
313         ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint16_t), false));
314         ASSERT_EQ(tmp, 0x0201);
315 
316         ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint32_t), false));
317         ASSERT_EQ(tmp, 0x04030201);
318 
319         ASSERT_TRUE(memory->Read(addr, &tmp, sizeof(uint64_t), false));
320         ASSERT_EQ(tmp, 0x0807060504030201);
321         DfxPtrace::Detach(pid);
322         _exit(0);
323     }
324     int status;
325     int ret = wait(&status);
326     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
327     GTEST_LOG_(INFO) << "DfxMemoryTest009: end.";
328 }
329 
330 /**
331  * @tc.name: DfxMemoryTest010
332  * @tc.desc: test DfxMemory class Read in remote case
333  * @tc.type: FUNC
334  */
335 HWTEST_F(DfxMemoryTest, DfxMemoryTest010, TestSize.Level2)
336 {
337     GTEST_LOG_(INFO) << "DfxMemoryTest010: start.";
338     static pid_t pid = getpid();
339     uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
340     pid_t child = fork();
341     if (child == 0) {
342         GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
343         DfxPtrace::Attach(pid);
344 
345         UnwindContext ctx;
346         ctx.pid = pid;
347         auto acc = std::make_shared<DfxAccessorsRemote>();
348         auto memory = std::make_shared<DfxMemory>(acc);
349         memory->SetCtx(&ctx);
350         uintptr_t addr = (uintptr_t)(&values[0]);
351         uint8_t tmp8;
352         ASSERT_TRUE(memory->ReadU8(addr, &tmp8, false));
353         ASSERT_EQ(tmp8, 0x01);
354         uint16_t tmp16;
355         ASSERT_TRUE(memory->ReadU16(addr, &tmp16, false));
356         ASSERT_EQ(tmp16, 0x0201);
357         uint32_t tmp32;
358         ASSERT_TRUE(memory->ReadU32(addr, &tmp32, false));
359         ASSERT_EQ(tmp32, 0x04030201);
360         uint64_t tmp64;
361         ASSERT_TRUE(memory->ReadU64(addr, &tmp64, false));
362         ASSERT_EQ(tmp64, 0x0807060504030201);
363         DfxPtrace::Detach(pid);
364         _exit(0);
365     }
366     int status;
367     int ret = wait(&status);
368     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
369     GTEST_LOG_(INFO) << "DfxMemoryTest010: end.";
370 }
371 
372 /**
373  * @tc.name: DfxMemoryTest011
374  * @tc.desc: test DfxMemory class Read in remote case
375  * @tc.type: FUNC
376  */
377 HWTEST_F(DfxMemoryTest, DfxMemoryTest011, TestSize.Level2)
378 {
379     GTEST_LOG_(INFO) << "DfxMemoryTest011: start.";
380     static pid_t pid = getpid();
381     uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
382     char testStr[] = "Test ReadString Func";
383     pid_t child = fork();
384     if (child == 0) {
385         GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
386         DfxPtrace::Attach(getppid());
387         UnwindContext ctx;
388         ctx.pid = getppid();
389         auto acc = std::make_shared<DfxAccessorsRemote>();
390         auto memory = std::make_shared<DfxMemory>(acc);
391         memory->SetCtx(&ctx);
392         uintptr_t addr = (uintptr_t)(&values[0]);
393         std::string resultStr;
394         uintptr_t addrStr = (uintptr_t)(&testStr[0]);
395         ASSERT_TRUE(memory->ReadString(addrStr, &resultStr, sizeof(testStr)/sizeof(char), false));
396         ASSERT_EQ(testStr, resultStr);
397         ASSERT_TRUE(memory->ReadString(addrStr, &resultStr, sizeof(testStr)/sizeof(char), true));
398         ASSERT_EQ(testStr, resultStr);
399         ASSERT_EQ(memory->ReadUleb128(addr), 1U);
400         ASSERT_EQ(memory->ReadSleb128(addr), 2);
401         DfxPtrace::Detach(pid);
402         _exit(0);
403     }
404     int status;
405     int ret = wait(&status);
406     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
407     GTEST_LOG_(INFO) << "DfxMemoryTest011: end.";
408 }
409 
410 /**
411  * @tc.name: DfxMemoryTest012
412  * @tc.desc: test DfxMemory class Read in remote case
413  * @tc.type: FUNC
414  */
415 HWTEST_F(DfxMemoryTest, DfxMemoryTest012, TestSize.Level2)
416 {
417     GTEST_LOG_(INFO) << "DfxMemoryTest012: start.";
418     static pid_t pid = getpid();
419     pid_t child = fork();
420     if (child == 0) {
421         GTEST_LOG_(INFO) << "pid: " << pid << ", ppid:" << getppid();
422         DfxPtrace::Attach(pid);
423         UnwindContext ctx;
424         ctx.pid = pid;
425         auto acc = std::make_shared<DfxAccessorsRemote>();
426         auto memory = std::make_shared<DfxMemory>(acc);
427         memory->SetCtx(&ctx);
428         ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_absptr), sizeof(uintptr_t));
429         ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata1), 1);
430         ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata2), 2);
431         ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata4), 4);
432         ASSERT_EQ(memory->GetEncodedSize(DW_EH_PE_sdata8), 8);
433         DfxPtrace::Detach(pid);
434         _exit(0);
435     }
436     int status;
437     int ret = wait(&status);
438     GTEST_LOG_(INFO) << "Status:" << status << " Result:" << ret;
439     GTEST_LOG_(INFO) << "DfxMemoryTest012: end.";
440 }
441 
442 /**
443  * @tc.name: DfxMemoryTest013
444  * @tc.desc: test DfxMemory class Read in error case
445  * @tc.type: FUNC
446  */
447 HWTEST_F(DfxMemoryTest, DfxMemoryTest013, TestSize.Level2)
448 {
449     GTEST_LOG_(INFO) << "DfxMemoryTest013: start.";
450     auto acc = std::make_shared<DfxAccessorsLocal>();
451     auto memory = std::make_shared<DfxMemory>(acc);
452     uintptr_t val;
453     EXPECT_FALSE(memory->ReadReg(0, &val));
454     uintptr_t regs[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa};
455     UnwindContext ctx;
456     ctx.regs = DfxRegs::CreateFromRegs(UnwindMode::DWARF_UNWIND, regs);
457     memory->SetCtx(&ctx);
458     EXPECT_FALSE(memory->ReadReg(-1, &val));
459 
460     uint8_t values[] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};
461     uintptr_t addr = (uintptr_t)(&values[0]);
462     EXPECT_FALSE(memory->ReadMem(addr, nullptr));
463     EXPECT_FALSE(memory->ReadUptr(addr, nullptr, false));
464     EXPECT_FALSE(memory->Read(addr, nullptr, sizeof(uint8_t), false));
465     EXPECT_FALSE(memory->ReadU8(addr, nullptr, false));
466     EXPECT_FALSE(memory->ReadU16(addr, nullptr, false));
467     EXPECT_FALSE(memory->ReadU32(addr, nullptr, false));
468     EXPECT_FALSE(memory->ReadU64(addr, nullptr, false));
469     GTEST_LOG_(INFO) << "DfxMemoryTest013: end.";
470 }
471 
472 }
473 } // namespace HiviewDFX
474 } // namespace OHOS
475