1 /*
2 * Copyright (c) 2024 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 <cstddef>
17 #include <cstdint>
18 #include <cstdio>
19 #include <sys/mman.h>
20 #include <unistd.h>
21 #include <thread>
22 #include <iostream>
23 #include <map>
24 #include <vector>
25 #include <string>
26 #include "hidebug/hidebug.h"
27 #include "hidebug/hidebug_type.h"
28 #include "securec.h"
29 #pragma clang optimize off
30
31 bool g_isInit = false;
MyMalloc(size_t size)32 static void* MyMalloc(size_t size)
33 {
34 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
35 printf("test my_malloc---\n");
36 return original->malloc(size);
37 }
38
MyFree(void * ptr)39 static void MyFree(void* ptr)
40 {
41 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
42 printf("test my_free----\n");
43 original->free(ptr);
44 }
45
MyMmap(void * addr,size_t len,int prot,int flags,int fd,off_t offset)46 static void* MyMmap(void* addr, size_t len, int prot, int flags, int fd, off_t offset)
47 {
48 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
49 printf("test my_mmap----\n");
50 return original->mmap(addr, len, prot, flags, fd, offset);
51 }
52
MyMunmap(void * addr,size_t len)53 static int MyMunmap(void* addr, size_t len)
54 {
55 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
56 printf("test my_munmap----\n");
57 return original->munmap(addr, len);
58 }
59
MyCalloc(size_t nmemb,size_t size)60 static void* MyCalloc(size_t nmemb, size_t size)
61 {
62 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
63 printf("test my_calloc----\n");
64 return original->calloc(nmemb, size);
65 }
66
MyRealloc(void * ptr,size_t size)67 static void* MyRealloc(void* ptr, size_t size)
68 {
69 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
70 printf("test my_realloc----\n");
71 return original->realloc(ptr, size);
72 }
73
InitCustomMalloc()74 HiDebug_MallocDispatch* InitCustomMalloc()
75 {
76 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
77 HiDebug_MallocDispatch* current = (HiDebug_MallocDispatch*)original->malloc(sizeof(HiDebug_MallocDispatch));
78 memset_s(current, sizeof(HiDebug_MallocDispatch), 0, sizeof(HiDebug_MallocDispatch));
79 current->malloc = MyMalloc;
80 current->free = MyFree;
81 current->mmap = MyMmap;
82 current->munmap = MyMunmap;
83 current->calloc = MyCalloc;
84 current->realloc = MyRealloc;
85 OH_HiDebug_SetMallocDispatchTable(current);
86 return current;
87 }
88
DesCustomMalloc(HiDebug_MallocDispatch * current)89 void DesCustomMalloc(HiDebug_MallocDispatch* current)
90 {
91 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
92 original->free(current);
93 OH_HiDebug_RestoreMallocDispatchTable();
94 }
95
TestMalloc()96 void TestMalloc()
97 {
98 int* temp = (int*)malloc(sizeof(int));
99 if (temp == nullptr) {
100 printf("malloc failed\n");
101 return;
102 }
103 *temp = 8;
104 int* temp2 = (int*)malloc(sizeof(int));
105 if (temp2 == nullptr) {
106 printf("malloc failed\n");
107 return;
108 }
109 *temp2 = 10;
110 int ret = *temp2 + *temp;
111 printf("ret = %d\n", ret);
112 free(temp);
113 free(temp2);
114 }
TestMmap()115 void TestMmap()
116 {
117 char* mapPtr = nullptr;
118 const size_t bufferSize = 100; // 100 : the size of memory
119 mapPtr = (char*)mmap(nullptr, bufferSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
120 if (mapPtr == MAP_FAILED) {
121 printf("mmap failed\n");
122 return;
123 }
124 int len = snprintf_s(mapPtr, bufferSize, bufferSize - 1, "%s", "hi, this is test mmap");
125 if (len < 0) {
126 printf("snprintf_s failed\n");
127 }
128 printf("mapPtr = %s\n", mapPtr);
129 munmap(mapPtr, bufferSize);
130 }
131
TestCalloc()132 void TestCalloc()
133 {
134 int* ptr = (int*)calloc(5, sizeof(int)); // 5 : the length of array
135 if (ptr == nullptr) {
136 printf("calloc failed\n");
137 return;
138 }
139 for (size_t i = 0; i < 5; ++i) { // 5 : the length of array
140 ptr[i] = i * i;
141 printf("ptr[%zu] = %d\n", i, ptr[i]);
142 }
143 free(ptr);
144 }
145
TestRealloc()146 void TestRealloc()
147 {
148 int* ptr = (int*)malloc(5 * sizeof(int)); // 5 : the length of array
149 if (ptr == nullptr) {
150 printf("malloc failed\n");
151 return;
152 }
153 for (size_t i = 0; i < 5; ++i) { // 5 : the length of array
154 ptr[i] = i * i;
155 printf("ptr[%zu] = %d\n", i, ptr[i]);
156 }
157 int* newPtr = (int*)realloc(ptr, 10 * sizeof(int)); // 10 : the length of array
158 if (newPtr == nullptr) {
159 printf("realloc failed\n");
160 free(ptr);
161 return;
162 }
163 for (size_t i = 0; i < 10; ++i) { // 10 : the length of array
164 newPtr[i] = i * i;
165 printf("newPtr[%zu] = %d\n", i, newPtr[i]);
166 }
167 free(newPtr);
168 }
169
TestMutilThread(int num)170 void TestMutilThread(int num)
171 {
172 std::cout << "TestMutilThread num = " << num << ", thread_id is " << std::this_thread::get_id() << std::endl;
173 TestMalloc();
174 TestMmap();
175 TestCalloc();
176 TestRealloc();
177 }
178
179 class TestCustomClass {
180 private:
181 int temp_;
182
183 public:
TestCustomClass()184 TestCustomClass()
185 {
186 temp_ = 10;
187 printf("TestCustomClass constructor\n");
188 }
~TestCustomClass()189 ~TestCustomClass()
190 {
191 printf("TestCustomClass destructor\n");
192 }
193 };
194
TestNewFunc()195 void TestNewFunc()
196 {
197 int* ptr = new int(10);
198 if (ptr == nullptr) {
199 printf("new failed\n");
200 return;
201 }
202 printf("ptr = %d\n", *ptr);
203 delete ptr;
204 ptr = nullptr;
205 int* ptr2 = new int[10]; // 10 : the length of array
206 if (ptr2 == nullptr) {
207 printf("new failed\n");
208 return;
209 }
210 for (size_t i = 0; i < 10; ++i) { // 10 : the length of array
211 ptr2[i] = i * i;
212 }
213 for (size_t i = 0; i < 10; ++i) { // 10 : the length of array
214 printf("ptr2[%zu] = %d\n", i, ptr2[i]);
215 }
216 delete[] ptr2;
217 ptr2 = nullptr;
218 std::string* str = new std::string("hello, world");
219 if (str == nullptr) {
220 printf("new failed\n");
221 return;
222 }
223 printf("str = %s\n", str->c_str());
224 delete str;
225 str = nullptr;
226 TestCustomClass* test = new TestCustomClass();
227 if (test == nullptr) {
228 printf("new failed\n");
229 return;
230 }
231 delete test;
232 test = nullptr;
233 std::vector<int>* vec = new std::vector<int>(10); // 10 : the length of vector
234 if (vec == nullptr) {
235 printf("new failed\n");
236 return;
237 }
238 for (size_t i = 0; i < vec->size(); ++i) {
239 (*vec)[i] = i * i;
240 }
241 for (size_t i = 0; i < vec->size(); ++i) {
242 printf("vec[%zu] = %d\n", i, (*vec)[i]);
243 }
244 delete vec;
245 vec = nullptr;
246 std::map<int, int>* map = new std::map<int, int>();
247 if (map == nullptr) {
248 printf("new failed\n");
249 return;
250 }
251 for (size_t i = 0; i < 10; ++i) { // 10 : test 10 times
252 (*map)[i] = i * i;
253 }
254 for (size_t i = 0; i < 10; ++i) { // 10 : test 10 times
255 printf("map[%zu] = %d\n", i, (*map)[i]);
256 }
257 delete map;
258 map = nullptr;
259 }
260
MyNestedMalloc(size_t size)261 static void* MyNestedMalloc(size_t size)
262 {
263 if (g_isInit) {
264 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
265 return original->malloc(size);
266 }
267 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
268 printf("test MyNestedMalloc----\n");
269 g_isInit = true;
270 TestMalloc();
271 g_isInit = false;
272 return original->malloc(size);
273 }
274
InitNestedCustomMalloc()275 HiDebug_MallocDispatch* InitNestedCustomMalloc()
276 {
277 HiDebug_MallocDispatch* original = (HiDebug_MallocDispatch*)OH_HiDebug_GetDefaultMallocDispatchTable();
278 HiDebug_MallocDispatch* current = (HiDebug_MallocDispatch*)original->malloc(sizeof(HiDebug_MallocDispatch));
279 memset_s(current, sizeof(HiDebug_MallocDispatch), 0, sizeof(HiDebug_MallocDispatch));
280 current->malloc = MyNestedMalloc;
281 OH_HiDebug_SetMallocDispatchTable(current);
282 return current;
283 }
284
main(int argc,char * argv[])285 int main(int argc, char* argv[])
286 {
287 HiDebug_MallocDispatch* current = InitCustomMalloc();
288 // test malloc
289 TestMalloc();
290 TestMmap();
291 TestCalloc();
292 TestRealloc();
293 // test muti-threads
294 std::vector<std::thread> vecThreads;
295 for (size_t i = 0; i < 10; i++) { // 10 : test 10 threads
296 vecThreads.push_back(std::thread(TestMutilThread, i));
297 }
298 for (auto& thread : vecThreads) {
299 thread.join();
300 }
301 // test new operation
302 TestNewFunc();
303 DesCustomMalloc(current);
304
305 // nested call
306 HiDebug_MallocDispatch* nestedCurrent = InitNestedCustomMalloc();
307 int *nestedPtr = (int*)malloc(sizeof(int));
308 if (nestedPtr == nullptr) {
309 printf("malloc failed\n");
310 return 0;
311 }
312 *nestedPtr = 8;
313 free(nestedPtr);
314 nestedPtr = nullptr;
315 DesCustomMalloc(nestedCurrent);
316 return 0;
317 }
318 #pragma clang optimize on