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}