• 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 
16 #include <gtest/gtest.h>
17 
18 #include <algorithm>
19 #include <dlfcn.h>
20 #include <fcntl.h>
21 #include <link.h>
22 
23 #include <sys/stat.h>
24 #include <sys/syscall.h>
25 #include <sys/types.h>
26 
27 #include "dfx_define.h"
28 #include "dfx_maps.h"
29 #include "safe_reader.h"
30 #include "smart_fd.h"
31 
32 using namespace testing::ext;
33 
34 namespace OHOS {
35 namespace HiviewDFX {
36 
37 /**
38  * @tc.name: SafeReaderTest001
39  * @tc.desc: test CopyReadbaleBufSafe read stack
40  * @tc.type: FUNC
41  */
42 HWTEST(SafeReaderTest, SafeReaderTest001, TestSize.Level2)
43 {
44     /**
45      * @tc.steps: step1. read maps.
46      * @tc.expected: read success
47      */
48     auto maps = DfxMaps::Create(getpid(), false);
49     uintptr_t bottom;
50     uintptr_t top;
51     ASSERT_TRUE(maps->GetStackRange(bottom, top));
52 
53     std::vector<uint8_t> stackBuf;
54     constexpr int stackBufferSize = 64 * 1024;
55     SafeReader reader;
56     stackBuf.resize(stackBufferSize);
57 
58     /**
59      * @tc.steps: step2. read stack form bottom.
60      * @tc.expected: read success
61      */
62     uintptr_t stackSize = top - bottom;
63     auto ret = reader.CopyReadbaleBufSafe(reinterpret_cast<uintptr_t>(stackBuf.data()), stackBuf.size(),
64                                            bottom, stackSize);
65     ASSERT_EQ(ret, std::min(stackSize, stackBuf.size()));
66 
67     /**
68      * @tc.steps: step3. read stack form top - 2048.
69      * @tc.expected: read success
70      */
71     constexpr uintptr_t offset = 2048;
72     ret = reader.CopyReadbaleBufSafe(reinterpret_cast<uintptr_t>(stackBuf.data()), stackBuf.size(),
73                                       top - offset, top - bottom);
74     ASSERT_EQ(ret, offset);
75 
76     ret = reader.CopyReadbaleBufSafe(reinterpret_cast<uintptr_t>(stackBuf.data()), stackBuf.size(),
77                                       top - offset, offset);
78     ASSERT_EQ(ret, offset);
79 
80     /**
81      * @tc.steps: step4. read stack form top + 2048.
82      * @tc.expected: read failed
83      */
84     ret = reader.CopyReadbaleBufSafe(reinterpret_cast<uintptr_t>(stackBuf.data()), stackBuf.size(),
85                                       top + offset, offset);
86     ASSERT_EQ(ret, 0);
87 }
88 
89 /**
90  * @tc.name: SafeReaderTest002
91  * @tc.desc: test DfxParam class functions
92  * @tc.type: FUNC
93  */
94 HWTEST(SafeReaderTest, SafeReaderTest002, TestSize.Level2)
95 {
96     /**
97      * @tc.steps: step1. read data from /dev/random.
98      * @tc.expected: read success
99      */
100     SmartFd fd(open("/dev/random", O_RDONLY));
101     std::vector<uint8_t> srcBuf;
102     std::vector<uint8_t> destBuf;
103     constexpr uintptr_t socLen = 1024 * 6;
104     constexpr uintptr_t destBuf1 = 1024 * 8;
105     constexpr uintptr_t destBuf2 = 1024 * 3;
106     srcBuf.resize(socLen, 1);
107     destBuf.resize(destBuf1, 0);
108     ssize_t ret = read(fd.GetFd(), srcBuf.data(), srcBuf.size());
109     ASSERT_EQ(ret, srcBuf.size());
110 
111     /**
112      * @tc.steps: step2. test CopyReadbaleBufSafe.
113      * @tc.expected: copy success
114      */
115     SafeReader reader;
116     ret = reader.CopyReadbaleBufSafe(reinterpret_cast<uintptr_t>(destBuf.data()), destBuf.size(),
117                                            reinterpret_cast<uintptr_t>(srcBuf.data()), srcBuf.size());
118     ASSERT_EQ(ret, std::min(destBuf.size(), srcBuf.size()));
119 
120     /**
121      * @tc.steps: step3. compare data.
122      * @tc.expected: data consistency
123      */
124     size_t compareLen = std::min(destBuf.size(), srcBuf.size());
125     ASSERT_TRUE(std::equal(destBuf.begin(), destBuf.begin() + compareLen, srcBuf.begin()));
126 
127     /**
128      * @tc.steps: step4. clear destBuf.
129      */
130     destBuf.clear();
131     destBuf.resize(destBuf2, 0);
132 
133     /**
134      * @tc.steps: step5. test CopyReadbaleBufSafe.
135      * @tc.expected: copy success
136      */
137     ret = reader.CopyReadbaleBufSafe(reinterpret_cast<uintptr_t>(destBuf.data()), destBuf.size(),
138                                       reinterpret_cast<uintptr_t>(srcBuf.data()), srcBuf.size());
139     ASSERT_EQ(ret, std::min(destBuf.size(), srcBuf.size()));
140 
141     /**
142      * @tc.steps: step6. compare data.
143      * @tc.expected: data consistency
144      */
145     compareLen = std::min(destBuf.size(), srcBuf.size());
146     ASSERT_TRUE(std::equal(destBuf.begin(), destBuf.begin() + compareLen, srcBuf.begin()));
147 }
148 
149 /**
150  * @tc.name: SafeReaderTest003
151  * @tc.desc: test fd = -1
152  * @tc.type: FUNC
153  */
154 HWTEST(SafeReaderTest, SafeReaderTest003, TestSize.Level2)
155 {
156     /**
157      * @tc.steps: step1. close fd
158      */
159 
160     SafeReader reader;
161     if (reader.pfd_[PIPE_READ] > 0) {
162         syscall(SYS_close, reader.pfd_[PIPE_READ]);
163         reader.pfd_[PIPE_READ] = -1;
164     }
165     if (reader.pfd_[PIPE_WRITE] > 0) {
166         syscall(SYS_close, reader.pfd_[PIPE_WRITE]);
167         reader.pfd_[PIPE_WRITE] = -1;
168     }
169 
170     /**
171      * @tc.steps: step2. compare data.
172      * @tc.expected: data consistency
173      */
174     ASSERT_FALSE(reader.IsReadbaleAddr(0));
175 }
176 
177 /**
178  * @tc.name: SafeReaderTest004
179  * @tc.desc: test GetCurrentPageEndAddr
180  * @tc.type: FUNC
181  */
182 HWTEST(SafeReaderTest, SafeReaderTest004, TestSize.Level2)
183 {
184     int pageSize = getpagesize();
185 
186     /**
187      * @tc.steps: step1. 0 ~ (pageSize - 1) >>> pageSize
188      */
189     ASSERT_EQ(SafeReader::GetCurrentPageEndAddr(0), pageSize);
190     ASSERT_EQ(SafeReader::GetCurrentPageEndAddr(1), pageSize);
191     ASSERT_EQ(SafeReader::GetCurrentPageEndAddr(pageSize - 1), pageSize);
192 
193     /**
194      * @tc.steps: step1. pageSize ~ (2*pageSize - 1) >>> 2*pageSize
195      */
196     ASSERT_EQ(SafeReader::GetCurrentPageEndAddr(pageSize), pageSize * 2);
197     ASSERT_EQ(SafeReader::GetCurrentPageEndAddr(pageSize + 1), pageSize * 2);
198     ASSERT_EQ(SafeReader::GetCurrentPageEndAddr(2 * pageSize - 1), pageSize * 2);
199 }
200 } // namespace HiviewDFX
201 } // namespace OHOS
202