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