106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021-2022. 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 1606f6ba60Sopenharmony_ci#include <atomic> 1706f6ba60Sopenharmony_ci#include <climits> 1806f6ba60Sopenharmony_ci#include <dlfcn.h> 1906f6ba60Sopenharmony_ci#include <fcntl.h> 2006f6ba60Sopenharmony_ci#include <malloc.h> 2106f6ba60Sopenharmony_ci#include <string> 2206f6ba60Sopenharmony_ci#include <sys/time.h> 2306f6ba60Sopenharmony_ci#include <pthread.h> 2406f6ba60Sopenharmony_ci#include <sys/prctl.h> 2506f6ba60Sopenharmony_ci#include <unordered_map> 2606f6ba60Sopenharmony_ci#include <unordered_set> 2706f6ba60Sopenharmony_ci#include "dfx_regs_get.h" 2806f6ba60Sopenharmony_ci#include "c/executor_task.h" 2906f6ba60Sopenharmony_ci#include "common.h" 3006f6ba60Sopenharmony_ci#include "hook_common.h" 3106f6ba60Sopenharmony_ci#include "hook_socket_client.h" 3206f6ba60Sopenharmony_ci#include "logging.h" 3306f6ba60Sopenharmony_ci#include "musl_preinit_common.h" 3406f6ba60Sopenharmony_ci#include "parameter.h" 3506f6ba60Sopenharmony_ci#include "stack_writer.h" 3606f6ba60Sopenharmony_ci#include "runtime_stack_range.h" 3706f6ba60Sopenharmony_ci#include "get_thread_id.h" 3806f6ba60Sopenharmony_ci#include "hook_client.h" 3906f6ba60Sopenharmony_ci#include <sys/mman.h> 4006f6ba60Sopenharmony_ci#include "sampling.h" 4106f6ba60Sopenharmony_ci#include "hitrace/trace.h" 4206f6ba60Sopenharmony_ci 4306f6ba60Sopenharmony_ciusing namespace OHOS::HiviewDFX; 4406f6ba60Sopenharmony_ciusing namespace OHOS::Developtools::NativeDaemon; 4506f6ba60Sopenharmony_ci 4606f6ba60Sopenharmony_cistatic pthread_key_t g_disableHookFlag; 4706f6ba60Sopenharmony_cistatic pthread_key_t g_hookTid; 4806f6ba60Sopenharmony_cistatic pthread_key_t g_updateThreadNameCount; 4906f6ba60Sopenharmony_cinamespace { 5006f6ba60Sopenharmony_cistatic std::atomic<uint64_t> g_mallocTimes = 0; 5106f6ba60Sopenharmony_ci 5206f6ba60Sopenharmony_cienum class MISC_TYPE : uint32_t { 5306f6ba60Sopenharmony_ci JS_STACK_DATA = 1, 5406f6ba60Sopenharmony_ci}; 5506f6ba60Sopenharmony_ci 5606f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 5706f6ba60Sopenharmony_cistatic std::atomic<uint64_t> g_timeCost = 0; 5806f6ba60Sopenharmony_cistatic std::atomic<uint64_t> g_dataCounts = 0; 5906f6ba60Sopenharmony_ciconstexpr int PRINT_INTERVAL = 5000; 6006f6ba60Sopenharmony_ciconstexpr uint64_t S_TO_NS = 1000 * 1000 * 1000; 6106f6ba60Sopenharmony_ci#endif 6206f6ba60Sopenharmony_ci 6306f6ba60Sopenharmony_ciusing OHOS::Developtools::NativeDaemon::buildArchType; 6406f6ba60Sopenharmony_cistatic std::shared_ptr<HookSocketClient> g_hookClient {nullptr}; 6506f6ba60Sopenharmony_cistatic Sampling g_sampler; 6606f6ba60Sopenharmony_cistd::recursive_timed_mutex g_ClientMutex; 6706f6ba60Sopenharmony_cistd::mutex g_tagMapMutex; 6806f6ba60Sopenharmony_cistd::atomic<const MallocDispatchType*> g_dispatch {nullptr}; 6906f6ba60Sopenharmony_ciconstexpr int UPDATE_THEARD_NAME = 1000; 7006f6ba60Sopenharmony_cistatic pid_t g_hookPid = 0; 7106f6ba60Sopenharmony_cistatic ClientConfig g_ClientConfig = {0}; 7206f6ba60Sopenharmony_cistatic uint32_t g_maxSize = INT_MAX; 7306f6ba60Sopenharmony_cistatic std::unordered_map<std::string, uint32_t> g_memTagMap; 7406f6ba60Sopenharmony_ciconstexpr int PID_STR_SIZE = 4; 7506f6ba60Sopenharmony_ciconstexpr int STATUS_LINE_SIZE = 512; 7606f6ba60Sopenharmony_ciconstexpr int PID_NAMESPACE_ID = 1; // 1: pid is 1 after pid namespace used 7706f6ba60Sopenharmony_ciconstexpr int FD_PATH_LENGTH = 64; 7806f6ba60Sopenharmony_ciconstexpr int MIN_SAMPLER_INTERVAL = 1; 7906f6ba60Sopenharmony_ciconstexpr int FIRST_HASH = 16; 8006f6ba60Sopenharmony_ciconstexpr int SECOND_HASH = 13; 8106f6ba60Sopenharmony_ciconstexpr int THRESHOLD = 256; 8206f6ba60Sopenharmony_ciconstexpr int DIVIDE_VAL = 64; 8306f6ba60Sopenharmony_ci//5: fp mode is used, response_library_mode maximum stack depth 8406f6ba60Sopenharmony_ci#if defined(__aarch64__) 8506f6ba60Sopenharmony_ciconstexpr int RESPONSE_LIBRARY_MODE_DEPTH = 5; 8606f6ba60Sopenharmony_ciconstexpr int TEMP_IP = 100; 8706f6ba60Sopenharmony_ci#endif 8806f6ba60Sopenharmony_cistatic bool g_isPidChanged = false; 8906f6ba60Sopenharmony_cistatic struct mallinfo2 g_miStart = {0}; 9006f6ba60Sopenharmony_cistd::vector<std::pair<uint64_t, uint64_t>> g_filterStaLibRange; 9106f6ba60Sopenharmony_ciconstexpr int MAX_BITPOOL_SIZE = 1000 * 1024; 9206f6ba60Sopenharmony_cistruct Bitpool { 9306f6ba60Sopenharmony_ci std::atomic<uint64_t> slot; 9406f6ba60Sopenharmony_ci}; 9506f6ba60Sopenharmony_ciBitpool* g_addressChecker = nullptr; 9606f6ba60Sopenharmony_ci 9706f6ba60Sopenharmony_ciinline static uint32_t AddrHash(uint32_t h) 9806f6ba60Sopenharmony_ci{ 9906f6ba60Sopenharmony_ci h ^= h >> FIRST_HASH; 10006f6ba60Sopenharmony_ci h *= 0x85ebca6b; 10106f6ba60Sopenharmony_ci h ^= h >> SECOND_HASH; 10206f6ba60Sopenharmony_ci h *= 0xc2b2ae35; 10306f6ba60Sopenharmony_ci h ^= h >> FIRST_HASH; 10406f6ba60Sopenharmony_ci return h; 10506f6ba60Sopenharmony_ci} 10606f6ba60Sopenharmony_ci 10706f6ba60Sopenharmony_ciinline void Addr2Bitpool(void* addr) 10806f6ba60Sopenharmony_ci{ 10906f6ba60Sopenharmony_ci if (!g_addressChecker) { 11006f6ba60Sopenharmony_ci return; 11106f6ba60Sopenharmony_ci } 11206f6ba60Sopenharmony_ci uint32_t val = AddrHash(static_cast<uint32_t>(reinterpret_cast<uint64_t>(addr))) % (MAX_BITPOOL_SIZE * DIVIDE_VAL); 11306f6ba60Sopenharmony_ci g_addressChecker[val / DIVIDE_VAL].slot |= (0x1 << (val % DIVIDE_VAL)); 11406f6ba60Sopenharmony_ci} 11506f6ba60Sopenharmony_ci 11606f6ba60Sopenharmony_ciinline bool IsAddrExist(void* addr) 11706f6ba60Sopenharmony_ci{ 11806f6ba60Sopenharmony_ci if (!g_addressChecker) { 11906f6ba60Sopenharmony_ci return true; 12006f6ba60Sopenharmony_ci } 12106f6ba60Sopenharmony_ci uint32_t val = AddrHash(static_cast<uint32_t>(reinterpret_cast<uint64_t>(addr))) % (MAX_BITPOOL_SIZE * DIVIDE_VAL); 12206f6ba60Sopenharmony_ci if (g_addressChecker[val / DIVIDE_VAL].slot.load() & (0x1 << (val % DIVIDE_VAL))) { 12306f6ba60Sopenharmony_ci return true; 12406f6ba60Sopenharmony_ci } 12506f6ba60Sopenharmony_ci return false; 12606f6ba60Sopenharmony_ci} 12706f6ba60Sopenharmony_ci 12806f6ba60Sopenharmony_ciconst MallocDispatchType* GetDispatch() 12906f6ba60Sopenharmony_ci{ 13006f6ba60Sopenharmony_ci return g_dispatch.load(std::memory_order_relaxed); 13106f6ba60Sopenharmony_ci} 13206f6ba60Sopenharmony_ci 13306f6ba60Sopenharmony_cibool InititalizeIPC() 13406f6ba60Sopenharmony_ci{ 13506f6ba60Sopenharmony_ci return true; 13606f6ba60Sopenharmony_ci} 13706f6ba60Sopenharmony_civoid FinalizeIPC() {} 13806f6ba60Sopenharmony_ci 13906f6ba60Sopenharmony_ciint ConvertPid(char* buf, size_t len) 14006f6ba60Sopenharmony_ci{ 14106f6ba60Sopenharmony_ci UNUSED_PARAMETER(len); 14206f6ba60Sopenharmony_ci int count = 0; 14306f6ba60Sopenharmony_ci char pidBuf[11] = {0}; /* 11: 32 bits to the maximum length of a string */ 14406f6ba60Sopenharmony_ci char *str = buf; 14506f6ba60Sopenharmony_ci while (*str != '\0') { 14606f6ba60Sopenharmony_ci if ((*str >= '0') && (*str <= '9') && (static_cast<unsigned long>(count) < sizeof(pidBuf) - 1)) { 14706f6ba60Sopenharmony_ci pidBuf[count] = *str; 14806f6ba60Sopenharmony_ci count++; 14906f6ba60Sopenharmony_ci str++; 15006f6ba60Sopenharmony_ci continue; 15106f6ba60Sopenharmony_ci } 15206f6ba60Sopenharmony_ci 15306f6ba60Sopenharmony_ci if (count > 0) { 15406f6ba60Sopenharmony_ci break; 15506f6ba60Sopenharmony_ci } 15606f6ba60Sopenharmony_ci str++; 15706f6ba60Sopenharmony_ci } 15806f6ba60Sopenharmony_ci return atoi(pidBuf); 15906f6ba60Sopenharmony_ci} 16006f6ba60Sopenharmony_ci 16106f6ba60Sopenharmony_cipid_t GetRealPid(void) 16206f6ba60Sopenharmony_ci{ 16306f6ba60Sopenharmony_ci const char *path = "/proc/self/status"; 16406f6ba60Sopenharmony_ci char buf[STATUS_LINE_SIZE] = {0}; 16506f6ba60Sopenharmony_ci FILE *fp = fopen(path, "r"); 16606f6ba60Sopenharmony_ci CHECK_NOTNULL(fp, -1, "fopen fail"); 16706f6ba60Sopenharmony_ci while (!feof(fp)) { 16806f6ba60Sopenharmony_ci if (fgets(buf, STATUS_LINE_SIZE, fp) == nullptr) { 16906f6ba60Sopenharmony_ci fclose(fp); 17006f6ba60Sopenharmony_ci return -1; 17106f6ba60Sopenharmony_ci } 17206f6ba60Sopenharmony_ci if (strncmp(buf, "Pid:", PID_STR_SIZE) == 0) { 17306f6ba60Sopenharmony_ci break; 17406f6ba60Sopenharmony_ci } 17506f6ba60Sopenharmony_ci } 17606f6ba60Sopenharmony_ci (void)fclose(fp); 17706f6ba60Sopenharmony_ci return static_cast<pid_t>(ConvertPid(buf, sizeof(buf))); 17806f6ba60Sopenharmony_ci} 17906f6ba60Sopenharmony_ci} // namespace 18006f6ba60Sopenharmony_ci 18106f6ba60Sopenharmony_cipid_t inline __attribute__((always_inline)) GetCurThreadId() 18206f6ba60Sopenharmony_ci{ 18306f6ba60Sopenharmony_ci if (pthread_getspecific(g_hookTid) == nullptr) { 18406f6ba60Sopenharmony_ci pthread_setspecific(g_hookTid, reinterpret_cast<void *>(GetThreadId())); 18506f6ba60Sopenharmony_ci } 18606f6ba60Sopenharmony_ci return reinterpret_cast<long>((pthread_getspecific(g_hookTid))); 18706f6ba60Sopenharmony_ci} 18806f6ba60Sopenharmony_ci 18906f6ba60Sopenharmony_cibool inline __attribute__((always_inline)) UpdateThreadName(std::shared_ptr<HookSocketClient>& client) 19006f6ba60Sopenharmony_ci{ 19106f6ba60Sopenharmony_ci long updateCount = reinterpret_cast<long>(pthread_getspecific(g_updateThreadNameCount)); 19206f6ba60Sopenharmony_ci bool ret = true; 19306f6ba60Sopenharmony_ci if (updateCount == 0) { 19406f6ba60Sopenharmony_ci StackRawData tnameData = {{{{0}}}}; 19506f6ba60Sopenharmony_ci tnameData.tid = static_cast<uint32_t>(GetCurThreadId()); 19606f6ba60Sopenharmony_ci tnameData.type = THREAD_NAME_MSG; 19706f6ba60Sopenharmony_ci prctl(PR_GET_NAME, tnameData.name); 19806f6ba60Sopenharmony_ci ret = client->SendStackWithPayload(&tnameData, 19906f6ba60Sopenharmony_ci sizeof(BaseStackRawData) + strlen(tnameData.name) + 1, nullptr, 0); 20006f6ba60Sopenharmony_ci if (!ret) { 20106f6ba60Sopenharmony_ci return ret; 20206f6ba60Sopenharmony_ci } 20306f6ba60Sopenharmony_ci } 20406f6ba60Sopenharmony_ci pthread_setspecific(g_updateThreadNameCount, 20506f6ba60Sopenharmony_ci reinterpret_cast<void *>(updateCount == UPDATE_THEARD_NAME ? 0 : updateCount + 1)); 20606f6ba60Sopenharmony_ci return ret; 20706f6ba60Sopenharmony_ci} 20806f6ba60Sopenharmony_ci 20906f6ba60Sopenharmony_ciuint32_t inline __attribute__((always_inline)) GetTagId(std::shared_ptr<HookSocketClient>& client, const char* tagName) 21006f6ba60Sopenharmony_ci{ 21106f6ba60Sopenharmony_ci if (tagName == nullptr || strlen(tagName) > PATH_MAX) { 21206f6ba60Sopenharmony_ci return 0; 21306f6ba60Sopenharmony_ci } 21406f6ba60Sopenharmony_ci uint32_t tagId = 0; 21506f6ba60Sopenharmony_ci bool isNewTag = false; 21606f6ba60Sopenharmony_ci std::unique_lock<std::mutex> lock(g_tagMapMutex); 21706f6ba60Sopenharmony_ci auto it = g_memTagMap.find(tagName); 21806f6ba60Sopenharmony_ci if (it == g_memTagMap.end()) { 21906f6ba60Sopenharmony_ci isNewTag = true; 22006f6ba60Sopenharmony_ci tagId = g_memTagMap.size() + 1; 22106f6ba60Sopenharmony_ci g_memTagMap[tagName] = tagId; 22206f6ba60Sopenharmony_ci } else { 22306f6ba60Sopenharmony_ci tagId = it->second; 22406f6ba60Sopenharmony_ci } 22506f6ba60Sopenharmony_ci lock.unlock(); 22606f6ba60Sopenharmony_ci if (isNewTag) { 22706f6ba60Sopenharmony_ci StackRawData tagData = {{{{0}}}}; 22806f6ba60Sopenharmony_ci tagData.type = MEMORY_TAG; 22906f6ba60Sopenharmony_ci tagData.tagId = tagId; 23006f6ba60Sopenharmony_ci strcpy_s(tagData.name, PATH_MAX + 1, tagName); 23106f6ba60Sopenharmony_ci if (client != nullptr) { 23206f6ba60Sopenharmony_ci client->SendStackWithPayload(&tagData, sizeof(BaseStackRawData) + strlen(tagName) + 1, nullptr, 0); 23306f6ba60Sopenharmony_ci } 23406f6ba60Sopenharmony_ci } 23506f6ba60Sopenharmony_ci return tagId; 23606f6ba60Sopenharmony_ci} 23706f6ba60Sopenharmony_ci 23806f6ba60Sopenharmony_cistatic bool IsPidChanged(void); 23906f6ba60Sopenharmony_ci 24006f6ba60Sopenharmony_civoid* MallocHookStart(void* disableHookCallback) 24106f6ba60Sopenharmony_ci{ 24206f6ba60Sopenharmony_ci std::lock_guard<std::recursive_timed_mutex> guard(g_ClientMutex); 24306f6ba60Sopenharmony_ci g_addressChecker = new Bitpool [MAX_BITPOOL_SIZE] {{0}}; 24406f6ba60Sopenharmony_ci g_miStart = mallinfo2(); 24506f6ba60Sopenharmony_ci COMMON::PrintMallinfoLog("before hook(byte) => ", g_miStart); 24606f6ba60Sopenharmony_ci g_mallocTimes = 0; 24706f6ba60Sopenharmony_ci g_hookClient.reset(); 24806f6ba60Sopenharmony_ci if (g_hookClient != nullptr) { 24906f6ba60Sopenharmony_ci return nullptr; 25006f6ba60Sopenharmony_ci } else { 25106f6ba60Sopenharmony_ci g_ClientConfig.Reset(); 25206f6ba60Sopenharmony_ci g_sampler.Reset(); 25306f6ba60Sopenharmony_ci g_hookClient = std::make_shared<HookSocketClient>(g_hookPid, &g_ClientConfig, &g_sampler, 25406f6ba60Sopenharmony_ci reinterpret_cast<void (*)()>(disableHookCallback)); 25506f6ba60Sopenharmony_ci } 25606f6ba60Sopenharmony_ci return nullptr; 25706f6ba60Sopenharmony_ci} 25806f6ba60Sopenharmony_ci 25906f6ba60Sopenharmony_cibool ohos_malloc_hook_on_start(void (*disableHookCallback)()) 26006f6ba60Sopenharmony_ci{ 26106f6ba60Sopenharmony_ci pthread_t threadStart; 26206f6ba60Sopenharmony_ci if (pthread_create(&threadStart, nullptr, MallocHookStart, 26306f6ba60Sopenharmony_ci reinterpret_cast<void *>(disableHookCallback))) { 26406f6ba60Sopenharmony_ci return false; 26506f6ba60Sopenharmony_ci } 26606f6ba60Sopenharmony_ci pthread_detach(threadStart); 26706f6ba60Sopenharmony_ci g_hookPid = GetRealPid(); 26806f6ba60Sopenharmony_ci pthread_key_create(&g_disableHookFlag, nullptr); 26906f6ba60Sopenharmony_ci pthread_setspecific(g_disableHookFlag, nullptr); 27006f6ba60Sopenharmony_ci pthread_key_create(&g_hookTid, nullptr); 27106f6ba60Sopenharmony_ci pthread_setspecific(g_hookTid, nullptr); 27206f6ba60Sopenharmony_ci pthread_key_create(&g_updateThreadNameCount, nullptr); 27306f6ba60Sopenharmony_ci pthread_setspecific(g_updateThreadNameCount, reinterpret_cast<void *>(0)); 27406f6ba60Sopenharmony_ci GetMainThreadRuntimeStackRange(g_filterStaLibRange); 27506f6ba60Sopenharmony_ci constexpr int paramBufferLen = 128; 27606f6ba60Sopenharmony_ci char paramOutBuf[paramBufferLen] = {0}; 27706f6ba60Sopenharmony_ci int ret = GetParameter("persist.hiviewdfx.profiler.mem.filter", "", paramOutBuf, paramBufferLen); 27806f6ba60Sopenharmony_ci if (ret > 0) { 27906f6ba60Sopenharmony_ci int min = 0; 28006f6ba60Sopenharmony_ci int max = 0; 28106f6ba60Sopenharmony_ci if (sscanf_s(paramOutBuf, "%d,%d", &min, &max) == 2) { // 2: two parameters. 28206f6ba60Sopenharmony_ci g_maxSize = max > 0 ? static_cast<uint32_t>(max) : INT_MAX; 28306f6ba60Sopenharmony_ci g_ClientConfig.filterSize = min > 0 ? min : 0; 28406f6ba60Sopenharmony_ci } 28506f6ba60Sopenharmony_ci } 28606f6ba60Sopenharmony_ci return true; 28706f6ba60Sopenharmony_ci} 28806f6ba60Sopenharmony_ci 28906f6ba60Sopenharmony_civoid* ohos_release_on_end(void*) 29006f6ba60Sopenharmony_ci{ 29106f6ba60Sopenharmony_ci std::lock_guard<std::recursive_timed_mutex> guard(g_ClientMutex); 29206f6ba60Sopenharmony_ci delete [] g_addressChecker; 29306f6ba60Sopenharmony_ci g_addressChecker = nullptr; 29406f6ba60Sopenharmony_ci g_hookClient = nullptr; 29506f6ba60Sopenharmony_ci pthread_key_delete(g_disableHookFlag); 29606f6ba60Sopenharmony_ci pthread_key_delete(g_hookTid); 29706f6ba60Sopenharmony_ci pthread_key_delete(g_updateThreadNameCount); 29806f6ba60Sopenharmony_ci g_ClientConfig.Reset(); 29906f6ba60Sopenharmony_ci return nullptr; 30006f6ba60Sopenharmony_ci} 30106f6ba60Sopenharmony_ci 30206f6ba60Sopenharmony_cibool ohos_malloc_hook_on_end(void) 30306f6ba60Sopenharmony_ci{ 30406f6ba60Sopenharmony_ci { 30506f6ba60Sopenharmony_ci std::lock_guard<std::recursive_timed_mutex> guard(g_ClientMutex); 30606f6ba60Sopenharmony_ci if (g_hookClient != nullptr) { 30706f6ba60Sopenharmony_ci if (g_hookClient->GetNmdType() == 1) { 30806f6ba60Sopenharmony_ci g_hookClient->SendNmdInfo(); 30906f6ba60Sopenharmony_ci } 31006f6ba60Sopenharmony_ci g_hookClient->SendEndMsg(); 31106f6ba60Sopenharmony_ci g_hookClient->Flush(); 31206f6ba60Sopenharmony_ci } 31306f6ba60Sopenharmony_ci } 31406f6ba60Sopenharmony_ci pthread_t threadEnd; 31506f6ba60Sopenharmony_ci if (pthread_create(&threadEnd, nullptr, ohos_release_on_end, nullptr)) { 31606f6ba60Sopenharmony_ci return false; 31706f6ba60Sopenharmony_ci } 31806f6ba60Sopenharmony_ci pthread_detach(threadEnd); 31906f6ba60Sopenharmony_ci return true; 32006f6ba60Sopenharmony_ci} 32106f6ba60Sopenharmony_ci 32206f6ba60Sopenharmony_cibool FilterStandardSoIp(uint64_t ip) 32306f6ba60Sopenharmony_ci{ 32406f6ba60Sopenharmony_ci for (auto [soBegin, soEnd_]: g_filterStaLibRange) { 32506f6ba60Sopenharmony_ci if (ip >= soBegin && ip < soEnd_) { 32606f6ba60Sopenharmony_ci return true; 32706f6ba60Sopenharmony_ci } 32806f6ba60Sopenharmony_ci } 32906f6ba60Sopenharmony_ci return false; 33006f6ba60Sopenharmony_ci} 33106f6ba60Sopenharmony_ci 33206f6ba60Sopenharmony_ci#if defined(__aarch64__) 33306f6ba60Sopenharmony_cistatic int inline __attribute__((always_inline)) FpUnwind(int maxDepth, uint64_t* ip, int stackSize, 33406f6ba60Sopenharmony_ci const char* startPtr, const char* endPtr) 33506f6ba60Sopenharmony_ci{ 33606f6ba60Sopenharmony_ci void** startfp = (void**)__builtin_frame_address(0); 33706f6ba60Sopenharmony_ci void** fp = startfp; 33806f6ba60Sopenharmony_ci int depth = 0; 33906f6ba60Sopenharmony_ci int count = 0; 34006f6ba60Sopenharmony_ci uint64_t tempIp = 0; 34106f6ba60Sopenharmony_ci while (depth < maxDepth) { 34206f6ba60Sopenharmony_ci if (fp < (void**)startPtr || (fp + 1) >= (void**)endPtr) { 34306f6ba60Sopenharmony_ci break; 34406f6ba60Sopenharmony_ci } 34506f6ba60Sopenharmony_ci void** nextFp = (void**)*fp; 34606f6ba60Sopenharmony_ci if (nextFp <= fp) { 34706f6ba60Sopenharmony_ci break; 34806f6ba60Sopenharmony_ci } 34906f6ba60Sopenharmony_ci if (((nextFp - startfp) * sizeof(void*)) > static_cast<unsigned long>(stackSize)) { 35006f6ba60Sopenharmony_ci break; 35106f6ba60Sopenharmony_ci } 35206f6ba60Sopenharmony_ci fp = nextFp; 35306f6ba60Sopenharmony_ci tempIp = *(reinterpret_cast<unsigned long*>(fp + 1)); 35406f6ba60Sopenharmony_ci if (tempIp <= TEMP_IP) { 35506f6ba60Sopenharmony_ci break; 35606f6ba60Sopenharmony_ci } 35706f6ba60Sopenharmony_ci if (g_ClientConfig.responseLibraryMode) { 35806f6ba60Sopenharmony_ci if (++count >= RESPONSE_LIBRARY_MODE_DEPTH || !FilterStandardSoIp(tempIp)) { 35906f6ba60Sopenharmony_ci break; 36006f6ba60Sopenharmony_ci } 36106f6ba60Sopenharmony_ci } else { 36206f6ba60Sopenharmony_ci ip[depth++] = tempIp; 36306f6ba60Sopenharmony_ci } 36406f6ba60Sopenharmony_ci } 36506f6ba60Sopenharmony_ci if (g_ClientConfig.responseLibraryMode) { 36606f6ba60Sopenharmony_ci ip[0] = tempIp; 36706f6ba60Sopenharmony_ci depth = 1; 36806f6ba60Sopenharmony_ci } 36906f6ba60Sopenharmony_ci return depth; 37006f6ba60Sopenharmony_ci} 37106f6ba60Sopenharmony_ci 37206f6ba60Sopenharmony_ciuint64_t getJsChainId() 37306f6ba60Sopenharmony_ci{ 37406f6ba60Sopenharmony_ci if (g_ClientConfig.arktsConfig.jsStackReport > 0) { 37506f6ba60Sopenharmony_ci OHOS::HiviewDFX::HiTraceId hitraceId = OHOS::HiviewDFX::HiTraceChain::GetId(); 37606f6ba60Sopenharmony_ci if (hitraceId.IsValid()) { 37706f6ba60Sopenharmony_ci return hitraceId.GetChainId(); 37806f6ba60Sopenharmony_ci } 37906f6ba60Sopenharmony_ci } 38006f6ba60Sopenharmony_ci return 0; 38106f6ba60Sopenharmony_ci} 38206f6ba60Sopenharmony_ci#endif 38306f6ba60Sopenharmony_ci 38406f6ba60Sopenharmony_civoid* hook_malloc(void* (*fn)(size_t), size_t size) 38506f6ba60Sopenharmony_ci{ 38606f6ba60Sopenharmony_ci void* ret = nullptr; 38706f6ba60Sopenharmony_ci if (fn) { 38806f6ba60Sopenharmony_ci ret = fn(size); 38906f6ba60Sopenharmony_ci } 39006f6ba60Sopenharmony_ci if (g_ClientConfig.mallocDisable || IsPidChanged()) { 39106f6ba60Sopenharmony_ci return ret; 39206f6ba60Sopenharmony_ci } 39306f6ba60Sopenharmony_ci if (!ohos_set_filter_size(size, ret)) { 39406f6ba60Sopenharmony_ci return ret; 39506f6ba60Sopenharmony_ci } 39606f6ba60Sopenharmony_ci 39706f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 39806f6ba60Sopenharmony_ci struct timespec start = {}; 39906f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &start); 40006f6ba60Sopenharmony_ci#endif 40106f6ba60Sopenharmony_ci 40206f6ba60Sopenharmony_ci if (g_ClientConfig.sampleInterval > MIN_SAMPLER_INTERVAL && g_sampler.StartSampling(size) == 0) { //0 not sampling 40306f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 40406f6ba60Sopenharmony_ci g_mallocTimes++; 40506f6ba60Sopenharmony_ci struct timespec end = {}; 40606f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 40706f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 40806f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 40906f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 41006f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 41106f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 41206f6ba60Sopenharmony_ci } 41306f6ba60Sopenharmony_ci#endif 41406f6ba60Sopenharmony_ci return ret; 41506f6ba60Sopenharmony_ci } 41606f6ba60Sopenharmony_ci 41706f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 41806f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 41906f6ba60Sopenharmony_ci if (holder == nullptr) { 42006f6ba60Sopenharmony_ci return ret; 42106f6ba60Sopenharmony_ci } 42206f6ba60Sopenharmony_ci if (!UpdateThreadName(holder)) { 42306f6ba60Sopenharmony_ci return ret; 42406f6ba60Sopenharmony_ci } 42506f6ba60Sopenharmony_ci StackRawData rawdata = {{{{0}}}}; 42606f6ba60Sopenharmony_ci const char* stackptr = nullptr; 42706f6ba60Sopenharmony_ci const char* stackendptr = nullptr; 42806f6ba60Sopenharmony_ci int stackSize = 0; 42906f6ba60Sopenharmony_ci int fpStackDepth = 0; 43006f6ba60Sopenharmony_ci clock_gettime(g_ClientConfig.clockId, &rawdata.ts); 43106f6ba60Sopenharmony_ci 43206f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 43306f6ba60Sopenharmony_ci#ifdef __aarch64__ 43406f6ba60Sopenharmony_ci void* stackAddr = nullptr; 43506f6ba60Sopenharmony_ci size_t coroutineStackSize = 0; 43606f6ba60Sopenharmony_ci if (ffrt_get_current_coroutine_stack(&stackAddr, &coroutineStackSize)) { 43706f6ba60Sopenharmony_ci stackSize = static_cast<int>(coroutineStackSize); 43806f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(stackAddr); 43906f6ba60Sopenharmony_ci stackendptr = stackptr + coroutineStackSize; 44006f6ba60Sopenharmony_ci } else { 44106f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(__builtin_frame_address(0)); 44206f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 44306f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 44406f6ba60Sopenharmony_ci } 44506f6ba60Sopenharmony_ci fpStackDepth = FpUnwind(g_ClientConfig.maxStackDepth, rawdata.ip, stackSize, stackptr, stackendptr); 44606f6ba60Sopenharmony_ci stackSize = 0; 44706f6ba60Sopenharmony_ci rawdata.jsChainId = getJsChainId(); 44806f6ba60Sopenharmony_ci#endif 44906f6ba60Sopenharmony_ci } else { 45006f6ba60Sopenharmony_ci unsigned long* regs = reinterpret_cast<unsigned long*>(&(rawdata.regs)); 45106f6ba60Sopenharmony_ci GetLocalRegs(regs); 45206f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(regs[RegisterGetSP(buildArchType)]); 45306f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 45406f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 45506f6ba60Sopenharmony_ci if (stackendptr == nullptr) { 45606f6ba60Sopenharmony_ci stackSize = 0; 45706f6ba60Sopenharmony_ci } 45806f6ba60Sopenharmony_ci } 45906f6ba60Sopenharmony_ci rawdata.type = MALLOC_MSG; 46006f6ba60Sopenharmony_ci rawdata.pid = static_cast<uint32_t>(g_hookPid); 46106f6ba60Sopenharmony_ci rawdata.tid = static_cast<uint32_t>(GetCurThreadId()); 46206f6ba60Sopenharmony_ci rawdata.mallocSize = size; 46306f6ba60Sopenharmony_ci rawdata.addr = ret; 46406f6ba60Sopenharmony_ci if (g_ClientConfig.sampleInterval >= THRESHOLD) { 46506f6ba60Sopenharmony_ci Addr2Bitpool(ret); 46606f6ba60Sopenharmony_ci } 46706f6ba60Sopenharmony_ci int realSize = 0; 46806f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 46906f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + (fpStackDepth * sizeof(uint64_t)); 47006f6ba60Sopenharmony_ci } else { 47106f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + sizeof(rawdata.regs); 47206f6ba60Sopenharmony_ci } 47306f6ba60Sopenharmony_ci holder->SendStackWithPayload(&rawdata, realSize, stackptr, stackSize); 47406f6ba60Sopenharmony_ci g_mallocTimes++; 47506f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 47606f6ba60Sopenharmony_ci struct timespec end = {}; 47706f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 47806f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 47906f6ba60Sopenharmony_ci g_dataCounts += stackSize; 48006f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 48106f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 48206f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 48306f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 48406f6ba60Sopenharmony_ci } 48506f6ba60Sopenharmony_ci#endif 48606f6ba60Sopenharmony_ci return ret; 48706f6ba60Sopenharmony_ci} 48806f6ba60Sopenharmony_ci 48906f6ba60Sopenharmony_civoid* hook_aligned_alloc(void* (*fn)(size_t, size_t), size_t align, size_t len) 49006f6ba60Sopenharmony_ci{ 49106f6ba60Sopenharmony_ci void* ret = nullptr; 49206f6ba60Sopenharmony_ci if (fn) { 49306f6ba60Sopenharmony_ci ret = fn(align, len); 49406f6ba60Sopenharmony_ci } 49506f6ba60Sopenharmony_ci if (g_ClientConfig.mallocDisable || IsPidChanged()) { 49606f6ba60Sopenharmony_ci return ret; 49706f6ba60Sopenharmony_ci } 49806f6ba60Sopenharmony_ci if (!ohos_set_filter_size(len, ret)) { 49906f6ba60Sopenharmony_ci return ret; 50006f6ba60Sopenharmony_ci } 50106f6ba60Sopenharmony_ci 50206f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 50306f6ba60Sopenharmony_ci struct timespec start = {}; 50406f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &start); 50506f6ba60Sopenharmony_ci#endif 50606f6ba60Sopenharmony_ci 50706f6ba60Sopenharmony_ci if (g_ClientConfig.sampleInterval > MIN_SAMPLER_INTERVAL && g_sampler.StartSampling(len) == 0) { //0 not sampling 50806f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 50906f6ba60Sopenharmony_ci g_mallocTimes++; 51006f6ba60Sopenharmony_ci struct timespec end = {}; 51106f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 51206f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 51306f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 51406f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 51506f6ba60Sopenharmony_ci "g_aligned_allocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 51606f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 51706f6ba60Sopenharmony_ci } 51806f6ba60Sopenharmony_ci#endif 51906f6ba60Sopenharmony_ci return ret; 52006f6ba60Sopenharmony_ci } 52106f6ba60Sopenharmony_ci 52206f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 52306f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 52406f6ba60Sopenharmony_ci if (holder == nullptr) { 52506f6ba60Sopenharmony_ci return ret; 52606f6ba60Sopenharmony_ci } 52706f6ba60Sopenharmony_ci if (!UpdateThreadName(holder)) { 52806f6ba60Sopenharmony_ci return ret; 52906f6ba60Sopenharmony_ci } 53006f6ba60Sopenharmony_ci StackRawData rawdata = {{{{0}}}}; 53106f6ba60Sopenharmony_ci const char* stackptr = nullptr; 53206f6ba60Sopenharmony_ci const char* stackendptr = nullptr; 53306f6ba60Sopenharmony_ci int stackSize = 0; 53406f6ba60Sopenharmony_ci int fpStackDepth = 0; 53506f6ba60Sopenharmony_ci clock_gettime(g_ClientConfig.clockId, &rawdata.ts); 53606f6ba60Sopenharmony_ci 53706f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 53806f6ba60Sopenharmony_ci#ifdef __aarch64__ 53906f6ba60Sopenharmony_ci void* stackAddr = nullptr; 54006f6ba60Sopenharmony_ci size_t coroutineStackSize = 0; 54106f6ba60Sopenharmony_ci if (ffrt_get_current_coroutine_stack(&stackAddr, &coroutineStackSize)) { 54206f6ba60Sopenharmony_ci stackSize = static_cast<int>(coroutineStackSize); 54306f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(stackAddr); 54406f6ba60Sopenharmony_ci stackendptr = stackptr + coroutineStackSize; 54506f6ba60Sopenharmony_ci } else { 54606f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(__builtin_frame_address(0)); 54706f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 54806f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 54906f6ba60Sopenharmony_ci } 55006f6ba60Sopenharmony_ci fpStackDepth = FpUnwind(g_ClientConfig.maxStackDepth, rawdata.ip, stackSize, stackptr, stackendptr); 55106f6ba60Sopenharmony_ci stackSize = 0; 55206f6ba60Sopenharmony_ci rawdata.jsChainId = getJsChainId(); 55306f6ba60Sopenharmony_ci#endif 55406f6ba60Sopenharmony_ci } else { 55506f6ba60Sopenharmony_ci unsigned long* regs = reinterpret_cast<unsigned long*>(&(rawdata.regs)); 55606f6ba60Sopenharmony_ci GetLocalRegs(regs); 55706f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(regs[RegisterGetSP(buildArchType)]); 55806f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 55906f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 56006f6ba60Sopenharmony_ci if (stackendptr == nullptr) { 56106f6ba60Sopenharmony_ci stackSize = 0; 56206f6ba60Sopenharmony_ci } 56306f6ba60Sopenharmony_ci } 56406f6ba60Sopenharmony_ci rawdata.type = MALLOC_MSG; 56506f6ba60Sopenharmony_ci rawdata.pid = static_cast<uint32_t>(g_hookPid); 56606f6ba60Sopenharmony_ci rawdata.tid = static_cast<uint32_t>(GetCurThreadId()); 56706f6ba60Sopenharmony_ci rawdata.mallocSize = len; 56806f6ba60Sopenharmony_ci rawdata.addr = ret; 56906f6ba60Sopenharmony_ci if (g_ClientConfig.sampleInterval >= THRESHOLD) { 57006f6ba60Sopenharmony_ci Addr2Bitpool(ret); 57106f6ba60Sopenharmony_ci } 57206f6ba60Sopenharmony_ci int realSize = 0; 57306f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 57406f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + (fpStackDepth * sizeof(uint64_t)); 57506f6ba60Sopenharmony_ci } else { 57606f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + sizeof(rawdata.regs); 57706f6ba60Sopenharmony_ci } 57806f6ba60Sopenharmony_ci holder->SendStackWithPayload(&rawdata, realSize, stackptr, stackSize); 57906f6ba60Sopenharmony_ci g_mallocTimes++; 58006f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 58106f6ba60Sopenharmony_ci struct timespec end = {}; 58206f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 58306f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 58406f6ba60Sopenharmony_ci g_dataCounts += stackSize; 58506f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 58606f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 58706f6ba60Sopenharmony_ci "g_aligned_allocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 58806f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 58906f6ba60Sopenharmony_ci } 59006f6ba60Sopenharmony_ci#endif 59106f6ba60Sopenharmony_ci return ret; 59206f6ba60Sopenharmony_ci} 59306f6ba60Sopenharmony_ci 59406f6ba60Sopenharmony_civoid* hook_valloc(void* (*fn)(size_t), size_t size) 59506f6ba60Sopenharmony_ci{ 59606f6ba60Sopenharmony_ci void* pRet = nullptr; 59706f6ba60Sopenharmony_ci if (fn) { 59806f6ba60Sopenharmony_ci pRet = fn(size); 59906f6ba60Sopenharmony_ci } 60006f6ba60Sopenharmony_ci return pRet; 60106f6ba60Sopenharmony_ci} 60206f6ba60Sopenharmony_ci 60306f6ba60Sopenharmony_civoid* hook_calloc(void* (*fn)(size_t, size_t), size_t number, size_t size) 60406f6ba60Sopenharmony_ci{ 60506f6ba60Sopenharmony_ci void* pRet = nullptr; 60606f6ba60Sopenharmony_ci if (fn) { 60706f6ba60Sopenharmony_ci pRet = fn(number, size); 60806f6ba60Sopenharmony_ci } 60906f6ba60Sopenharmony_ci if (g_ClientConfig.mallocDisable || IsPidChanged()) { 61006f6ba60Sopenharmony_ci return pRet; 61106f6ba60Sopenharmony_ci } 61206f6ba60Sopenharmony_ci if (!ohos_set_filter_size(number * size, pRet)) { 61306f6ba60Sopenharmony_ci return pRet; 61406f6ba60Sopenharmony_ci } 61506f6ba60Sopenharmony_ci 61606f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 61706f6ba60Sopenharmony_ci struct timespec start = {}; 61806f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &start); 61906f6ba60Sopenharmony_ci#endif 62006f6ba60Sopenharmony_ci 62106f6ba60Sopenharmony_ci if (g_ClientConfig.sampleInterval > MIN_SAMPLER_INTERVAL && g_sampler.StartSampling(size * number) == 0) { 62206f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 62306f6ba60Sopenharmony_ci g_mallocTimes++; 62406f6ba60Sopenharmony_ci struct timespec end = {}; 62506f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 62606f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 62706f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 62806f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 62906f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 63006f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 63106f6ba60Sopenharmony_ci } 63206f6ba60Sopenharmony_ci#endif 63306f6ba60Sopenharmony_ci return pRet; 63406f6ba60Sopenharmony_ci } 63506f6ba60Sopenharmony_ci StackRawData rawdata = {{{{0}}}}; 63606f6ba60Sopenharmony_ci const char* stackptr = nullptr; 63706f6ba60Sopenharmony_ci const char* stackendptr = nullptr; 63806f6ba60Sopenharmony_ci int stackSize = 0; 63906f6ba60Sopenharmony_ci int fpStackDepth = 0; 64006f6ba60Sopenharmony_ci clock_gettime(g_ClientConfig.clockId, &rawdata.ts); 64106f6ba60Sopenharmony_ci 64206f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 64306f6ba60Sopenharmony_ci#ifdef __aarch64__ 64406f6ba60Sopenharmony_ci void* stackAddr = nullptr; 64506f6ba60Sopenharmony_ci size_t coroutineStackSize = 0; 64606f6ba60Sopenharmony_ci if (ffrt_get_current_coroutine_stack(&stackAddr, &coroutineStackSize)) { 64706f6ba60Sopenharmony_ci stackSize = static_cast<int>(coroutineStackSize); 64806f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(stackAddr); 64906f6ba60Sopenharmony_ci stackendptr = stackptr + coroutineStackSize; 65006f6ba60Sopenharmony_ci } else { 65106f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(__builtin_frame_address(0)); 65206f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 65306f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 65406f6ba60Sopenharmony_ci } 65506f6ba60Sopenharmony_ci fpStackDepth = FpUnwind(g_ClientConfig.maxStackDepth, rawdata.ip, stackSize, stackptr, stackendptr); 65606f6ba60Sopenharmony_ci stackSize = 0; 65706f6ba60Sopenharmony_ci rawdata.jsChainId = getJsChainId(); 65806f6ba60Sopenharmony_ci#endif 65906f6ba60Sopenharmony_ci } else { 66006f6ba60Sopenharmony_ci unsigned long* regs = reinterpret_cast<unsigned long*>(&(rawdata.regs)); 66106f6ba60Sopenharmony_ci GetLocalRegs(regs); 66206f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(regs[RegisterGetSP(buildArchType)]); 66306f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 66406f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 66506f6ba60Sopenharmony_ci if (stackendptr == nullptr) { 66606f6ba60Sopenharmony_ci stackSize = 0; 66706f6ba60Sopenharmony_ci } 66806f6ba60Sopenharmony_ci } 66906f6ba60Sopenharmony_ci 67006f6ba60Sopenharmony_ci rawdata.type = MALLOC_MSG; 67106f6ba60Sopenharmony_ci rawdata.pid = static_cast<uint32_t>(g_hookPid); 67206f6ba60Sopenharmony_ci rawdata.tid = static_cast<uint32_t>(GetCurThreadId()); 67306f6ba60Sopenharmony_ci rawdata.mallocSize = number * size; 67406f6ba60Sopenharmony_ci rawdata.addr = pRet; 67506f6ba60Sopenharmony_ci if (g_ClientConfig.sampleInterval >= THRESHOLD) { 67606f6ba60Sopenharmony_ci Addr2Bitpool(pRet); 67706f6ba60Sopenharmony_ci } 67806f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 67906f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 68006f6ba60Sopenharmony_ci if (holder != nullptr) { 68106f6ba60Sopenharmony_ci int realSize = 0; 68206f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 68306f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + (fpStackDepth * sizeof(uint64_t)); 68406f6ba60Sopenharmony_ci } else { 68506f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + sizeof(rawdata.regs); 68606f6ba60Sopenharmony_ci } 68706f6ba60Sopenharmony_ci holder->SendStackWithPayload(&rawdata, realSize, stackptr, stackSize); 68806f6ba60Sopenharmony_ci } 68906f6ba60Sopenharmony_ci g_mallocTimes++; 69006f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 69106f6ba60Sopenharmony_ci struct timespec end = {}; 69206f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 69306f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 69406f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 69506f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 69606f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 69706f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 69806f6ba60Sopenharmony_ci } 69906f6ba60Sopenharmony_ci#endif 70006f6ba60Sopenharmony_ci return pRet; 70106f6ba60Sopenharmony_ci} 70206f6ba60Sopenharmony_ci 70306f6ba60Sopenharmony_civoid* hook_memalign(void* (*fn)(size_t, size_t), size_t align, size_t bytes) 70406f6ba60Sopenharmony_ci{ 70506f6ba60Sopenharmony_ci void* pRet = nullptr; 70606f6ba60Sopenharmony_ci if (fn) { 70706f6ba60Sopenharmony_ci pRet = fn(align, bytes); 70806f6ba60Sopenharmony_ci } 70906f6ba60Sopenharmony_ci return pRet; 71006f6ba60Sopenharmony_ci} 71106f6ba60Sopenharmony_ci 71206f6ba60Sopenharmony_civoid* hook_realloc(void* (*fn)(void*, size_t), void* ptr, size_t size) 71306f6ba60Sopenharmony_ci{ 71406f6ba60Sopenharmony_ci void* pRet = nullptr; 71506f6ba60Sopenharmony_ci if (fn) { 71606f6ba60Sopenharmony_ci pRet = fn(ptr, size); 71706f6ba60Sopenharmony_ci } 71806f6ba60Sopenharmony_ci if (g_ClientConfig.mallocDisable || IsPidChanged()) { 71906f6ba60Sopenharmony_ci return pRet; 72006f6ba60Sopenharmony_ci } 72106f6ba60Sopenharmony_ci if (!ohos_set_filter_size(size, pRet)) { 72206f6ba60Sopenharmony_ci return pRet; 72306f6ba60Sopenharmony_ci } 72406f6ba60Sopenharmony_ci 72506f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 72606f6ba60Sopenharmony_ci struct timespec start = {}; 72706f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &start); 72806f6ba60Sopenharmony_ci#endif 72906f6ba60Sopenharmony_ci 73006f6ba60Sopenharmony_ci if (g_ClientConfig.sampleInterval > MIN_SAMPLER_INTERVAL && g_sampler.StartSampling(size) == 0) { 73106f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 73206f6ba60Sopenharmony_ci g_mallocTimes++; 73306f6ba60Sopenharmony_ci struct timespec end = {}; 73406f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 73506f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 73606f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 73706f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 73806f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 73906f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 74006f6ba60Sopenharmony_ci } 74106f6ba60Sopenharmony_ci#endif 74206f6ba60Sopenharmony_ci return pRet; 74306f6ba60Sopenharmony_ci } 74406f6ba60Sopenharmony_ci StackRawData rawdata = {{{{0}}}}; 74506f6ba60Sopenharmony_ci StackRawData freeData = {{{{0}}}}; 74606f6ba60Sopenharmony_ci const char* stackptr = nullptr; 74706f6ba60Sopenharmony_ci const char* stackendptr = nullptr; 74806f6ba60Sopenharmony_ci int stackSize = 0; 74906f6ba60Sopenharmony_ci int fpStackDepth = 0; 75006f6ba60Sopenharmony_ci clock_gettime(g_ClientConfig.clockId, &rawdata.ts); 75106f6ba60Sopenharmony_ci 75206f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 75306f6ba60Sopenharmony_ci#ifdef __aarch64__ 75406f6ba60Sopenharmony_ci void* stackAddr = nullptr; 75506f6ba60Sopenharmony_ci size_t coroutineStackSize = 0; 75606f6ba60Sopenharmony_ci if (ffrt_get_current_coroutine_stack(&stackAddr, &coroutineStackSize)) { 75706f6ba60Sopenharmony_ci stackSize = static_cast<int>(coroutineStackSize); 75806f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(stackAddr); 75906f6ba60Sopenharmony_ci stackendptr = stackptr + coroutineStackSize; 76006f6ba60Sopenharmony_ci } else { 76106f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(__builtin_frame_address(0)); 76206f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 76306f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 76406f6ba60Sopenharmony_ci } 76506f6ba60Sopenharmony_ci fpStackDepth = FpUnwind(g_ClientConfig.maxStackDepth, rawdata.ip, stackSize, stackptr, stackendptr); 76606f6ba60Sopenharmony_ci stackSize = 0; 76706f6ba60Sopenharmony_ci if (g_ClientConfig.freeStackData) { 76806f6ba60Sopenharmony_ci (void)memcpy_s(freeData.ip, sizeof(freeData.ip) / sizeof(uint64_t), 76906f6ba60Sopenharmony_ci rawdata.ip, sizeof(rawdata.ip) / sizeof(uint64_t)); 77006f6ba60Sopenharmony_ci } 77106f6ba60Sopenharmony_ci#endif 77206f6ba60Sopenharmony_ci } else { 77306f6ba60Sopenharmony_ci unsigned long* regs = reinterpret_cast<unsigned long*>(&(rawdata.regs)); 77406f6ba60Sopenharmony_ci GetLocalRegs(regs); 77506f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(regs[RegisterGetSP(buildArchType)]); 77606f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 77706f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 77806f6ba60Sopenharmony_ci if (stackendptr == nullptr) { 77906f6ba60Sopenharmony_ci stackSize = 0; 78006f6ba60Sopenharmony_ci } 78106f6ba60Sopenharmony_ci if (g_ClientConfig.freeStackData) { 78206f6ba60Sopenharmony_ci (void)memcpy_s(freeData.regs, sizeof(freeData.regs) / sizeof(char), 78306f6ba60Sopenharmony_ci rawdata.regs, sizeof(rawdata.regs) / sizeof(char)); 78406f6ba60Sopenharmony_ci } 78506f6ba60Sopenharmony_ci } 78606f6ba60Sopenharmony_ci 78706f6ba60Sopenharmony_ci rawdata.type = MALLOC_MSG; 78806f6ba60Sopenharmony_ci rawdata.pid = static_cast<uint32_t>(g_hookPid); 78906f6ba60Sopenharmony_ci rawdata.tid = static_cast<uint32_t>(GetCurThreadId()); 79006f6ba60Sopenharmony_ci rawdata.mallocSize = size; 79106f6ba60Sopenharmony_ci rawdata.addr = pRet; 79206f6ba60Sopenharmony_ci if (g_ClientConfig.sampleInterval >= THRESHOLD) { 79306f6ba60Sopenharmony_ci Addr2Bitpool(pRet); 79406f6ba60Sopenharmony_ci } 79506f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 79606f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 79706f6ba60Sopenharmony_ci if (holder != nullptr) { 79806f6ba60Sopenharmony_ci int realSize = 0; 79906f6ba60Sopenharmony_ci int freeRealSize = 0; 80006f6ba60Sopenharmony_ci freeData.type = FREE_MSG; 80106f6ba60Sopenharmony_ci freeData.pid = rawdata.pid; 80206f6ba60Sopenharmony_ci freeData.tid = rawdata.tid; 80306f6ba60Sopenharmony_ci freeData.mallocSize = 0; 80406f6ba60Sopenharmony_ci freeData.addr = ptr; 80506f6ba60Sopenharmony_ci freeData.ts = rawdata.ts; 80606f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 80706f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + (fpStackDepth * sizeof(uint64_t)); 80806f6ba60Sopenharmony_ci freeRealSize = sizeof(BaseStackRawData); 80906f6ba60Sopenharmony_ci } else { 81006f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + sizeof(rawdata.regs); 81106f6ba60Sopenharmony_ci freeRealSize = realSize; 81206f6ba60Sopenharmony_ci } 81306f6ba60Sopenharmony_ci holder->SendStackWithPayload(&freeData, freeRealSize, nullptr, 0); // 0: Don't unwind the freeData 81406f6ba60Sopenharmony_ci holder->SendStackWithPayload(&rawdata, realSize, stackptr, stackSize); 81506f6ba60Sopenharmony_ci } 81606f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 81706f6ba60Sopenharmony_ci g_mallocTimes++; 81806f6ba60Sopenharmony_ci struct timespec end = {}; 81906f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 82006f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 82106f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 82206f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 82306f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 82406f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 82506f6ba60Sopenharmony_ci } 82606f6ba60Sopenharmony_ci#endif 82706f6ba60Sopenharmony_ci return pRet; 82806f6ba60Sopenharmony_ci} 82906f6ba60Sopenharmony_ci 83006f6ba60Sopenharmony_cisize_t hook_malloc_usable_size(size_t (*fn)(void*), void* ptr) 83106f6ba60Sopenharmony_ci{ 83206f6ba60Sopenharmony_ci size_t ret = 0; 83306f6ba60Sopenharmony_ci if (fn) { 83406f6ba60Sopenharmony_ci ret = fn(ptr); 83506f6ba60Sopenharmony_ci } 83606f6ba60Sopenharmony_ci 83706f6ba60Sopenharmony_ci return ret; 83806f6ba60Sopenharmony_ci} 83906f6ba60Sopenharmony_ci 84006f6ba60Sopenharmony_civoid hook_free(void (*free_func)(void*), void* p) 84106f6ba60Sopenharmony_ci{ 84206f6ba60Sopenharmony_ci if (g_ClientConfig.statisticsInterval > 0) { 84306f6ba60Sopenharmony_ci if (!free_func) { 84406f6ba60Sopenharmony_ci return; 84506f6ba60Sopenharmony_ci } 84606f6ba60Sopenharmony_ci if (g_ClientConfig.mallocDisable || IsPidChanged()) { 84706f6ba60Sopenharmony_ci free_func(p); 84806f6ba60Sopenharmony_ci return; 84906f6ba60Sopenharmony_ci } 85006f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 85106f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 85206f6ba60Sopenharmony_ci if ((holder != nullptr) && p) { 85306f6ba60Sopenharmony_ci holder->SendStackWithPayload(&p, sizeof(uint64_t), nullptr, 0); 85406f6ba60Sopenharmony_ci } 85506f6ba60Sopenharmony_ci free_func(p); 85606f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 85706f6ba60Sopenharmony_ci g_mallocTimes++; 85806f6ba60Sopenharmony_ci struct timespec end = {}; 85906f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 86006f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 86106f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 86206f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 86306f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 86406f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 86506f6ba60Sopenharmony_ci } 86606f6ba60Sopenharmony_ci#endif 86706f6ba60Sopenharmony_ci return; 86806f6ba60Sopenharmony_ci } 86906f6ba60Sopenharmony_ci struct timespec freeTime = {}; 87006f6ba60Sopenharmony_ci clock_gettime(g_ClientConfig.clockId, &freeTime); 87106f6ba60Sopenharmony_ci if (free_func) { 87206f6ba60Sopenharmony_ci free_func(p); 87306f6ba60Sopenharmony_ci } 87406f6ba60Sopenharmony_ci if (g_ClientConfig.mallocDisable || IsPidChanged()) { 87506f6ba60Sopenharmony_ci return; 87606f6ba60Sopenharmony_ci } 87706f6ba60Sopenharmony_ci if (g_ClientConfig.sampleInterval >= THRESHOLD) { 87806f6ba60Sopenharmony_ci if (!IsAddrExist(p)) { 87906f6ba60Sopenharmony_ci return; 88006f6ba60Sopenharmony_ci } 88106f6ba60Sopenharmony_ci } 88206f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 88306f6ba60Sopenharmony_ci struct timespec start = {}; 88406f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &start); 88506f6ba60Sopenharmony_ci#endif 88606f6ba60Sopenharmony_ci StackRawData rawdata = {{{{0}}}}; 88706f6ba60Sopenharmony_ci const char* stackptr = nullptr; 88806f6ba60Sopenharmony_ci const char* stackendptr = nullptr; 88906f6ba60Sopenharmony_ci int stackSize = 0; 89006f6ba60Sopenharmony_ci int fpStackDepth = 0; 89106f6ba60Sopenharmony_ci rawdata.ts = freeTime; 89206f6ba60Sopenharmony_ci 89306f6ba60Sopenharmony_ci if (g_ClientConfig.freeStackData) { 89406f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 89506f6ba60Sopenharmony_ci#ifdef __aarch64__ 89606f6ba60Sopenharmony_ci void* stackAddr = nullptr; 89706f6ba60Sopenharmony_ci size_t coroutineStackSize = 0; 89806f6ba60Sopenharmony_ci if (ffrt_get_current_coroutine_stack(&stackAddr, &coroutineStackSize)) { 89906f6ba60Sopenharmony_ci stackSize = static_cast<int>(coroutineStackSize); 90006f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(stackAddr); 90106f6ba60Sopenharmony_ci stackendptr = stackptr + coroutineStackSize; 90206f6ba60Sopenharmony_ci } else { 90306f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(__builtin_frame_address(0)); 90406f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 90506f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 90606f6ba60Sopenharmony_ci } 90706f6ba60Sopenharmony_ci fpStackDepth = FpUnwind(g_ClientConfig.maxStackDepth, rawdata.ip, stackSize, stackptr, stackendptr); 90806f6ba60Sopenharmony_ci stackSize = 0; 90906f6ba60Sopenharmony_ci rawdata.jsChainId = getJsChainId(); 91006f6ba60Sopenharmony_ci#endif 91106f6ba60Sopenharmony_ci } else { 91206f6ba60Sopenharmony_ci unsigned long* regs = reinterpret_cast<unsigned long*>(&(rawdata.regs)); 91306f6ba60Sopenharmony_ci GetLocalRegs(regs); 91406f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(regs[RegisterGetSP(buildArchType)]); 91506f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 91606f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 91706f6ba60Sopenharmony_ci if (stackendptr == nullptr) { 91806f6ba60Sopenharmony_ci stackSize = 0; 91906f6ba60Sopenharmony_ci } 92006f6ba60Sopenharmony_ci } 92106f6ba60Sopenharmony_ci } 92206f6ba60Sopenharmony_ci 92306f6ba60Sopenharmony_ci rawdata.type = FREE_MSG; 92406f6ba60Sopenharmony_ci rawdata.pid = static_cast<uint32_t>(g_hookPid); 92506f6ba60Sopenharmony_ci rawdata.tid = static_cast<uint32_t>(GetCurThreadId()); 92606f6ba60Sopenharmony_ci rawdata.mallocSize = 0; 92706f6ba60Sopenharmony_ci rawdata.addr = p; 92806f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 92906f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 93006f6ba60Sopenharmony_ci if (holder != nullptr) { 93106f6ba60Sopenharmony_ci int realSize = 0; 93206f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 93306f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + (fpStackDepth * sizeof(uint64_t)); 93406f6ba60Sopenharmony_ci } else { 93506f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + sizeof(rawdata.regs); 93606f6ba60Sopenharmony_ci } 93706f6ba60Sopenharmony_ci holder->SendStackWithPayload(&rawdata, realSize, stackptr, stackSize); 93806f6ba60Sopenharmony_ci } 93906f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 94006f6ba60Sopenharmony_ci g_mallocTimes++; 94106f6ba60Sopenharmony_ci struct timespec end = {}; 94206f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 94306f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 94406f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 94506f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 94606f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 94706f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 94806f6ba60Sopenharmony_ci } 94906f6ba60Sopenharmony_ci#endif 95006f6ba60Sopenharmony_ci} 95106f6ba60Sopenharmony_ci 95206f6ba60Sopenharmony_ciinline void SendMmapFileRawData(int prot, int flags, off_t offset, const std::string& filePath, 95306f6ba60Sopenharmony_ci const StackRawData& rawdata, std::shared_ptr<HookSocketClient>& holder) 95406f6ba60Sopenharmony_ci{ 95506f6ba60Sopenharmony_ci StackRawData curRawdata = {{{{0}}}}; 95606f6ba60Sopenharmony_ci curRawdata.addr = rawdata.addr; 95706f6ba60Sopenharmony_ci curRawdata.pid = static_cast<uint32_t>(g_hookPid); 95806f6ba60Sopenharmony_ci curRawdata.mallocSize = rawdata.mallocSize; 95906f6ba60Sopenharmony_ci curRawdata.mmapArgs.offset = offset; 96006f6ba60Sopenharmony_ci curRawdata.type = OHOS::Developtools::NativeDaemon::MMAP_FILE_TYPE; 96106f6ba60Sopenharmony_ci if (prot & PROT_EXEC) { 96206f6ba60Sopenharmony_ci curRawdata.mmapArgs.flags |= PROT_EXEC; 96306f6ba60Sopenharmony_ci } 96406f6ba60Sopenharmony_ci size_t len = strlen(filePath.c_str()) + 1; 96506f6ba60Sopenharmony_ci if (strncpy_s(curRawdata.name, PATH_MAX + 1, filePath.c_str(), len) != EOK) { 96606f6ba60Sopenharmony_ci return; 96706f6ba60Sopenharmony_ci } 96806f6ba60Sopenharmony_ci if (flags & MAP_FIXED) { 96906f6ba60Sopenharmony_ci curRawdata.mmapArgs.flags |= MAP_FIXED; 97006f6ba60Sopenharmony_ci } 97106f6ba60Sopenharmony_ci holder->SendStackWithPayload(&curRawdata, sizeof(BaseStackRawData) + len, nullptr, 0); 97206f6ba60Sopenharmony_ci} 97306f6ba60Sopenharmony_ci 97406f6ba60Sopenharmony_civoid* hook_mmap(void*(*fn)(void*, size_t, int, int, int, off_t), 97506f6ba60Sopenharmony_ci void* addr, size_t length, int prot, int flags, int fd, off_t offset) 97606f6ba60Sopenharmony_ci{ 97706f6ba60Sopenharmony_ci void* ret = nullptr; 97806f6ba60Sopenharmony_ci if (fn) { 97906f6ba60Sopenharmony_ci ret = fn(addr, length, prot, flags, fd, offset); 98006f6ba60Sopenharmony_ci } 98106f6ba60Sopenharmony_ci if (g_ClientConfig.mmapDisable || IsPidChanged()) { 98206f6ba60Sopenharmony_ci return ret; 98306f6ba60Sopenharmony_ci } 98406f6ba60Sopenharmony_ci 98506f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 98606f6ba60Sopenharmony_ci struct timespec start = {}; 98706f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &start); 98806f6ba60Sopenharmony_ci#endif 98906f6ba60Sopenharmony_ci 99006f6ba60Sopenharmony_ci if ((fd < 0 && offset == 0) && g_ClientConfig.sampleInterval > MIN_SAMPLER_INTERVAL 99106f6ba60Sopenharmony_ci && g_sampler.StartSampling(length) == 0) { 99206f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 99306f6ba60Sopenharmony_ci g_mallocTimes++; 99406f6ba60Sopenharmony_ci struct timespec end = {}; 99506f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 99606f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 99706f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 99806f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 99906f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 100006f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 100106f6ba60Sopenharmony_ci } 100206f6ba60Sopenharmony_ci#endif 100306f6ba60Sopenharmony_ci return ret; 100406f6ba60Sopenharmony_ci } 100506f6ba60Sopenharmony_ci StackRawData rawdata = {{{{0}}}}; 100606f6ba60Sopenharmony_ci const char* stackptr = nullptr; 100706f6ba60Sopenharmony_ci const char* stackendptr = nullptr; 100806f6ba60Sopenharmony_ci int stackSize = 0; 100906f6ba60Sopenharmony_ci int fpStackDepth = 0; 101006f6ba60Sopenharmony_ci clock_gettime(g_ClientConfig.clockId, &rawdata.ts); 101106f6ba60Sopenharmony_ci 101206f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 101306f6ba60Sopenharmony_ci#ifdef __aarch64__ 101406f6ba60Sopenharmony_ci void* stackAddr = nullptr; 101506f6ba60Sopenharmony_ci size_t coroutineStackSize = 0; 101606f6ba60Sopenharmony_ci if (ffrt_get_current_coroutine_stack(&stackAddr, &coroutineStackSize)) { 101706f6ba60Sopenharmony_ci stackSize = static_cast<int>(coroutineStackSize); 101806f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(stackAddr); 101906f6ba60Sopenharmony_ci stackendptr = stackptr + coroutineStackSize; 102006f6ba60Sopenharmony_ci } else { 102106f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(__builtin_frame_address(0)); 102206f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 102306f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 102406f6ba60Sopenharmony_ci } 102506f6ba60Sopenharmony_ci fpStackDepth = FpUnwind(g_ClientConfig.maxStackDepth, rawdata.ip, stackSize, stackptr, stackendptr); 102606f6ba60Sopenharmony_ci stackSize = 0; 102706f6ba60Sopenharmony_ci rawdata.jsChainId = getJsChainId(); 102806f6ba60Sopenharmony_ci#endif 102906f6ba60Sopenharmony_ci } else { 103006f6ba60Sopenharmony_ci unsigned long* regs = reinterpret_cast<unsigned long*>(&(rawdata.regs)); 103106f6ba60Sopenharmony_ci GetLocalRegs(regs); 103206f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(regs[RegisterGetSP(buildArchType)]); 103306f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 103406f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 103506f6ba60Sopenharmony_ci if (stackendptr == nullptr) { 103606f6ba60Sopenharmony_ci stackSize = 0; 103706f6ba60Sopenharmony_ci } 103806f6ba60Sopenharmony_ci } 103906f6ba60Sopenharmony_ci 104006f6ba60Sopenharmony_ci rawdata.type = MMAP_MSG; 104106f6ba60Sopenharmony_ci rawdata.pid = static_cast<uint32_t>(g_hookPid); 104206f6ba60Sopenharmony_ci rawdata.tid = static_cast<uint32_t>(GetCurThreadId()); 104306f6ba60Sopenharmony_ci rawdata.mallocSize = length; 104406f6ba60Sopenharmony_ci rawdata.addr = ret; 104506f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 104606f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 104706f6ba60Sopenharmony_ci if (holder == nullptr) { 104806f6ba60Sopenharmony_ci return ret; 104906f6ba60Sopenharmony_ci } 105006f6ba60Sopenharmony_ci if (fd >= 0) { 105106f6ba60Sopenharmony_ci rawdata.type = MMAP_FILE_PAGE_MSG; 105206f6ba60Sopenharmony_ci char path[FD_PATH_LENGTH] = {0}; 105306f6ba60Sopenharmony_ci char fileName[PATH_MAX + 1] = {0}; 105406f6ba60Sopenharmony_ci (void)snprintf_s(path, FD_PATH_LENGTH, FD_PATH_LENGTH - 1, "/proc/self/fd/%d", fd); 105506f6ba60Sopenharmony_ci ssize_t len = readlink(path, fileName, sizeof(fileName) - 1); 105606f6ba60Sopenharmony_ci if (len != -1) { 105706f6ba60Sopenharmony_ci fileName[len] = '\0'; 105806f6ba60Sopenharmony_ci SendMmapFileRawData(prot, flags, offset, fileName, rawdata, holder); 105906f6ba60Sopenharmony_ci char* p = strrchr(fileName, '/'); 106006f6ba60Sopenharmony_ci if (p != nullptr) { 106106f6ba60Sopenharmony_ci rawdata.tagId = GetTagId(holder, &fileName[p - fileName + 1]); 106206f6ba60Sopenharmony_ci } else { 106306f6ba60Sopenharmony_ci rawdata.tagId = GetTagId(holder, fileName); 106406f6ba60Sopenharmony_ci } 106506f6ba60Sopenharmony_ci } 106606f6ba60Sopenharmony_ci } 106706f6ba60Sopenharmony_ci if (!UpdateThreadName(holder)) { 106806f6ba60Sopenharmony_ci return ret; 106906f6ba60Sopenharmony_ci } 107006f6ba60Sopenharmony_ci int realSize = 0; 107106f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 107206f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + (fpStackDepth * sizeof(uint64_t)); 107306f6ba60Sopenharmony_ci } else { 107406f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + sizeof(rawdata.regs); 107506f6ba60Sopenharmony_ci } 107606f6ba60Sopenharmony_ci holder->SendStackWithPayload(&rawdata, realSize, stackptr, stackSize); 107706f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 107806f6ba60Sopenharmony_ci g_mallocTimes++; 107906f6ba60Sopenharmony_ci struct timespec end = {}; 108006f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 108106f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 108206f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 108306f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 108406f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 108506f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 108606f6ba60Sopenharmony_ci } 108706f6ba60Sopenharmony_ci#endif 108806f6ba60Sopenharmony_ci return ret; 108906f6ba60Sopenharmony_ci} 109006f6ba60Sopenharmony_ci 109106f6ba60Sopenharmony_ciint hook_munmap(int(*fn)(void*, size_t), void* addr, size_t length) 109206f6ba60Sopenharmony_ci{ 109306f6ba60Sopenharmony_ci int ret = -1; 109406f6ba60Sopenharmony_ci struct timespec unmapTime = {}; 109506f6ba60Sopenharmony_ci clock_gettime(g_ClientConfig.clockId, &unmapTime); 109606f6ba60Sopenharmony_ci if (fn) { 109706f6ba60Sopenharmony_ci ret = fn(addr, length); 109806f6ba60Sopenharmony_ci } 109906f6ba60Sopenharmony_ci if (g_ClientConfig.mmapDisable || IsPidChanged()) { 110006f6ba60Sopenharmony_ci return ret; 110106f6ba60Sopenharmony_ci } 110206f6ba60Sopenharmony_ci 110306f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 110406f6ba60Sopenharmony_ci struct timespec start = {}; 110506f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &start); 110606f6ba60Sopenharmony_ci#endif 110706f6ba60Sopenharmony_ci 110806f6ba60Sopenharmony_ci int stackSize = 0; 110906f6ba60Sopenharmony_ci StackRawData rawdata = {{{{0}}}}; 111006f6ba60Sopenharmony_ci const char* stackptr = nullptr; 111106f6ba60Sopenharmony_ci const char* stackendptr = nullptr; 111206f6ba60Sopenharmony_ci int fpStackDepth = 0; 111306f6ba60Sopenharmony_ci rawdata.ts = unmapTime; 111406f6ba60Sopenharmony_ci if (g_ClientConfig.munmapStackData) { 111506f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 111606f6ba60Sopenharmony_ci#ifdef __aarch64__ 111706f6ba60Sopenharmony_ci void* stackAddr = nullptr; 111806f6ba60Sopenharmony_ci size_t coroutineStackSize = 0; 111906f6ba60Sopenharmony_ci if (ffrt_get_current_coroutine_stack(&stackAddr, &coroutineStackSize)) { 112006f6ba60Sopenharmony_ci stackSize = static_cast<int>(coroutineStackSize); 112106f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(stackAddr); 112206f6ba60Sopenharmony_ci stackendptr = stackptr + coroutineStackSize; 112306f6ba60Sopenharmony_ci } else { 112406f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(__builtin_frame_address(0)); 112506f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 112606f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 112706f6ba60Sopenharmony_ci } 112806f6ba60Sopenharmony_ci fpStackDepth = FpUnwind(g_ClientConfig.maxStackDepth, rawdata.ip, stackSize, stackptr, stackendptr); 112906f6ba60Sopenharmony_ci stackSize = 0; 113006f6ba60Sopenharmony_ci rawdata.jsChainId = getJsChainId(); 113106f6ba60Sopenharmony_ci#endif 113206f6ba60Sopenharmony_ci } else { 113306f6ba60Sopenharmony_ci unsigned long* regs = reinterpret_cast<unsigned long*>(&(rawdata.regs)); 113406f6ba60Sopenharmony_ci GetLocalRegs(regs); 113506f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(regs[RegisterGetSP(buildArchType)]); 113606f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 113706f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 113806f6ba60Sopenharmony_ci if (stackendptr == nullptr) { 113906f6ba60Sopenharmony_ci stackSize = 0; 114006f6ba60Sopenharmony_ci } 114106f6ba60Sopenharmony_ci } 114206f6ba60Sopenharmony_ci } 114306f6ba60Sopenharmony_ci 114406f6ba60Sopenharmony_ci rawdata.type = MUNMAP_MSG; 114506f6ba60Sopenharmony_ci rawdata.pid = static_cast<uint32_t>(g_hookPid); 114606f6ba60Sopenharmony_ci rawdata.tid = static_cast<uint32_t>(GetCurThreadId()); 114706f6ba60Sopenharmony_ci rawdata.mallocSize = length; 114806f6ba60Sopenharmony_ci rawdata.addr = addr; 114906f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 115006f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 115106f6ba60Sopenharmony_ci if (holder != nullptr) { 115206f6ba60Sopenharmony_ci int realSize = 0; 115306f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 115406f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + (fpStackDepth * sizeof(uint64_t)); 115506f6ba60Sopenharmony_ci } else { 115606f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + sizeof(rawdata.regs); 115706f6ba60Sopenharmony_ci } 115806f6ba60Sopenharmony_ci holder->SendStackWithPayload(&rawdata, realSize, stackptr, stackSize); 115906f6ba60Sopenharmony_ci } 116006f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 116106f6ba60Sopenharmony_ci g_mallocTimes++; 116206f6ba60Sopenharmony_ci struct timespec end = {}; 116306f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 116406f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 116506f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 116606f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 116706f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 116806f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 116906f6ba60Sopenharmony_ci } 117006f6ba60Sopenharmony_ci#endif 117106f6ba60Sopenharmony_ci return ret; 117206f6ba60Sopenharmony_ci} 117306f6ba60Sopenharmony_ci 117406f6ba60Sopenharmony_ciint hook_prctl(int(*fn)(int, ...), 117506f6ba60Sopenharmony_ci int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) 117606f6ba60Sopenharmony_ci{ 117706f6ba60Sopenharmony_ci int ret = -1; 117806f6ba60Sopenharmony_ci if (fn) { 117906f6ba60Sopenharmony_ci ret = fn(option, arg2, arg3, arg4, arg5); 118006f6ba60Sopenharmony_ci } 118106f6ba60Sopenharmony_ci if (reinterpret_cast<char*>(arg5) == nullptr || IsPidChanged()) { 118206f6ba60Sopenharmony_ci return ret; 118306f6ba60Sopenharmony_ci } 118406f6ba60Sopenharmony_ci if (option == PR_SET_VMA && arg2 == PR_SET_VMA_ANON_NAME) { 118506f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 118606f6ba60Sopenharmony_ci struct timespec start = {}; 118706f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &start); 118806f6ba60Sopenharmony_ci#endif 118906f6ba60Sopenharmony_ci StackRawData rawdata = {{{{0}}}}; 119006f6ba60Sopenharmony_ci clock_gettime(g_ClientConfig.clockId, &rawdata.ts); 119106f6ba60Sopenharmony_ci rawdata.type = PR_SET_VMA_MSG; 119206f6ba60Sopenharmony_ci rawdata.pid = static_cast<uint32_t>(g_hookPid); 119306f6ba60Sopenharmony_ci rawdata.tid = static_cast<uint32_t>(GetCurThreadId()); 119406f6ba60Sopenharmony_ci rawdata.mallocSize = arg4; 119506f6ba60Sopenharmony_ci rawdata.addr = reinterpret_cast<void*>(arg3); 119606f6ba60Sopenharmony_ci size_t tagLen = strlen(reinterpret_cast<char*>(arg5)) + 1; 119706f6ba60Sopenharmony_ci if (memcpy_s(rawdata.name, sizeof(rawdata.name), reinterpret_cast<char*>(arg5), tagLen) != EOK) { 119806f6ba60Sopenharmony_ci HILOG_BASE_ERROR(LOG_CORE, "memcpy_s tag failed"); 119906f6ba60Sopenharmony_ci } 120006f6ba60Sopenharmony_ci rawdata.name[sizeof(rawdata.name) - 1] = '\0'; 120106f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 120206f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 120306f6ba60Sopenharmony_ci if (holder != nullptr) { 120406f6ba60Sopenharmony_ci holder->SendStackWithPayload(&rawdata, sizeof(BaseStackRawData) + tagLen, nullptr, 0); 120506f6ba60Sopenharmony_ci } 120606f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 120706f6ba60Sopenharmony_ci g_mallocTimes++; 120806f6ba60Sopenharmony_ci struct timespec end = {}; 120906f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 121006f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 121106f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 121206f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 121306f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 121406f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 121506f6ba60Sopenharmony_ci } 121606f6ba60Sopenharmony_ci#endif 121706f6ba60Sopenharmony_ci } 121806f6ba60Sopenharmony_ci return ret; 121906f6ba60Sopenharmony_ci} 122006f6ba60Sopenharmony_ci 122106f6ba60Sopenharmony_civoid hook_memtrace(void* addr, size_t size, const char* tag, bool isUsing) 122206f6ba60Sopenharmony_ci{ 122306f6ba60Sopenharmony_ci if (!g_ClientConfig.memtraceEnable || IsPidChanged()) { 122406f6ba60Sopenharmony_ci return; 122506f6ba60Sopenharmony_ci } 122606f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 122706f6ba60Sopenharmony_ci struct timespec start = {}; 122806f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &start); 122906f6ba60Sopenharmony_ci#endif 123006f6ba60Sopenharmony_ci int stackSize = 0; 123106f6ba60Sopenharmony_ci StackRawData rawdata = {{{{0}}}}; 123206f6ba60Sopenharmony_ci const char* stackptr = nullptr; 123306f6ba60Sopenharmony_ci const char* stackendptr = nullptr; 123406f6ba60Sopenharmony_ci int fpStackDepth = 0; 123506f6ba60Sopenharmony_ci clock_gettime(g_ClientConfig.clockId, &rawdata.ts); 123606f6ba60Sopenharmony_ci 123706f6ba60Sopenharmony_ci if (isUsing) { 123806f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 123906f6ba60Sopenharmony_ci#ifdef __aarch64__ 124006f6ba60Sopenharmony_ci void* stackAddr = nullptr; 124106f6ba60Sopenharmony_ci size_t coroutineStackSize = 0; 124206f6ba60Sopenharmony_ci if (ffrt_get_current_coroutine_stack(&stackAddr, &coroutineStackSize)) { 124306f6ba60Sopenharmony_ci stackSize = static_cast<int>(coroutineStackSize); 124406f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(stackAddr); 124506f6ba60Sopenharmony_ci stackendptr = stackptr + coroutineStackSize; 124606f6ba60Sopenharmony_ci } else { 124706f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(__builtin_frame_address(0)); 124806f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 124906f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 125006f6ba60Sopenharmony_ci } 125106f6ba60Sopenharmony_ci fpStackDepth = FpUnwind(g_ClientConfig.maxStackDepth, rawdata.ip, stackSize, stackptr, stackendptr); 125206f6ba60Sopenharmony_ci stackSize = 0; 125306f6ba60Sopenharmony_ci rawdata.jsChainId = getJsChainId(); 125406f6ba60Sopenharmony_ci#endif 125506f6ba60Sopenharmony_ci } else { 125606f6ba60Sopenharmony_ci unsigned long* regs = reinterpret_cast<unsigned long*>(&(rawdata.regs)); 125706f6ba60Sopenharmony_ci GetLocalRegs(regs); 125806f6ba60Sopenharmony_ci stackptr = reinterpret_cast<const char*>(regs[RegisterGetSP(buildArchType)]); 125906f6ba60Sopenharmony_ci GetRuntimeStackEnd(stackptr, &stackendptr, g_hookPid, GetCurThreadId()); // stack end pointer 126006f6ba60Sopenharmony_ci stackSize = stackendptr - stackptr; 126106f6ba60Sopenharmony_ci if (stackendptr == nullptr) { 126206f6ba60Sopenharmony_ci stackSize = 0; 126306f6ba60Sopenharmony_ci } 126406f6ba60Sopenharmony_ci } 126506f6ba60Sopenharmony_ci } 126606f6ba60Sopenharmony_ci rawdata.type = isUsing ? MEMORY_USING_MSG : MEMORY_UNUSING_MSG; 126706f6ba60Sopenharmony_ci rawdata.pid = static_cast<uint32_t>(g_hookPid); 126806f6ba60Sopenharmony_ci rawdata.tid = static_cast<uint32_t>(GetCurThreadId()); 126906f6ba60Sopenharmony_ci rawdata.mallocSize = size; 127006f6ba60Sopenharmony_ci rawdata.addr = addr; 127106f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 127206f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 127306f6ba60Sopenharmony_ci rawdata.tagId = isUsing ? GetTagId(holder, tag) : 0; 127406f6ba60Sopenharmony_ci if (holder != nullptr) { 127506f6ba60Sopenharmony_ci int realSize = 0; 127606f6ba60Sopenharmony_ci if (g_ClientConfig.fpunwind) { 127706f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + (fpStackDepth * sizeof(uint64_t)); 127806f6ba60Sopenharmony_ci } else { 127906f6ba60Sopenharmony_ci realSize = sizeof(BaseStackRawData) + sizeof(rawdata.regs); 128006f6ba60Sopenharmony_ci } 128106f6ba60Sopenharmony_ci holder->SendStackWithPayload(&rawdata, realSize, stackptr, stackSize); 128206f6ba60Sopenharmony_ci } 128306f6ba60Sopenharmony_ci#ifdef PERFORMANCE_DEBUG 128406f6ba60Sopenharmony_ci g_mallocTimes++; 128506f6ba60Sopenharmony_ci struct timespec end = {}; 128606f6ba60Sopenharmony_ci clock_gettime(CLOCK_REALTIME, &end); 128706f6ba60Sopenharmony_ci g_timeCost += (end.tv_sec - start.tv_sec) * S_TO_NS + (end.tv_nsec - start.tv_nsec); 128806f6ba60Sopenharmony_ci if (g_mallocTimes % PRINT_INTERVAL == 0) { 128906f6ba60Sopenharmony_ci PROFILER_LOG_ERROR(LOG_CORE, 129006f6ba60Sopenharmony_ci "g_mallocTimes %" PRIu64" cost time = %" PRIu64" copy data bytes = %" PRIu64" mean cost = %" PRIu64"\n", 129106f6ba60Sopenharmony_ci g_mallocTimes.load(), g_timeCost.load(), g_dataCounts.load(), g_timeCost.load() / g_mallocTimes.load()); 129206f6ba60Sopenharmony_ci } 129306f6ba60Sopenharmony_ci#endif 129406f6ba60Sopenharmony_ci} 129506f6ba60Sopenharmony_ci 129606f6ba60Sopenharmony_cibool ohos_malloc_hook_initialize(const MallocDispatchType*malloc_dispatch, bool*, const char*) 129706f6ba60Sopenharmony_ci{ 129806f6ba60Sopenharmony_ci g_dispatch.store(malloc_dispatch); 129906f6ba60Sopenharmony_ci InititalizeIPC(); 130006f6ba60Sopenharmony_ci return true; 130106f6ba60Sopenharmony_ci} 130206f6ba60Sopenharmony_civoid ohos_malloc_hook_finalize(void) 130306f6ba60Sopenharmony_ci{ 130406f6ba60Sopenharmony_ci FinalizeIPC(); 130506f6ba60Sopenharmony_ci} 130606f6ba60Sopenharmony_ci 130706f6ba60Sopenharmony_civoid* ohos_malloc_hook_malloc(size_t size) 130806f6ba60Sopenharmony_ci{ 130906f6ba60Sopenharmony_ci __set_hook_flag(false); 131006f6ba60Sopenharmony_ci void* ret = hook_malloc(GetDispatch()->malloc, size); 131106f6ba60Sopenharmony_ci __set_hook_flag(true); 131206f6ba60Sopenharmony_ci return ret; 131306f6ba60Sopenharmony_ci} 131406f6ba60Sopenharmony_ci 131506f6ba60Sopenharmony_civoid* ohos_malloc_hook_realloc(void* ptr, size_t size) 131606f6ba60Sopenharmony_ci{ 131706f6ba60Sopenharmony_ci __set_hook_flag(false); 131806f6ba60Sopenharmony_ci void* ret = hook_realloc(GetDispatch()->realloc, ptr, size); 131906f6ba60Sopenharmony_ci __set_hook_flag(true); 132006f6ba60Sopenharmony_ci return ret; 132106f6ba60Sopenharmony_ci} 132206f6ba60Sopenharmony_ci 132306f6ba60Sopenharmony_civoid* ohos_malloc_hook_calloc(size_t number, size_t size) 132406f6ba60Sopenharmony_ci{ 132506f6ba60Sopenharmony_ci __set_hook_flag(false); 132606f6ba60Sopenharmony_ci void* ret = hook_calloc(GetDispatch()->calloc, number, size); 132706f6ba60Sopenharmony_ci __set_hook_flag(true); 132806f6ba60Sopenharmony_ci return ret; 132906f6ba60Sopenharmony_ci} 133006f6ba60Sopenharmony_ci 133106f6ba60Sopenharmony_civoid* ohos_malloc_hook_valloc(size_t size) 133206f6ba60Sopenharmony_ci{ 133306f6ba60Sopenharmony_ci __set_hook_flag(false); 133406f6ba60Sopenharmony_ci void* ret = hook_valloc(GetDispatch()->valloc, size); 133506f6ba60Sopenharmony_ci __set_hook_flag(true); 133606f6ba60Sopenharmony_ci return ret; 133706f6ba60Sopenharmony_ci} 133806f6ba60Sopenharmony_ci 133906f6ba60Sopenharmony_civoid ohos_malloc_hook_free(void* p) 134006f6ba60Sopenharmony_ci{ 134106f6ba60Sopenharmony_ci __set_hook_flag(false); 134206f6ba60Sopenharmony_ci hook_free(GetDispatch()->free, p); 134306f6ba60Sopenharmony_ci __set_hook_flag(true); 134406f6ba60Sopenharmony_ci} 134506f6ba60Sopenharmony_ci 134606f6ba60Sopenharmony_cisize_t ohos_malloc_hook_malloc_usable_size(void* mem) 134706f6ba60Sopenharmony_ci{ 134806f6ba60Sopenharmony_ci __set_hook_flag(false); 134906f6ba60Sopenharmony_ci size_t ret = hook_malloc_usable_size(GetDispatch()->malloc_usable_size, mem); 135006f6ba60Sopenharmony_ci __set_hook_flag(true); 135106f6ba60Sopenharmony_ci return ret; 135206f6ba60Sopenharmony_ci} 135306f6ba60Sopenharmony_ci 135406f6ba60Sopenharmony_cibool ohos_malloc_hook_get_hook_flag(void) 135506f6ba60Sopenharmony_ci{ 135606f6ba60Sopenharmony_ci return pthread_getspecific(g_disableHookFlag) == nullptr; 135706f6ba60Sopenharmony_ci} 135806f6ba60Sopenharmony_ci 135906f6ba60Sopenharmony_cibool ohos_malloc_hook_set_hook_flag(bool flag) 136006f6ba60Sopenharmony_ci{ 136106f6ba60Sopenharmony_ci bool oldFlag = ohos_malloc_hook_get_hook_flag(); 136206f6ba60Sopenharmony_ci if (flag) { 136306f6ba60Sopenharmony_ci pthread_setspecific(g_disableHookFlag, nullptr); 136406f6ba60Sopenharmony_ci } else { 136506f6ba60Sopenharmony_ci pthread_setspecific(g_disableHookFlag, reinterpret_cast<void *>(1)); 136606f6ba60Sopenharmony_ci } 136706f6ba60Sopenharmony_ci return oldFlag; 136806f6ba60Sopenharmony_ci} 136906f6ba60Sopenharmony_ci 137006f6ba60Sopenharmony_civoid* ohos_malloc_hook_mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) 137106f6ba60Sopenharmony_ci{ 137206f6ba60Sopenharmony_ci __set_hook_flag(false); 137306f6ba60Sopenharmony_ci void* ret = hook_mmap(GetDispatch()->mmap, addr, length, prot, flags, fd, offset); 137406f6ba60Sopenharmony_ci __set_hook_flag(true); 137506f6ba60Sopenharmony_ci return ret; 137606f6ba60Sopenharmony_ci} 137706f6ba60Sopenharmony_ci 137806f6ba60Sopenharmony_ciint ohos_malloc_hook_munmap(void* addr, size_t length) 137906f6ba60Sopenharmony_ci{ 138006f6ba60Sopenharmony_ci __set_hook_flag(false); 138106f6ba60Sopenharmony_ci int ret = hook_munmap(GetDispatch()->munmap, addr, length); 138206f6ba60Sopenharmony_ci __set_hook_flag(true); 138306f6ba60Sopenharmony_ci return ret; 138406f6ba60Sopenharmony_ci} 138506f6ba60Sopenharmony_ci 138606f6ba60Sopenharmony_civoid ohos_malloc_hook_memtrace(void* addr, size_t size, const char* tag, bool isUsing) 138706f6ba60Sopenharmony_ci{ 138806f6ba60Sopenharmony_ci __set_hook_flag(false); 138906f6ba60Sopenharmony_ci hook_memtrace(addr, size, tag, isUsing); 139006f6ba60Sopenharmony_ci __set_hook_flag(true); 139106f6ba60Sopenharmony_ci} 139206f6ba60Sopenharmony_ci 139306f6ba60Sopenharmony_civoid* ohos_malloc_hook_aligned_alloc(size_t align, size_t len) 139406f6ba60Sopenharmony_ci{ 139506f6ba60Sopenharmony_ci __set_hook_flag(false); 139606f6ba60Sopenharmony_ci void* ret = hook_aligned_alloc(GetDispatch()->aligned_alloc, align, len); 139706f6ba60Sopenharmony_ci __set_hook_flag(true); 139806f6ba60Sopenharmony_ci return ret; 139906f6ba60Sopenharmony_ci} 140006f6ba60Sopenharmony_ci 140106f6ba60Sopenharmony_ciint ohos_malloc_hook_prctl(int option, unsigned long arg2, unsigned long arg3, 140206f6ba60Sopenharmony_ci unsigned long arg4, unsigned long arg5) 140306f6ba60Sopenharmony_ci{ 140406f6ba60Sopenharmony_ci __set_hook_flag(false); 140506f6ba60Sopenharmony_ci int ret = hook_prctl((GetDispatch()->prctl), option, arg2, arg3, arg4, arg5); 140606f6ba60Sopenharmony_ci __set_hook_flag(true); 140706f6ba60Sopenharmony_ci return ret; 140806f6ba60Sopenharmony_ci} 140906f6ba60Sopenharmony_ci 141006f6ba60Sopenharmony_cibool ohos_set_filter_size(size_t size, void* ret) 141106f6ba60Sopenharmony_ci{ 141206f6ba60Sopenharmony_ci if (g_ClientConfig.filterSize < 0 || size < static_cast<size_t>(g_ClientConfig.filterSize) || size > g_maxSize) { 141306f6ba60Sopenharmony_ci return false; 141406f6ba60Sopenharmony_ci } 141506f6ba60Sopenharmony_ci return true; 141606f6ba60Sopenharmony_ci} 141706f6ba60Sopenharmony_ci 141806f6ba60Sopenharmony_cistatic bool IsPidChanged(void) 141906f6ba60Sopenharmony_ci{ 142006f6ba60Sopenharmony_ci if (g_isPidChanged) { 142106f6ba60Sopenharmony_ci return true; 142206f6ba60Sopenharmony_ci } 142306f6ba60Sopenharmony_ci int pid = getprocpid(); 142406f6ba60Sopenharmony_ci // hap app after pid namespace used 142506f6ba60Sopenharmony_ci if (pid == PID_NAMESPACE_ID) { 142606f6ba60Sopenharmony_ci return false; 142706f6ba60Sopenharmony_ci } else { 142806f6ba60Sopenharmony_ci // native app & sa service 142906f6ba60Sopenharmony_ci g_isPidChanged = (g_hookPid != pid); 143006f6ba60Sopenharmony_ci } 143106f6ba60Sopenharmony_ci return g_isPidChanged; 143206f6ba60Sopenharmony_ci} 143306f6ba60Sopenharmony_ci 143406f6ba60Sopenharmony_cibool ohos_malloc_hook_send_hook_misc_data(uint64_t id, const char* stackPtr, size_t stackSize, uint32_t type) 143506f6ba60Sopenharmony_ci{ 143606f6ba60Sopenharmony_ci if (type == static_cast<uint32_t>(MISC_TYPE::JS_STACK_DATA)) { 143706f6ba60Sopenharmony_ci StackRawData rawdata = {{{{0}}}}; 143806f6ba60Sopenharmony_ci rawdata.jsChainId = id; 143906f6ba60Sopenharmony_ci rawdata.type = JS_STACK_MSG; 144006f6ba60Sopenharmony_ci std::weak_ptr<HookSocketClient> weakClient = g_hookClient; 144106f6ba60Sopenharmony_ci auto holder = weakClient.lock(); 144206f6ba60Sopenharmony_ci if (holder != nullptr) { 144306f6ba60Sopenharmony_ci return holder->SendStackWithPayload(&rawdata, sizeof(BaseStackRawData), stackPtr, stackSize); 144406f6ba60Sopenharmony_ci } 144506f6ba60Sopenharmony_ci } 144606f6ba60Sopenharmony_ci return false; 144706f6ba60Sopenharmony_ci} 144806f6ba60Sopenharmony_ci 144906f6ba60Sopenharmony_civoid* ohos_malloc_hook_get_hook_config() 145006f6ba60Sopenharmony_ci{ 145106f6ba60Sopenharmony_ci return &g_ClientConfig.arktsConfig; 145206f6ba60Sopenharmony_ci}