106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci#include <chrono> 1606f6ba60Sopenharmony_ci#include <cstdio> 1706f6ba60Sopenharmony_ci#include <cstdlib> 1806f6ba60Sopenharmony_ci#include <string> 1906f6ba60Sopenharmony_ci#include <vector> 2006f6ba60Sopenharmony_ci#include <dlfcn.h> 2106f6ba60Sopenharmony_ci#include <fcntl.h> 2206f6ba60Sopenharmony_ci#include <memory.h> 2306f6ba60Sopenharmony_ci#include <pthread.h> 2406f6ba60Sopenharmony_ci#include <unistd.h> 2506f6ba60Sopenharmony_ci#include <sys/mman.h> 2606f6ba60Sopenharmony_ci#include <sys/prctl.h> 2706f6ba60Sopenharmony_ci#include <sys/stat.h> 2806f6ba60Sopenharmony_ci#include <sys/syscall.h> 2906f6ba60Sopenharmony_ci#include <sys/types.h> 3006f6ba60Sopenharmony_ci 3106f6ba60Sopenharmony_ci#include "memory_trace.h" 3206f6ba60Sopenharmony_ci#include "securec.h" 3306f6ba60Sopenharmony_ci 3406f6ba60Sopenharmony_ci#pragma clang optimize off 3506f6ba60Sopenharmony_ci 3606f6ba60Sopenharmony_cinamespace { 3706f6ba60Sopenharmony_citypedef char* (*DepthMallocSo)(int depth, int mallocSize); 3806f6ba60Sopenharmony_citypedef void (*DepthFreeSo)(int depth, char *p); 3906f6ba60Sopenharmony_ciconstexpr int MALLOC_SIZE = 1000; 4006f6ba60Sopenharmony_ciconstexpr int ARGC_NUM_MAX = 3; 4106f6ba60Sopenharmony_ciconstexpr int DOUBLE = 2; 4206f6ba60Sopenharmony_ci 4306f6ba60Sopenharmony_ciconstexpr int USLEEP_TIME = 1000; 4406f6ba60Sopenharmony_ci// liba.z.so and libb.z.so for same so. 4506f6ba60Sopenharmony_ci#ifdef __arm__ 4606f6ba60Sopenharmony_ciconst std::vector<std::string> VEC_SO_PATH { "/system/lib/liba.z.so", "/system/lib/libb.z.so" }; 4706f6ba60Sopenharmony_ci#else 4806f6ba60Sopenharmony_ciconst std::vector<std::string> VEC_SO_PATH { "/system/lib64/liba.z.so", "/system/lib64/libb.z.so" }; 4906f6ba60Sopenharmony_ci#endif 5006f6ba60Sopenharmony_ciunsigned int g_stickDepth = 1; 5106f6ba60Sopenharmony_ci} 5206f6ba60Sopenharmony_ci 5306f6ba60Sopenharmony_cistatic void CallocFun() 5406f6ba60Sopenharmony_ci{ 5506f6ba60Sopenharmony_ci static int i = 0; 5606f6ba60Sopenharmony_ci char* ptr = static_cast<char*>(calloc(1, MALLOC_SIZE / 100)); 5706f6ba60Sopenharmony_ci if (ptr == nullptr) { 5806f6ba60Sopenharmony_ci fprintf(stderr, "calloc err.\n"); 5906f6ba60Sopenharmony_ci return; 6006f6ba60Sopenharmony_ci } 6106f6ba60Sopenharmony_ci fprintf(stderr, "calloc i=%d\n", i); 6206f6ba60Sopenharmony_ci free(ptr); 6306f6ba60Sopenharmony_ci i++; 6406f6ba60Sopenharmony_ci} 6506f6ba60Sopenharmony_ci 6606f6ba60Sopenharmony_cistatic void ReallocFun() 6706f6ba60Sopenharmony_ci{ 6806f6ba60Sopenharmony_ci static int i = 0; 6906f6ba60Sopenharmony_ci char* ptr = static_cast<char*>(calloc(1, MALLOC_SIZE / 10)); // 10: multiple num 7006f6ba60Sopenharmony_ci if (ptr == nullptr) { 7106f6ba60Sopenharmony_ci fprintf(stderr, "calloc err.\n"); 7206f6ba60Sopenharmony_ci return; 7306f6ba60Sopenharmony_ci } 7406f6ba60Sopenharmony_ci ptr = static_cast<char*>(realloc(ptr, MALLOC_SIZE * 10)); // 10: multiple num 7506f6ba60Sopenharmony_ci if (ptr == nullptr) { 7606f6ba60Sopenharmony_ci fprintf(stderr, "realloc err.\n"); 7706f6ba60Sopenharmony_ci return; 7806f6ba60Sopenharmony_ci } 7906f6ba60Sopenharmony_ci fprintf(stderr, "realloc i=%d\n", i); 8006f6ba60Sopenharmony_ci free(ptr); 8106f6ba60Sopenharmony_ci i++; 8206f6ba60Sopenharmony_ci} 8306f6ba60Sopenharmony_ci 8406f6ba60Sopenharmony_cistatic bool DepthMallocFree(int depth = 0, int mallocSize = 100) 8506f6ba60Sopenharmony_ci{ 8606f6ba60Sopenharmony_ci if (depth < 0 || mallocSize <= 0) { 8706f6ba60Sopenharmony_ci return false; 8806f6ba60Sopenharmony_ci } 8906f6ba60Sopenharmony_ci if (depth == 0) { 9006f6ba60Sopenharmony_ci char* ptr = static_cast<char*>(malloc(mallocSize)); 9106f6ba60Sopenharmony_ci if (ptr == nullptr) { 9206f6ba60Sopenharmony_ci fprintf(stderr, "malloc err.\n"); 9306f6ba60Sopenharmony_ci return false; 9406f6ba60Sopenharmony_ci } 9506f6ba60Sopenharmony_ci fprintf(stderr, "%s\n", __func__); 9606f6ba60Sopenharmony_ci *ptr = 'a'; 9706f6ba60Sopenharmony_ci free(ptr); 9806f6ba60Sopenharmony_ci return true; 9906f6ba60Sopenharmony_ci } 10006f6ba60Sopenharmony_ci return (DepthMallocFree(depth - 1, mallocSize)); 10106f6ba60Sopenharmony_ci} 10206f6ba60Sopenharmony_ci 10306f6ba60Sopenharmony_cistatic void DlopenAndCloseSo(const std::string& filePath, int size) 10406f6ba60Sopenharmony_ci{ 10506f6ba60Sopenharmony_ci void* handle = nullptr; 10606f6ba60Sopenharmony_ci DepthMallocSo mallocFunc = nullptr; 10706f6ba60Sopenharmony_ci DepthFreeSo freeFunc = nullptr; 10806f6ba60Sopenharmony_ci 10906f6ba60Sopenharmony_ci fprintf(stderr, "dlopen %s %d!!!\n", filePath.data(), size); 11006f6ba60Sopenharmony_ci usleep(USLEEP_TIME * 300); // 300 ms 11106f6ba60Sopenharmony_ci handle = dlopen(filePath.data(), RTLD_LAZY); 11206f6ba60Sopenharmony_ci if (handle == nullptr) { 11306f6ba60Sopenharmony_ci fprintf(stderr, "library not exist!\n"); 11406f6ba60Sopenharmony_ci exit(0); 11506f6ba60Sopenharmony_ci } 11606f6ba60Sopenharmony_ci mallocFunc = (DepthMallocSo)dlsym(handle, "DepthMallocSo"); 11706f6ba60Sopenharmony_ci freeFunc = (DepthFreeSo)dlsym(handle, "DepthFreeSo"); 11806f6ba60Sopenharmony_ci if (mallocFunc == nullptr || freeFunc == nullptr) { 11906f6ba60Sopenharmony_ci fprintf(stderr, "function not exist!\n"); 12006f6ba60Sopenharmony_ci exit(0); 12106f6ba60Sopenharmony_ci } 12206f6ba60Sopenharmony_ci char* ptr = nullptr; 12306f6ba60Sopenharmony_ci for (size_t i = 0; i < 20; i++) { // 20: loop count 12406f6ba60Sopenharmony_ci ptr = mallocFunc(g_stickDepth, size); 12506f6ba60Sopenharmony_ci *ptr = 'a'; 12606f6ba60Sopenharmony_ci freeFunc(g_stickDepth, ptr); 12706f6ba60Sopenharmony_ci } 12806f6ba60Sopenharmony_ci if (handle != nullptr) { 12906f6ba60Sopenharmony_ci usleep(USLEEP_TIME * 300); // 300 ms 13006f6ba60Sopenharmony_ci dlclose(handle); 13106f6ba60Sopenharmony_ci } 13206f6ba60Sopenharmony_ci} 13306f6ba60Sopenharmony_ci 13406f6ba60Sopenharmony_cistatic int MmapAndMunMap() 13506f6ba60Sopenharmony_ci{ 13606f6ba60Sopenharmony_ci size_t size = (1024); 13706f6ba60Sopenharmony_ci 13806f6ba60Sopenharmony_ci char* ptr = static_cast<char*>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); 13906f6ba60Sopenharmony_ci if (ptr == MAP_FAILED) { 14006f6ba60Sopenharmony_ci fprintf(stderr, "Mmap err.\n"); 14106f6ba60Sopenharmony_ci ptr = nullptr; 14206f6ba60Sopenharmony_ci return 1; 14306f6ba60Sopenharmony_ci } 14406f6ba60Sopenharmony_ci 14506f6ba60Sopenharmony_ci (void)memset_s(ptr, size, 0, size); 14606f6ba60Sopenharmony_ci munmap(ptr, size); 14706f6ba60Sopenharmony_ci return 0; 14806f6ba60Sopenharmony_ci} 14906f6ba60Sopenharmony_ci 15006f6ba60Sopenharmony_cistatic void Fun1() 15106f6ba60Sopenharmony_ci{ 15206f6ba60Sopenharmony_ci static int i = 0; 15306f6ba60Sopenharmony_ci char* ptr = static_cast<char*>(malloc(MALLOC_SIZE)); 15406f6ba60Sopenharmony_ci if (ptr == nullptr) { 15506f6ba60Sopenharmony_ci fprintf(stderr, "malloc err.\n"); 15606f6ba60Sopenharmony_ci return; 15706f6ba60Sopenharmony_ci } 15806f6ba60Sopenharmony_ci fprintf(stderr, "i=%d\n", i); 15906f6ba60Sopenharmony_ci *ptr = 'a'; 16006f6ba60Sopenharmony_ci free(ptr); 16106f6ba60Sopenharmony_ci i++; 16206f6ba60Sopenharmony_ci MmapAndMunMap(); 16306f6ba60Sopenharmony_ci CallocFun(); 16406f6ba60Sopenharmony_ci ReallocFun(); 16506f6ba60Sopenharmony_ci} 16606f6ba60Sopenharmony_ci 16706f6ba60Sopenharmony_cistatic void Fun2() 16806f6ba60Sopenharmony_ci{ 16906f6ba60Sopenharmony_ci Fun1(); 17006f6ba60Sopenharmony_ci static int i = 0; 17106f6ba60Sopenharmony_ci char *ptr = static_cast<char*>(malloc(MALLOC_SIZE)); 17206f6ba60Sopenharmony_ci if (ptr == nullptr) { 17306f6ba60Sopenharmony_ci fprintf(stderr, "malloc err.\n"); 17406f6ba60Sopenharmony_ci return; 17506f6ba60Sopenharmony_ci } 17606f6ba60Sopenharmony_ci fprintf(stderr, "i=%d\n", i); 17706f6ba60Sopenharmony_ci *ptr = 'a'; 17806f6ba60Sopenharmony_ci if (i % DOUBLE == 0) { 17906f6ba60Sopenharmony_ci free(ptr); 18006f6ba60Sopenharmony_ci } 18106f6ba60Sopenharmony_ci i++; 18206f6ba60Sopenharmony_ci} 18306f6ba60Sopenharmony_ci 18406f6ba60Sopenharmony_cistatic void Fun3() 18506f6ba60Sopenharmony_ci{ 18606f6ba60Sopenharmony_ci Fun2(); 18706f6ba60Sopenharmony_ci static int i = 0; 18806f6ba60Sopenharmony_ci char *ptr = static_cast<char*>(malloc(MALLOC_SIZE)); 18906f6ba60Sopenharmony_ci if (ptr == nullptr) { 19006f6ba60Sopenharmony_ci fprintf(stderr, "malloc err.\n"); 19106f6ba60Sopenharmony_ci return; 19206f6ba60Sopenharmony_ci } 19306f6ba60Sopenharmony_ci fprintf(stderr, "i=%d\n", i); 19406f6ba60Sopenharmony_ci *ptr = 'a'; 19506f6ba60Sopenharmony_ci if (i % DOUBLE == 0) { 19606f6ba60Sopenharmony_ci free(ptr); 19706f6ba60Sopenharmony_ci } 19806f6ba60Sopenharmony_ci i++; 19906f6ba60Sopenharmony_ci DlopenAndCloseSo(VEC_SO_PATH[0], MALLOC_SIZE * DOUBLE); 20006f6ba60Sopenharmony_ci} 20106f6ba60Sopenharmony_ci 20206f6ba60Sopenharmony_cistatic void Fun4() 20306f6ba60Sopenharmony_ci{ 20406f6ba60Sopenharmony_ci Fun3(); 20506f6ba60Sopenharmony_ci static int i = 0; 20606f6ba60Sopenharmony_ci char *ptr = static_cast<char*>(malloc(MALLOC_SIZE)); 20706f6ba60Sopenharmony_ci if (ptr == nullptr) { 20806f6ba60Sopenharmony_ci fprintf(stderr, "malloc err.\n"); 20906f6ba60Sopenharmony_ci return; 21006f6ba60Sopenharmony_ci } 21106f6ba60Sopenharmony_ci fprintf(stderr, "i=%d\n", i); 21206f6ba60Sopenharmony_ci *ptr = 'a'; 21306f6ba60Sopenharmony_ci if (i % DOUBLE == 0) { 21406f6ba60Sopenharmony_ci free(ptr); 21506f6ba60Sopenharmony_ci } 21606f6ba60Sopenharmony_ci i++; 21706f6ba60Sopenharmony_ci} 21806f6ba60Sopenharmony_ci 21906f6ba60Sopenharmony_cistatic void Fun5() 22006f6ba60Sopenharmony_ci{ 22106f6ba60Sopenharmony_ci Fun4(); 22206f6ba60Sopenharmony_ci static int i = 0; 22306f6ba60Sopenharmony_ci char *ptr = static_cast<char*>(malloc(MALLOC_SIZE)); 22406f6ba60Sopenharmony_ci if (ptr == nullptr) { 22506f6ba60Sopenharmony_ci fprintf(stderr, "malloc err.\n"); 22606f6ba60Sopenharmony_ci return; 22706f6ba60Sopenharmony_ci } 22806f6ba60Sopenharmony_ci fprintf(stderr, "i=%d\n", i); 22906f6ba60Sopenharmony_ci *ptr = 'a'; 23006f6ba60Sopenharmony_ci if (i % DOUBLE == 0) { 23106f6ba60Sopenharmony_ci free(ptr); 23206f6ba60Sopenharmony_ci } 23306f6ba60Sopenharmony_ci i++; 23406f6ba60Sopenharmony_ci DepthMallocFree(g_stickDepth * 30); // 30: depth count 23506f6ba60Sopenharmony_ci DlopenAndCloseSo(VEC_SO_PATH[1], MALLOC_SIZE * 3); // 3: multiple num 23606f6ba60Sopenharmony_ci} 23706f6ba60Sopenharmony_ci 23806f6ba60Sopenharmony_cistatic void* HhreadFuncCpp(void* param) 23906f6ba60Sopenharmony_ci{ 24006f6ba60Sopenharmony_ci std::string name = "thread"; 24106f6ba60Sopenharmony_ci name = name + std::to_string(gettid()); 24206f6ba60Sopenharmony_ci prctl(PR_SET_NAME, name.c_str()); 24306f6ba60Sopenharmony_ci int forNum = *static_cast<int*>(param); 24406f6ba60Sopenharmony_ci for (int num = 0; num < forNum; num++) { 24506f6ba60Sopenharmony_ci fprintf(stderr, "thread %d:num=%d\n", gettid(), num); 24606f6ba60Sopenharmony_ci Fun5(); 24706f6ba60Sopenharmony_ci } 24806f6ba60Sopenharmony_ci return nullptr; 24906f6ba60Sopenharmony_ci} 25006f6ba60Sopenharmony_ci 25106f6ba60Sopenharmony_cistatic void TestMemoryMap() 25206f6ba60Sopenharmony_ci{ 25306f6ba60Sopenharmony_ci constexpr int smallSize = 4096; 25406f6ba60Sopenharmony_ci constexpr int bigSize = 8192; 25506f6ba60Sopenharmony_ci int fd = open("/bin/hiebpf", O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH); 25606f6ba60Sopenharmony_ci if (fd < 0) { 25706f6ba60Sopenharmony_ci printf("open %s failed\n", "/bin/hiebpf"); 25806f6ba60Sopenharmony_ci return; 25906f6ba60Sopenharmony_ci } 26006f6ba60Sopenharmony_ci 26106f6ba60Sopenharmony_ci void* mapAddr1 = mmap(nullptr, smallSize, PROT_WRITE | PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0); 26206f6ba60Sopenharmony_ci if (mapAddr1 == MAP_FAILED) { 26306f6ba60Sopenharmony_ci printf("named mmap failed\n"); 26406f6ba60Sopenharmony_ci close(fd); 26506f6ba60Sopenharmony_ci return; 26606f6ba60Sopenharmony_ci } 26706f6ba60Sopenharmony_ci printf("named mmap size: 4096, fd: %d\n", fd); 26806f6ba60Sopenharmony_ci 26906f6ba60Sopenharmony_ci void* mapAddr2 = mmap(nullptr, bigSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 27006f6ba60Sopenharmony_ci if (mapAddr2 == MAP_FAILED) { 27106f6ba60Sopenharmony_ci printf("anonymous mmap failed\n"); 27206f6ba60Sopenharmony_ci close(fd); 27306f6ba60Sopenharmony_ci munmap(mapAddr1, smallSize); 27406f6ba60Sopenharmony_ci return; 27506f6ba60Sopenharmony_ci } 27606f6ba60Sopenharmony_ci printf("anonymous mmap size: 8192\n"); 27706f6ba60Sopenharmony_ci 27806f6ba60Sopenharmony_ci memtrace(reinterpret_cast<void*>(0x123456), 3333, "memtrace_test", true); // 3333 num 27906f6ba60Sopenharmony_ci printf("memtrace(0x123456, 3333, \"memtrace_test\", true)\n"); 28006f6ba60Sopenharmony_ci 28106f6ba60Sopenharmony_ci memtrace(reinterpret_cast<void*>(0x123456), 3333, "memtrace_test", false); // 3333 num 28206f6ba60Sopenharmony_ci printf("memtrace(0x123456, 3333, \"memtrace_test\", false)\n"); 28306f6ba60Sopenharmony_ci close(fd); 28406f6ba60Sopenharmony_ci munmap(mapAddr1, smallSize); 28506f6ba60Sopenharmony_ci munmap(mapAddr2, bigSize); 28606f6ba60Sopenharmony_ci} 28706f6ba60Sopenharmony_ci 28806f6ba60Sopenharmony_ciint main(int argc, char *argv[]) 28906f6ba60Sopenharmony_ci{ 29006f6ba60Sopenharmony_ci int threadNum = 1; 29106f6ba60Sopenharmony_ci int forNum = 10; 29206f6ba60Sopenharmony_ci if (argc == ARGC_NUM_MAX) { 29306f6ba60Sopenharmony_ci if (atoi(argv[1]) > 0 && atoi(argv[1]) <= 10) { // 10: max threads 29406f6ba60Sopenharmony_ci threadNum = atoi(argv[1]); 29506f6ba60Sopenharmony_ci } 29606f6ba60Sopenharmony_ci if (atoi(argv[2]) > 0 && atoi(argv[2]) <= 100) { // 2: args num. 100: max value 29706f6ba60Sopenharmony_ci forNum = atoi(argv[2]); // 2: args num 29806f6ba60Sopenharmony_ci } 29906f6ba60Sopenharmony_ci } else if (argc > ARGC_NUM_MAX) { 30006f6ba60Sopenharmony_ci printf("command error, argc must <= %d\n", ARGC_NUM_MAX); 30106f6ba60Sopenharmony_ci return 0; 30206f6ba60Sopenharmony_ci } 30306f6ba60Sopenharmony_ci fprintf(stderr, "start.Enter or send signal for next.\n"); 30406f6ba60Sopenharmony_ci getchar(); 30506f6ba60Sopenharmony_ci TestMemoryMap(); 30606f6ba60Sopenharmony_ci 30706f6ba60Sopenharmony_ci fprintf(stderr, "forNum = %d, threadNum = %d\n", forNum, threadNum); 30806f6ba60Sopenharmony_ci fprintf(stderr, "Notice: need copy libnativetest_so.z.so for %s, %s\n", 30906f6ba60Sopenharmony_ci VEC_SO_PATH[0].data(), VEC_SO_PATH[1].data()); 31006f6ba60Sopenharmony_ci pthread_t* thrArray = new (std::nothrow) pthread_t[threadNum]; 31106f6ba60Sopenharmony_ci if (!thrArray) { 31206f6ba60Sopenharmony_ci printf("new thread array failed.\n"); 31306f6ba60Sopenharmony_ci return 1; 31406f6ba60Sopenharmony_ci } 31506f6ba60Sopenharmony_ci int idx; 31606f6ba60Sopenharmony_ci for (idx = 0; idx < threadNum; ++idx) { 31706f6ba60Sopenharmony_ci if (pthread_create(thrArray + idx, nullptr, HhreadFuncCpp, static_cast<void*>(&forNum)) != 0) { 31806f6ba60Sopenharmony_ci printf("Creating thread failed.\n"); 31906f6ba60Sopenharmony_ci } 32006f6ba60Sopenharmony_ci } 32106f6ba60Sopenharmony_ci for (idx = 0; idx < threadNum; ++idx) { 32206f6ba60Sopenharmony_ci pthread_join(thrArray[idx], nullptr); 32306f6ba60Sopenharmony_ci } 32406f6ba60Sopenharmony_ci delete []thrArray; 32506f6ba60Sopenharmony_ci 32606f6ba60Sopenharmony_ci fprintf(stderr, "end.\n"); 32706f6ba60Sopenharmony_ci return 0; 32806f6ba60Sopenharmony_ci} 32906f6ba60Sopenharmony_ci 33006f6ba60Sopenharmony_ci#pragma clang optimize on