106f6ba60Sopenharmony_ci/*
206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. 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 "hook_manager.h"
1706f6ba60Sopenharmony_ci
1806f6ba60Sopenharmony_ci#include <limits>
1906f6ba60Sopenharmony_ci#include <sys/stat.h>
2006f6ba60Sopenharmony_ci#include <unistd.h>
2106f6ba60Sopenharmony_ci#include <cstdlib>
2206f6ba60Sopenharmony_ci#include "command_poller.h"
2306f6ba60Sopenharmony_ci#include "common.h"
2406f6ba60Sopenharmony_ci#include "epoll_event_poller.h"
2506f6ba60Sopenharmony_ci#include "event_notifier.h"
2606f6ba60Sopenharmony_ci#include "hook_common.h"
2706f6ba60Sopenharmony_ci#include "hook_service.h"
2806f6ba60Sopenharmony_ci#include "init_param.h"
2906f6ba60Sopenharmony_ci#include "logging.h"
3006f6ba60Sopenharmony_ci#include "plugin_service_types.pb.h"
3106f6ba60Sopenharmony_ci#include "share_memory_allocator.h"
3206f6ba60Sopenharmony_ci#include "utilities.h"
3306f6ba60Sopenharmony_ci#include "virtual_runtime.h"
3406f6ba60Sopenharmony_ci#include "hook_common.h"
3506f6ba60Sopenharmony_ci#include "common.h"
3606f6ba60Sopenharmony_ci#include "native_memory_profiler_sa_service.h"
3706f6ba60Sopenharmony_ci
3806f6ba60Sopenharmony_cinamespace OHOS::Developtools::NativeDaemon {
3906f6ba60Sopenharmony_cinamespace {
4006f6ba60Sopenharmony_ciconstexpr int DEFAULT_EVENT_POLLING_INTERVAL = 5000;
4106f6ba60Sopenharmony_ciconstexpr uint32_t PAGE_BYTES = 4096;
4206f6ba60Sopenharmony_cistd::shared_ptr<Writer> g_buffWriter;
4306f6ba60Sopenharmony_ciconst std::string STARTUP = "startup:";
4406f6ba60Sopenharmony_ciconst std::string PARAM_NAME = "libc.hook_mode";
4506f6ba60Sopenharmony_ciconstexpr int SIGNAL_START_HOOK = 36;
4606f6ba60Sopenharmony_ciconstexpr int SIGNAL_STOP_HOOK = 37;
4706f6ba60Sopenharmony_ciconst std::string VERSION = "1.02";
4806f6ba60Sopenharmony_ciconstexpr int32_t RESPONSE_MAX_PID_COUNT = 8;
4906f6ba60Sopenharmony_ciconstexpr int32_t MAX_PID_COUNT = 4;
5006f6ba60Sopenharmony_ci}
5106f6ba60Sopenharmony_ci
5206f6ba60Sopenharmony_ciHookManager::~HookManager()
5306f6ba60Sopenharmony_ci{
5406f6ba60Sopenharmony_ci    hookService_ = nullptr;
5506f6ba60Sopenharmony_ci    for (const auto& item : hookCtx_) {
5606f6ba60Sopenharmony_ci        if (item->eventPoller != nullptr) {
5706f6ba60Sopenharmony_ci            item->eventPoller = nullptr;
5806f6ba60Sopenharmony_ci        }
5906f6ba60Sopenharmony_ci        if (item->shareMemoryBlock != nullptr) {
6006f6ba60Sopenharmony_ci            item->shareMemoryBlock = nullptr;
6106f6ba60Sopenharmony_ci        }
6206f6ba60Sopenharmony_ci        if (item->stackPreprocess != nullptr) {
6306f6ba60Sopenharmony_ci            item->stackPreprocess = nullptr;
6406f6ba60Sopenharmony_ci        }
6506f6ba60Sopenharmony_ci        if (item->stackData != nullptr) {
6606f6ba60Sopenharmony_ci            item->stackData = nullptr;
6706f6ba60Sopenharmony_ci        }
6806f6ba60Sopenharmony_ci    }
6906f6ba60Sopenharmony_ci}
7006f6ba60Sopenharmony_ci
7106f6ba60Sopenharmony_cibool HookManager::CheckProcess()
7206f6ba60Sopenharmony_ci{
7306f6ba60Sopenharmony_ci    if (hookConfig_.pid() > 0) {
7406f6ba60Sopenharmony_ci        hookConfig_.add_expand_pids(hookConfig_.pid());
7506f6ba60Sopenharmony_ci    }
7606f6ba60Sopenharmony_ci    std::set<int32_t> pidCache;
7706f6ba60Sopenharmony_ci    for (const auto& pid : hookConfig_.expand_pids()) {
7806f6ba60Sopenharmony_ci        if (pid > 0) {
7906f6ba60Sopenharmony_ci            struct stat statBuf;
8006f6ba60Sopenharmony_ci            std::string pidPath = "/proc/" + std::to_string(pid) + "/status";
8106f6ba60Sopenharmony_ci            if (stat(pidPath.c_str(), &statBuf) != 0) {
8206f6ba60Sopenharmony_ci                PROFILER_LOG_ERROR(LOG_CORE, "%s: hook process does not exist", __func__);
8306f6ba60Sopenharmony_ci                return false;
8406f6ba60Sopenharmony_ci            } else {
8506f6ba60Sopenharmony_ci                auto [iter, isExist] = pidCache.emplace(pid);
8606f6ba60Sopenharmony_ci                if (isExist) {
8706f6ba60Sopenharmony_ci                    hookCtx_.emplace_back(std::make_shared<HookManagerCtx>(pid));
8806f6ba60Sopenharmony_ci                    PROFILER_LOG_INFO(LOG_CORE, "hook context: pid: %d", pid);
8906f6ba60Sopenharmony_ci                }
9006f6ba60Sopenharmony_ci                continue;
9106f6ba60Sopenharmony_ci            }
9206f6ba60Sopenharmony_ci        }
9306f6ba60Sopenharmony_ci    }
9406f6ba60Sopenharmony_ci
9506f6ba60Sopenharmony_ci    if (!hookConfig_.process_name().empty() && !CheckProcessName()) {
9606f6ba60Sopenharmony_ci        return false;
9706f6ba60Sopenharmony_ci    }
9806f6ba60Sopenharmony_ci
9906f6ba60Sopenharmony_ci    if (hookConfig_.response_library_mode()) {
10006f6ba60Sopenharmony_ci        if (hookCtx_.size() > RESPONSE_MAX_PID_COUNT) {
10106f6ba60Sopenharmony_ci            PROFILER_LOG_ERROR(LOG_CORE, "%s: The maximum allowed is to set %d PIDs.",
10206f6ba60Sopenharmony_ci                               __func__, RESPONSE_MAX_PID_COUNT);
10306f6ba60Sopenharmony_ci            return false;
10406f6ba60Sopenharmony_ci        }
10506f6ba60Sopenharmony_ci    } else {
10606f6ba60Sopenharmony_ci        if (hookCtx_.size() > MAX_PID_COUNT) {
10706f6ba60Sopenharmony_ci            PROFILER_LOG_ERROR(LOG_CORE, "%s: The maximum allowed is to set %d PIDs.", __func__, MAX_PID_COUNT);
10806f6ba60Sopenharmony_ci            return false;
10906f6ba60Sopenharmony_ci        }
11006f6ba60Sopenharmony_ci    }
11106f6ba60Sopenharmony_ci
11206f6ba60Sopenharmony_ci    if (hookCtx_.size() > 1) {
11306f6ba60Sopenharmony_ci        isProtobufSerialize_ = true;
11406f6ba60Sopenharmony_ci    }
11506f6ba60Sopenharmony_ci    return true;
11606f6ba60Sopenharmony_ci}
11706f6ba60Sopenharmony_ci
11806f6ba60Sopenharmony_cibool HookManager::CheckProcessName()
11906f6ba60Sopenharmony_ci{
12006f6ba60Sopenharmony_ci    int pidValue = -1;
12106f6ba60Sopenharmony_ci    const std::string processName = hookConfig_.process_name();
12206f6ba60Sopenharmony_ci    bool isExist = COMMON::IsProcessExist(processName, pidValue);
12306f6ba60Sopenharmony_ci    if (hookConfig_.startup_mode() || !isExist) {
12406f6ba60Sopenharmony_ci        PROFILER_LOG_INFO(LOG_CORE, "Wait process %s start or restart, set param", hookConfig_.process_name().c_str());
12506f6ba60Sopenharmony_ci        std::string cmd = STARTUP + hookConfig_.process_name();
12606f6ba60Sopenharmony_ci        int ret = SystemSetParameter(PARAM_NAME.c_str(), cmd.c_str());
12706f6ba60Sopenharmony_ci        if (ret < 0) {
12806f6ba60Sopenharmony_ci            PROFILER_LOG_ERROR(LOG_CORE, "set param failed, please manually set param and start process(%s)",
12906f6ba60Sopenharmony_ci                               hookConfig_.process_name().c_str());
13006f6ba60Sopenharmony_ci        } else {
13106f6ba60Sopenharmony_ci            PROFILER_LOG_INFO(LOG_CORE, "set param success, please start process(%s)",
13206f6ba60Sopenharmony_ci                              hookConfig_.process_name().c_str());
13306f6ba60Sopenharmony_ci            hookCtx_.emplace_back(std::make_shared<HookManagerCtx>(hookConfig_.process_name()));
13406f6ba60Sopenharmony_ci            hookConfig_.set_startup_mode(true);
13506f6ba60Sopenharmony_ci        }
13606f6ba60Sopenharmony_ci    } else if (pidValue != -1) {
13706f6ba60Sopenharmony_ci        PROFILER_LOG_INFO(LOG_CORE, "Process %s exist, pid = %d", hookConfig_.process_name().c_str(), pidValue);
13806f6ba60Sopenharmony_ci        for (const auto& item : hookCtx_) {
13906f6ba60Sopenharmony_ci            if (item->pid == pidValue) {
14006f6ba60Sopenharmony_ci                return true;
14106f6ba60Sopenharmony_ci            }
14206f6ba60Sopenharmony_ci        }
14306f6ba60Sopenharmony_ci        hookCtx_.emplace_back(std::make_shared<HookManagerCtx>(pidValue));
14406f6ba60Sopenharmony_ci    } else {
14506f6ba60Sopenharmony_ci        PROFILER_LOG_ERROR(LOG_CORE, "The startup mode parameter is not set, name: %s",
14606f6ba60Sopenharmony_ci                           hookConfig_.process_name().c_str());
14706f6ba60Sopenharmony_ci        return false;
14806f6ba60Sopenharmony_ci    }
14906f6ba60Sopenharmony_ci    return true;
15006f6ba60Sopenharmony_ci}
15106f6ba60Sopenharmony_ci
15206f6ba60Sopenharmony_civoid HookManager::SetCommandPoller(const std::shared_ptr<CommandPoller>& p)
15306f6ba60Sopenharmony_ci{
15406f6ba60Sopenharmony_ci    commandPoller_ = p;
15506f6ba60Sopenharmony_ci}
15606f6ba60Sopenharmony_ci
15706f6ba60Sopenharmony_cibool HookManager::RegisterAgentPlugin(const std::string& pluginPath)
15806f6ba60Sopenharmony_ci{
15906f6ba60Sopenharmony_ci    RegisterPluginRequest request;
16006f6ba60Sopenharmony_ci    request.set_request_id(commandPoller_->GetRequestId());
16106f6ba60Sopenharmony_ci    request.set_path(pluginPath);
16206f6ba60Sopenharmony_ci    request.set_sha256("");
16306f6ba60Sopenharmony_ci    request.set_name(pluginPath);
16406f6ba60Sopenharmony_ci    request.set_buffer_size_hint(0);
16506f6ba60Sopenharmony_ci    RegisterPluginResponse response;
16606f6ba60Sopenharmony_ci
16706f6ba60Sopenharmony_ci    if (commandPoller_->RegisterPlugin(request, response)) {
16806f6ba60Sopenharmony_ci        if (response.status() == ResponseStatus::OK) {
16906f6ba60Sopenharmony_ci            PROFILER_LOG_DEBUG(LOG_CORE, "response.plugin_id() = %d", response.plugin_id());
17006f6ba60Sopenharmony_ci            agentIndex_ = response.plugin_id();
17106f6ba60Sopenharmony_ci            PROFILER_LOG_DEBUG(LOG_CORE, "RegisterPlugin OK");
17206f6ba60Sopenharmony_ci        } else {
17306f6ba60Sopenharmony_ci            PROFILER_LOG_DEBUG(LOG_CORE, "RegisterPlugin FAIL 1");
17406f6ba60Sopenharmony_ci            return false;
17506f6ba60Sopenharmony_ci        }
17606f6ba60Sopenharmony_ci    } else {
17706f6ba60Sopenharmony_ci        PROFILER_LOG_DEBUG(LOG_CORE, "RegisterPlugin FAIL 2");
17806f6ba60Sopenharmony_ci        return false;
17906f6ba60Sopenharmony_ci    }
18006f6ba60Sopenharmony_ci
18106f6ba60Sopenharmony_ci    return true;
18206f6ba60Sopenharmony_ci}
18306f6ba60Sopenharmony_ci
18406f6ba60Sopenharmony_cibool HookManager::UnregisterAgentPlugin(const std::string& pluginPath)
18506f6ba60Sopenharmony_ci{
18606f6ba60Sopenharmony_ci    UnregisterPluginRequest request;
18706f6ba60Sopenharmony_ci    request.set_request_id(commandPoller_->GetRequestId());
18806f6ba60Sopenharmony_ci    request.set_plugin_id(agentIndex_);
18906f6ba60Sopenharmony_ci    UnregisterPluginResponse response;
19006f6ba60Sopenharmony_ci    if (commandPoller_->UnregisterPlugin(request, response)) {
19106f6ba60Sopenharmony_ci        CHECK_TRUE(response.status() == ResponseStatus::OK, false, "UnregisterPlugin FAIL 1");
19206f6ba60Sopenharmony_ci    } else {
19306f6ba60Sopenharmony_ci        PROFILER_LOG_DEBUG(LOG_CORE, "UnregisterPlugin FAIL 2");
19406f6ba60Sopenharmony_ci        return false;
19506f6ba60Sopenharmony_ci    }
19606f6ba60Sopenharmony_ci    agentIndex_ = -1;
19706f6ba60Sopenharmony_ci
19806f6ba60Sopenharmony_ci    return true;
19906f6ba60Sopenharmony_ci}
20006f6ba60Sopenharmony_ci
20106f6ba60Sopenharmony_cibool HookManager::LoadPlugin(const std::string& pluginPath)
20206f6ba60Sopenharmony_ci{
20306f6ba60Sopenharmony_ci    return true;
20406f6ba60Sopenharmony_ci}
20506f6ba60Sopenharmony_ci
20606f6ba60Sopenharmony_cibool HookManager::UnloadPlugin(const std::string& pluginPath)
20706f6ba60Sopenharmony_ci{
20806f6ba60Sopenharmony_ci    return true;
20906f6ba60Sopenharmony_ci}
21006f6ba60Sopenharmony_ci
21106f6ba60Sopenharmony_cibool HookManager::UnloadPlugin(const uint32_t pluginId)
21206f6ba60Sopenharmony_ci{
21306f6ba60Sopenharmony_ci    return true;
21406f6ba60Sopenharmony_ci}
21506f6ba60Sopenharmony_ci
21606f6ba60Sopenharmony_civoid HookManager::GetClientConfig(ClientConfig& clientConfig)
21706f6ba60Sopenharmony_ci{
21806f6ba60Sopenharmony_ci    clientConfig.shareMemorySize = static_cast<uint32_t>(hookConfig_.smb_pages() * PAGE_BYTES);
21906f6ba60Sopenharmony_ci    clientConfig.filterSize = static_cast<int32_t>(hookConfig_.filter_size());
22006f6ba60Sopenharmony_ci    clientConfig.clockId = COMMON::GetClockId(hookConfig_.clock());
22106f6ba60Sopenharmony_ci    clientConfig.maxStackDepth = hookConfig_.max_stack_depth();
22206f6ba60Sopenharmony_ci    clientConfig.arktsConfig.maxJsStackDepth = hookConfig_.max_js_stack_depth();
22306f6ba60Sopenharmony_ci    clientConfig.mallocDisable = hookConfig_.malloc_disable();
22406f6ba60Sopenharmony_ci    clientConfig.mmapDisable = hookConfig_.mmap_disable();
22506f6ba60Sopenharmony_ci    clientConfig.freeStackData = hookConfig_.free_stack_report();
22606f6ba60Sopenharmony_ci    clientConfig.munmapStackData = hookConfig_.munmap_stack_report();
22706f6ba60Sopenharmony_ci    clientConfig.fpunwind = hookConfig_.fp_unwind();
22806f6ba60Sopenharmony_ci    clientConfig.arktsConfig.jsFpunwind = hookConfig_.fp_unwind();
22906f6ba60Sopenharmony_ci    clientConfig.isBlocked = hookConfig_.blocked();
23006f6ba60Sopenharmony_ci    clientConfig.memtraceEnable = hookConfig_.memtrace_enable();
23106f6ba60Sopenharmony_ci    clientConfig.statisticsInterval = hookConfig_.statistics_interval();
23206f6ba60Sopenharmony_ci    clientConfig.sampleInterval = hookConfig_.sample_interval();
23306f6ba60Sopenharmony_ci    clientConfig.responseLibraryMode = hookConfig_.response_library_mode();
23406f6ba60Sopenharmony_ci    clientConfig.arktsConfig.jsStackReport = hookConfig_.js_stack_report();
23506f6ba60Sopenharmony_ci    clientConfig.printNmd = printMallocNmd_;
23606f6ba60Sopenharmony_ci    clientConfig.nmdType = static_cast<int>(nmdParamInfo_.type);
23706f6ba60Sopenharmony_ci    // -1 is save '\0'
23806f6ba60Sopenharmony_ci    int ret = memcpy_s(clientConfig.arktsConfig.filterNapiName, sizeof(clientConfig.arktsConfig.filterNapiName) - 1,
23906f6ba60Sopenharmony_ci                       hookConfig_.filter_napi_name().c_str(), hookConfig_.filter_napi_name().size());
24006f6ba60Sopenharmony_ci    if (ret != EOK) {
24106f6ba60Sopenharmony_ci        PROFILER_LOG_ERROR(LOG_CORE, "memcpy_s filter_napi_name fail");
24206f6ba60Sopenharmony_ci    }
24306f6ba60Sopenharmony_ci}
24406f6ba60Sopenharmony_ci
24506f6ba60Sopenharmony_cibool HookManager::HandleHookContext(const std::shared_ptr<HookManagerCtx>& ctx)
24606f6ba60Sopenharmony_ci{
24706f6ba60Sopenharmony_ci    if (ctx == nullptr) {
24806f6ba60Sopenharmony_ci        return false;
24906f6ba60Sopenharmony_ci    }
25006f6ba60Sopenharmony_ci    if (ctx->pid > 0) {
25106f6ba60Sopenharmony_ci        ctx->smbName = "hooknativesmb_" + std::to_string(ctx->pid);
25206f6ba60Sopenharmony_ci    } else if (!ctx->processName.empty()) {
25306f6ba60Sopenharmony_ci        ctx->smbName = "hooknativesmb_" + ctx->processName;
25406f6ba60Sopenharmony_ci    } else {
25506f6ba60Sopenharmony_ci        PROFILER_LOG_ERROR(LOG_CORE, "HandleHookContext context error, pid: %d, process name: %s",
25606f6ba60Sopenharmony_ci            ctx->pid, ctx->processName.c_str());
25706f6ba60Sopenharmony_ci        return false;
25806f6ba60Sopenharmony_ci    }
25906f6ba60Sopenharmony_ci    // create smb and eventNotifier
26006f6ba60Sopenharmony_ci    uint32_t bufferSize = static_cast<uint32_t>(hookConfig_.smb_pages()) * PAGE_BYTES; /* bufferConfig.pages() */
26106f6ba60Sopenharmony_ci    ctx->shareMemoryBlock = ShareMemoryAllocator::GetInstance().CreateMemoryBlockLocal(ctx->smbName, bufferSize);
26206f6ba60Sopenharmony_ci    CHECK_TRUE(ctx->shareMemoryBlock != nullptr, false, "CreateMemoryBlockLocal FAIL %s", ctx->smbName.c_str());
26306f6ba60Sopenharmony_ci
26406f6ba60Sopenharmony_ci    ctx->eventNotifier = EventNotifier::Create(0, EventNotifier::NONBLOCK);
26506f6ba60Sopenharmony_ci    CHECK_NOTNULL(ctx->eventNotifier, false, "create EventNotifier for %s failed!", ctx->smbName.c_str());
26606f6ba60Sopenharmony_ci
26706f6ba60Sopenharmony_ci    // start event poller task
26806f6ba60Sopenharmony_ci    ctx->eventPoller = std::make_unique<EpollEventPoller>(DEFAULT_EVENT_POLLING_INTERVAL);
26906f6ba60Sopenharmony_ci    CHECK_NOTNULL(ctx->eventPoller, false, "create event poller FAILED!");
27006f6ba60Sopenharmony_ci
27106f6ba60Sopenharmony_ci    ctx->eventPoller->Init();
27206f6ba60Sopenharmony_ci    ctx->eventPoller->Start();
27306f6ba60Sopenharmony_ci
27406f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "hookservice smbFd = %d, eventFd = %d\n", ctx->shareMemoryBlock->GetfileDescriptor(),
27506f6ba60Sopenharmony_ci                      ctx->eventNotifier->GetFd());
27606f6ba60Sopenharmony_ci
27706f6ba60Sopenharmony_ci    ctx->isRecordAccurately = hookConfig_.record_accurately();
27806f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "hookConfig filter size = %d, malloc disable = %d mmap disable = %d",
27906f6ba60Sopenharmony_ci        hookConfig_.filter_size(), hookConfig_.malloc_disable(), hookConfig_.mmap_disable());
28006f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "hookConfig fp unwind = %d, max stack depth = %d, record_accurately=%d",
28106f6ba60Sopenharmony_ci        hookConfig_.fp_unwind(), hookConfig_.max_stack_depth(), ctx->isRecordAccurately);
28206f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "hookConfig  offline_symbolization = %d", hookConfig_.offline_symbolization());
28306f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "hookConfig  js_stack_report = %d max_js_stack_depth = %u",
28406f6ba60Sopenharmony_ci        hookConfig_.js_stack_report(), hookConfig_.max_js_stack_depth());
28506f6ba60Sopenharmony_ci
28606f6ba60Sopenharmony_ci    clockid_t pluginDataClockId = COMMON::GetClockId(hookConfig_.clock());
28706f6ba60Sopenharmony_ci    if (noDataQueue_) {
28806f6ba60Sopenharmony_ci        ctx->stackPreprocess = std::make_shared<StackPreprocess>(nullptr, hookConfig_, pluginDataClockId,
28906f6ba60Sopenharmony_ci            fpHookData_, isHookStandalone_, isSaService_, isProtobufSerialize_);
29006f6ba60Sopenharmony_ci        ctx->stackPreprocess->SetFlushSize(shareMemorySize_);
29106f6ba60Sopenharmony_ci        ctx->stackPreprocess->SetNmdFd(nmdParamInfo_.fd);
29206f6ba60Sopenharmony_ci        ctx->eventPoller->AddFileDescriptor(
29306f6ba60Sopenharmony_ci            ctx->eventNotifier->GetFd(),
29406f6ba60Sopenharmony_ci            std::bind(&StackPreprocess::TakeResultsFromShmem, ctx->stackPreprocess,
29506f6ba60Sopenharmony_ci            ctx->eventNotifier, ctx->shareMemoryBlock));
29606f6ba60Sopenharmony_ci    } else {
29706f6ba60Sopenharmony_ci        ctx->stackData = std::make_shared<StackDataRepeater>(STACK_DATA_SIZE);
29806f6ba60Sopenharmony_ci        CHECK_TRUE(ctx->stackData != nullptr, false, "Create StackDataRepeater FAIL");
29906f6ba60Sopenharmony_ci        ctx->stackPreprocess = std::make_shared<StackPreprocess>(ctx->stackData, hookConfig_, pluginDataClockId,
30006f6ba60Sopenharmony_ci            fpHookData_, isHookStandalone_, isSaService_, isProtobufSerialize_);
30106f6ba60Sopenharmony_ci        ctx->stackPreprocess->SetFlushSize(shareMemorySize_);
30206f6ba60Sopenharmony_ci        ctx->eventPoller->AddFileDescriptor(
30306f6ba60Sopenharmony_ci            ctx->eventNotifier->GetFd(),
30406f6ba60Sopenharmony_ci            [this, &ctx] { this->ReadShareMemory(ctx); });
30506f6ba60Sopenharmony_ci    }
30606f6ba60Sopenharmony_ci    if (isProtobufSerialize_ || isSaService_) {
30706f6ba60Sopenharmony_ci        ctx->stackPreprocess->SetWriter(g_buffWriter);
30806f6ba60Sopenharmony_ci    } else {
30906f6ba60Sopenharmony_ci        ctx->stackPreprocess->SetWriter(const_cast<WriterStructPtr>(writerAdapter_->GetStruct()));
31006f6ba60Sopenharmony_ci    }
31106f6ba60Sopenharmony_ci    return true;
31206f6ba60Sopenharmony_ci}
31306f6ba60Sopenharmony_ci
31406f6ba60Sopenharmony_civoid HookManager::CheckHapEncryped()
31506f6ba60Sopenharmony_ci{
31606f6ba60Sopenharmony_ci    for (const auto& pid : hookConfig_.expand_pids()) {
31706f6ba60Sopenharmony_ci        if (pid > 0 && COMMON::CheckApplicationEncryped(pid, "")) {
31806f6ba60Sopenharmony_ci            hookConfig_.set_js_stack_report(0);
31906f6ba60Sopenharmony_ci            hookConfig_.set_max_js_stack_depth(0);
32006f6ba60Sopenharmony_ci            break;
32106f6ba60Sopenharmony_ci        }
32206f6ba60Sopenharmony_ci    }
32306f6ba60Sopenharmony_ci    const std::string processName = hookConfig_.process_name();
32406f6ba60Sopenharmony_ci    if (!processName.empty() && COMMON::CheckApplicationEncryped(0, processName)) {
32506f6ba60Sopenharmony_ci        PROFILER_LOG_INFO(LOG_CORE, "Encryped Application don't unwind js stack:%s", processName.c_str());
32606f6ba60Sopenharmony_ci        hookConfig_.set_js_stack_report(0);
32706f6ba60Sopenharmony_ci        hookConfig_.set_max_js_stack_depth(0);
32806f6ba60Sopenharmony_ci    }
32906f6ba60Sopenharmony_ci}
33006f6ba60Sopenharmony_ci
33106f6ba60Sopenharmony_cibool HookManager::CreatePluginSession(const std::vector<ProfilerPluginConfig>& config)
33206f6ba60Sopenharmony_ci{
33306f6ba60Sopenharmony_ci    PROFILER_LOG_DEBUG(LOG_CORE, "CreatePluginSession");
33406f6ba60Sopenharmony_ci    // save config
33506f6ba60Sopenharmony_ci    if (!config.empty()) {
33606f6ba60Sopenharmony_ci        std::string cfgData = config[0].config_data();
33706f6ba60Sopenharmony_ci        if (hookConfig_.ParseFromArray(reinterpret_cast<const uint8_t*>(cfgData.c_str()), cfgData.size()) <= 0) {
33806f6ba60Sopenharmony_ci            PROFILER_LOG_ERROR(LOG_CORE, "%s: ParseFromArray failed", __func__);
33906f6ba60Sopenharmony_ci            return false;
34006f6ba60Sopenharmony_ci        }
34106f6ba60Sopenharmony_ci    }
34206f6ba60Sopenharmony_ci    if ((!saMode_) && (!COMMON::IsBetaVersion())) {
34306f6ba60Sopenharmony_ci        if (!COMMON::CheckApplicationPermission(hookConfig_.pid(), hookConfig_.process_name())) {
34406f6ba60Sopenharmony_ci            return false;
34506f6ba60Sopenharmony_ci        }
34606f6ba60Sopenharmony_ci    }
34706f6ba60Sopenharmony_ci    int32_t uShortMax = (std::numeric_limits<unsigned short>::max)();
34806f6ba60Sopenharmony_ci    if (hookConfig_.filter_size() > uShortMax) {
34906f6ba60Sopenharmony_ci        PROFILER_LOG_WARN(LOG_CORE, "%s: filter size invalid(size exceed 65535), reset to 65535!", __func__);
35006f6ba60Sopenharmony_ci        hookConfig_.set_filter_size(uShortMax);
35106f6ba60Sopenharmony_ci    }
35206f6ba60Sopenharmony_ci    if (!CheckProcess()) { // Check and initialize the context for the target process.
35306f6ba60Sopenharmony_ci        return false;
35406f6ba60Sopenharmony_ci    }
35506f6ba60Sopenharmony_ci    (void)CheckHapEncryped();
35606f6ba60Sopenharmony_ci    if (hookConfig_.max_stack_depth() < DLOPEN_MIN_UNWIND_DEPTH) {
35706f6ba60Sopenharmony_ci        // set default max depth
35806f6ba60Sopenharmony_ci        hookConfig_.set_max_stack_depth(DLOPEN_MIN_UNWIND_DEPTH);
35906f6ba60Sopenharmony_ci    }
36006f6ba60Sopenharmony_ci#if defined(__arm__)
36106f6ba60Sopenharmony_ci    hookConfig_.set_fp_unwind(false); // if OS is 32-bit,set fp_unwind false.
36206f6ba60Sopenharmony_ci    hookConfig_.set_response_library_mode(false);
36306f6ba60Sopenharmony_ci#endif
36406f6ba60Sopenharmony_ci    if (hookConfig_.response_library_mode()) {
36506f6ba60Sopenharmony_ci        hookConfig_.set_fp_unwind(true);
36606f6ba60Sopenharmony_ci        hookConfig_.set_offline_symbolization(true);
36706f6ba60Sopenharmony_ci        hookConfig_.set_js_stack_report(0);
36806f6ba60Sopenharmony_ci    }
36906f6ba60Sopenharmony_ci    // offlinem symbolization, callframe must be compressed
37006f6ba60Sopenharmony_ci    if (hookConfig_.offline_symbolization()) {
37106f6ba60Sopenharmony_ci        hookConfig_.set_callframe_compress(true);
37206f6ba60Sopenharmony_ci    }
37306f6ba60Sopenharmony_ci
37406f6ba60Sopenharmony_ci    // statistical reporting must be callframe compressed and accurate.
37506f6ba60Sopenharmony_ci    if (hookConfig_.statistics_interval() > 0) {
37606f6ba60Sopenharmony_ci        hookConfig_.set_callframe_compress(true);
37706f6ba60Sopenharmony_ci        hookConfig_.set_record_accurately(true);
37806f6ba60Sopenharmony_ci    }
37906f6ba60Sopenharmony_ci
38006f6ba60Sopenharmony_ci    // malloc and free matching interval reporting must be callframe compressed and accurate.
38106f6ba60Sopenharmony_ci    if (hookConfig_.malloc_free_matching_interval() > 0) {
38206f6ba60Sopenharmony_ci        hookConfig_.set_callframe_compress(true);
38306f6ba60Sopenharmony_ci        hookConfig_.set_record_accurately(true);
38406f6ba60Sopenharmony_ci        hookConfig_.set_statistics_interval(0);
38506f6ba60Sopenharmony_ci    }
38606f6ba60Sopenharmony_ci
38706f6ba60Sopenharmony_ci    // callframe compressed, string must be compressed.
38806f6ba60Sopenharmony_ci    if (hookConfig_.callframe_compress()) {
38906f6ba60Sopenharmony_ci        hookConfig_.set_string_compressed(true);
39006f6ba60Sopenharmony_ci    }
39106f6ba60Sopenharmony_ci
39206f6ba60Sopenharmony_ci    if (hookConfig_.js_stack_report() > 0 && hookConfig_.max_js_stack_depth() == 0 && hookConfig_.fp_unwind()) {
39306f6ba60Sopenharmony_ci        hookConfig_.set_max_js_stack_depth(DEFAULT_MAX_JS_STACK_DEPTH);
39406f6ba60Sopenharmony_ci    }
39506f6ba60Sopenharmony_ci
39606f6ba60Sopenharmony_ci    if (hookCtx_.empty()) {
39706f6ba60Sopenharmony_ci        PROFILER_LOG_ERROR(LOG_CORE, "HookManager no task");
39806f6ba60Sopenharmony_ci        return false;
39906f6ba60Sopenharmony_ci    }
40006f6ba60Sopenharmony_ci    if (hookConfig_.save_file() && !hookConfig_.file_name().empty()) {
40106f6ba60Sopenharmony_ci        auto retFile = COMMON::CheckNotExistsFilePath(hookConfig_.file_name());
40206f6ba60Sopenharmony_ci        if (!retFile.first) {
40306f6ba60Sopenharmony_ci            PROFILER_LOG_INFO(LOG_CORE, "check file path %s fail", hookConfig_.file_name().c_str());
40406f6ba60Sopenharmony_ci            return false;
40506f6ba60Sopenharmony_ci        }
40606f6ba60Sopenharmony_ci        fpHookData_ = fopen(retFile.second.c_str(), "wb+");
40706f6ba60Sopenharmony_ci        if (fpHookData_ == nullptr) {
40806f6ba60Sopenharmony_ci            PROFILER_LOG_INFO(LOG_CORE, "fopen file %s fail", hookConfig_.file_name().c_str());
40906f6ba60Sopenharmony_ci            return false;
41006f6ba60Sopenharmony_ci        }
41106f6ba60Sopenharmony_ci    }
41206f6ba60Sopenharmony_ci    if (hookConfig_.fp_unwind() && hookConfig_.record_accurately()
41306f6ba60Sopenharmony_ci        && hookConfig_.blocked() && hookConfig_.offline_symbolization()
41406f6ba60Sopenharmony_ci        && hookConfig_.statistics_interval() > 0
41506f6ba60Sopenharmony_ci        && hookConfig_.sample_interval() > 1
41606f6ba60Sopenharmony_ci        && !hookConfig_.js_stack_report()) {
41706f6ba60Sopenharmony_ci        noDataQueue_ = true;
41806f6ba60Sopenharmony_ci    }
41906f6ba60Sopenharmony_ci
42006f6ba60Sopenharmony_ci    if (!isSaService_) {
42106f6ba60Sopenharmony_ci        CreateWriter();
42206f6ba60Sopenharmony_ci    }
42306f6ba60Sopenharmony_ci
42406f6ba60Sopenharmony_ci    for (const auto& item : hookCtx_) {
42506f6ba60Sopenharmony_ci        CHECK_TRUE(HandleHookContext(item), false, "handle hook context failed"); // Create the required resources.
42606f6ba60Sopenharmony_ci    }
42706f6ba60Sopenharmony_ci
42806f6ba60Sopenharmony_ci    if (!isSaService_) { // SA mode will start HookService in the service.
42906f6ba60Sopenharmony_ci        ClientConfig clientConfig;
43006f6ba60Sopenharmony_ci        GetClientConfig(clientConfig);
43106f6ba60Sopenharmony_ci        if (noDataQueue_) {
43206f6ba60Sopenharmony_ci            clientConfig.freeEventOnlyAddrEnable = true;
43306f6ba60Sopenharmony_ci        }
43406f6ba60Sopenharmony_ci        std::string clientConfigStr = clientConfig.ToString();
43506f6ba60Sopenharmony_ci        PROFILER_LOG_INFO(LOG_CORE, "send hook client config:%s\n", clientConfigStr.c_str());
43606f6ba60Sopenharmony_ci        hookService_ = std::make_shared<HookService>(clientConfig, shared_from_this(), (hookCtx_.size() > 1));
43706f6ba60Sopenharmony_ci        CHECK_NOTNULL(hookService_, false, "HookService create failed!");
43806f6ba60Sopenharmony_ci    }
43906f6ba60Sopenharmony_ci
44006f6ba60Sopenharmony_ci    return true;
44106f6ba60Sopenharmony_ci}
44206f6ba60Sopenharmony_ci
44306f6ba60Sopenharmony_civoid HookManager::HookManagerCtx::FlushStackArray()
44406f6ba60Sopenharmony_ci{
44506f6ba60Sopenharmony_ci    if (rawDataArray.size() > 0 && stackData != nullptr) {
44606f6ba60Sopenharmony_ci        if (!stackData->PutRawStackArray(rawDataArray, rawStackCount)) {
44706f6ba60Sopenharmony_ci            PROFILER_LOG_INFO(LOG_CORE, "PutRawStackArray error");
44806f6ba60Sopenharmony_ci        }
44906f6ba60Sopenharmony_ci        rawStackCount = 0;
45006f6ba60Sopenharmony_ci        rawDataArray = {};
45106f6ba60Sopenharmony_ci    }
45206f6ba60Sopenharmony_ci}
45306f6ba60Sopenharmony_ci
45406f6ba60Sopenharmony_civoid HookManager::FlushRawStackArray(const std::shared_ptr<HookManagerCtx>& hookCtx,
45506f6ba60Sopenharmony_ci                                     std::shared_ptr<StackDataRepeater::RawStack>& rawStack)
45606f6ba60Sopenharmony_ci{
45706f6ba60Sopenharmony_ci    if (hookCtx == nullptr || rawStack == nullptr) {
45806f6ba60Sopenharmony_ci        return;
45906f6ba60Sopenharmony_ci    }
46006f6ba60Sopenharmony_ci    hookCtx->rawDataArray[hookCtx->rawStackCount] = rawStack;
46106f6ba60Sopenharmony_ci    ++hookCtx->rawStackCount;
46206f6ba60Sopenharmony_ci    if (hookCtx->rawStackCount == CACHE_ARRAY_SIZE) {
46306f6ba60Sopenharmony_ci        hookCtx->FlushStackArray();
46406f6ba60Sopenharmony_ci    }
46506f6ba60Sopenharmony_ci}
46606f6ba60Sopenharmony_ci
46706f6ba60Sopenharmony_civoid HookManager::ReadShareMemory(const std::shared_ptr<HookManagerCtx>& hookCtx)
46806f6ba60Sopenharmony_ci{
46906f6ba60Sopenharmony_ci    CHECK_NOTNULL(hookCtx->shareMemoryBlock, NO_RETVAL, "smb is null!");
47006f6ba60Sopenharmony_ci    hookCtx->eventNotifier->Take();
47106f6ba60Sopenharmony_ci    int rawRealSize = 0;
47206f6ba60Sopenharmony_ci    while (true) {
47306f6ba60Sopenharmony_ci        auto rawStack = hookCtx->stackData->GetRawStack();
47406f6ba60Sopenharmony_ci        bool ret = hookCtx->shareMemoryBlock->TakeData([&](const int8_t data[], uint32_t size) -> bool {
47506f6ba60Sopenharmony_ci            if (size == sizeof(uint64_t)) {
47606f6ba60Sopenharmony_ci                if (data) {
47706f6ba60Sopenharmony_ci                    rawStack->freeData = *(reinterpret_cast<uint64_t *>(const_cast<int8_t *>(data)));
47806f6ba60Sopenharmony_ci                }
47906f6ba60Sopenharmony_ci                rawStack->baseStackData = nullptr;
48006f6ba60Sopenharmony_ci                return true;
48106f6ba60Sopenharmony_ci            }
48206f6ba60Sopenharmony_ci            CHECK_TRUE(size >= sizeof(BaseStackRawData), false, "stack data invalid!");
48306f6ba60Sopenharmony_ci
48406f6ba60Sopenharmony_ci            rawStack->baseStackData = std::make_unique<uint8_t[]>(size);
48506f6ba60Sopenharmony_ci            CHECK_TRUE(memcpy_s(rawStack->baseStackData.get(), size, data, size) == EOK, false,
48606f6ba60Sopenharmony_ci                       "memcpy_s raw data failed!");
48706f6ba60Sopenharmony_ci
48806f6ba60Sopenharmony_ci            rawStack->stackConext = reinterpret_cast<BaseStackRawData*>(rawStack->baseStackData.get());
48906f6ba60Sopenharmony_ci
49006f6ba60Sopenharmony_ci            if (rawStack->stackConext->type == NMD_MSG && printMallocNmd_) {
49106f6ba60Sopenharmony_ci                rawStack->data = rawStack->baseStackData.get() + sizeof(BaseStackRawData);
49206f6ba60Sopenharmony_ci                const char* nmdResult = reinterpret_cast<const char*>(rawStack->data);
49306f6ba60Sopenharmony_ci                lseek(nmdParamInfo_.fd, 0, SEEK_END);
49406f6ba60Sopenharmony_ci                (void)write(nmdParamInfo_.fd, nmdResult, strlen(nmdResult));
49506f6ba60Sopenharmony_ci                return true;
49606f6ba60Sopenharmony_ci            } else if (rawStack->stackConext->type == END_MSG) {
49706f6ba60Sopenharmony_ci                return true;
49806f6ba60Sopenharmony_ci            }
49906f6ba60Sopenharmony_ci            rawStack->data = rawStack->baseStackData.get() + sizeof(BaseStackRawData);
50006f6ba60Sopenharmony_ci            rawStack->reportFlag = true;
50106f6ba60Sopenharmony_ci            if (rawStack->stackConext->type == MEMORY_TAG || rawStack->stackConext->type == THREAD_NAME_MSG ||
50206f6ba60Sopenharmony_ci                rawStack->stackConext->type == MMAP_FILE_TYPE || rawStack->stackConext->type == PR_SET_VMA_MSG ||
50306f6ba60Sopenharmony_ci                rawStack->stackConext->type == JS_STACK_MSG) {
50406f6ba60Sopenharmony_ci                return true;
50506f6ba60Sopenharmony_ci            }
50606f6ba60Sopenharmony_ci            rawStack->reduceStackFlag = false;
50706f6ba60Sopenharmony_ci            if (hookConfig_.fp_unwind()) {
50806f6ba60Sopenharmony_ci                rawStack->fpDepth = (size - sizeof(BaseStackRawData)) / sizeof(uint64_t);
50906f6ba60Sopenharmony_ci                if (rawStack->stackConext->jsChainId > 0) {
51006f6ba60Sopenharmony_ci                    rawStack->jsStackData = hookCtx->stackPreprocess->GetJsRawStack(rawStack->stackConext->jsChainId);
51106f6ba60Sopenharmony_ci                }
51206f6ba60Sopenharmony_ci                return true;
51306f6ba60Sopenharmony_ci            } else {
51406f6ba60Sopenharmony_ci                rawRealSize = sizeof(BaseStackRawData) + MAX_REG_SIZE * sizeof(char);
51506f6ba60Sopenharmony_ci            }
51606f6ba60Sopenharmony_ci
51706f6ba60Sopenharmony_ci            rawStack->stackSize = size - rawRealSize;
51806f6ba60Sopenharmony_ci            if (rawStack->stackSize > 0) {
51906f6ba60Sopenharmony_ci                rawStack->stackData = rawStack->baseStackData.get() + rawRealSize;
52006f6ba60Sopenharmony_ci            }
52106f6ba60Sopenharmony_ci            return true;
52206f6ba60Sopenharmony_ci        });
52306f6ba60Sopenharmony_ci        if (!ret) {
52406f6ba60Sopenharmony_ci            break;
52506f6ba60Sopenharmony_ci        }
52606f6ba60Sopenharmony_ci        if (rawStack->baseStackData == nullptr) {
52706f6ba60Sopenharmony_ci            FlushRawStackArray(hookCtx, rawStack);
52806f6ba60Sopenharmony_ci            continue;
52906f6ba60Sopenharmony_ci        }
53006f6ba60Sopenharmony_ci        if (rawStack->stackConext->type == MEMORY_TAG) {
53106f6ba60Sopenharmony_ci            std::string tagName = reinterpret_cast<char*>(rawStack->data);
53206f6ba60Sopenharmony_ci            hookCtx->stackPreprocess->SaveMemTag(rawStack->stackConext->tagId, tagName);
53306f6ba60Sopenharmony_ci            continue;
53406f6ba60Sopenharmony_ci        } else if (rawStack->stackConext->type == JS_STACK_MSG) {
53506f6ba60Sopenharmony_ci            hookCtx->stackPreprocess->SaveJsRawStack(rawStack->stackConext->jsChainId,
53606f6ba60Sopenharmony_ci                                                     reinterpret_cast<char*>(rawStack->data));
53706f6ba60Sopenharmony_ci            continue;
53806f6ba60Sopenharmony_ci        } else if (rawStack->stackConext->type == END_MSG) {
53906f6ba60Sopenharmony_ci            hookCtx->FlushStackArray();
54006f6ba60Sopenharmony_ci            if (!hookCtx->stackData->PutRawStack(rawStack, hookCtx->isRecordAccurately)) {
54106f6ba60Sopenharmony_ci                break;
54206f6ba60Sopenharmony_ci            }
54306f6ba60Sopenharmony_ci            if (!hookCtx->stackData->PutRawStack(nullptr, false)) {
54406f6ba60Sopenharmony_ci                break;
54506f6ba60Sopenharmony_ci            }
54606f6ba60Sopenharmony_ci            continue;
54706f6ba60Sopenharmony_ci        } else if (rawStack->stackConext->type == NMD_MSG) {
54806f6ba60Sopenharmony_ci            continue;
54906f6ba60Sopenharmony_ci        }
55006f6ba60Sopenharmony_ci        FlushRawStackArray(hookCtx, rawStack);
55106f6ba60Sopenharmony_ci    }
55206f6ba60Sopenharmony_ci}
55306f6ba60Sopenharmony_ci
55406f6ba60Sopenharmony_cibool HookManager::DestroyPluginSession(const std::vector<uint32_t>& pluginIds)
55506f6ba60Sopenharmony_ci{
55606f6ba60Sopenharmony_ci    if ((!saMode_) && (!COMMON::IsBetaVersion())) {
55706f6ba60Sopenharmony_ci        if (!COMMON::CheckApplicationPermission(hookConfig_.pid(), hookConfig_.process_name())) {
55806f6ba60Sopenharmony_ci            return false;
55906f6ba60Sopenharmony_ci        }
56006f6ba60Sopenharmony_ci    }
56106f6ba60Sopenharmony_ci    for (const auto& item : hookCtx_) {
56206f6ba60Sopenharmony_ci        if (item->eventPoller != nullptr) {
56306f6ba60Sopenharmony_ci            PROFILER_LOG_ERROR(LOG_CORE, "eventPoller unset!");
56406f6ba60Sopenharmony_ci            if (item->eventNotifier != nullptr) {
56506f6ba60Sopenharmony_ci                item->eventPoller->RemoveFileDescriptor(item->eventNotifier->GetFd());
56606f6ba60Sopenharmony_ci            }
56706f6ba60Sopenharmony_ci            item->eventPoller->Stop();
56806f6ba60Sopenharmony_ci            item->eventPoller->Finalize();
56906f6ba60Sopenharmony_ci        }
57006f6ba60Sopenharmony_ci        if (item->shareMemoryBlock != nullptr) {
57106f6ba60Sopenharmony_ci            ShareMemoryAllocator::GetInstance().ReleaseMemoryBlockLocal(item->smbName);
57206f6ba60Sopenharmony_ci        }
57306f6ba60Sopenharmony_ci        if (item->stackData != nullptr) {
57406f6ba60Sopenharmony_ci            item->stackData->ClearCache();
57506f6ba60Sopenharmony_ci        }
57606f6ba60Sopenharmony_ci    }
57706f6ba60Sopenharmony_ci    if (fpHookData_) {
57806f6ba60Sopenharmony_ci        fclose(fpHookData_);
57906f6ba60Sopenharmony_ci        fpHookData_ = nullptr;
58006f6ba60Sopenharmony_ci    }
58106f6ba60Sopenharmony_ci    return true;
58206f6ba60Sopenharmony_ci}
58306f6ba60Sopenharmony_ci
58406f6ba60Sopenharmony_cibool HookManager::StartPluginSession(const std::vector<uint32_t>& pluginIds,
58506f6ba60Sopenharmony_ci                                     const std::vector<ProfilerPluginConfig>& config, PluginResult& result)
58606f6ba60Sopenharmony_ci{
58706f6ba60Sopenharmony_ci    UNUSED_PARAMETER(config);
58806f6ba60Sopenharmony_ci    if (hookCtx_.empty()) {
58906f6ba60Sopenharmony_ci        return false;
59006f6ba60Sopenharmony_ci    }
59106f6ba60Sopenharmony_ci    if ((!saMode_) && (!COMMON::IsBetaVersion())) {
59206f6ba60Sopenharmony_ci        if (!COMMON::CheckApplicationPermission(hookConfig_.pid(), hookConfig_.process_name())) {
59306f6ba60Sopenharmony_ci            return false;
59406f6ba60Sopenharmony_ci        }
59506f6ba60Sopenharmony_ci    }
59606f6ba60Sopenharmony_ci    StartPluginSession();
59706f6ba60Sopenharmony_ci    return true;
59806f6ba60Sopenharmony_ci}
59906f6ba60Sopenharmony_ci
60006f6ba60Sopenharmony_cibool HookManager::StopPluginSession(const std::vector<uint32_t>& pluginIds)
60106f6ba60Sopenharmony_ci{
60206f6ba60Sopenharmony_ci    if (hookCtx_.empty()) {
60306f6ba60Sopenharmony_ci        return false;
60406f6ba60Sopenharmony_ci    }
60506f6ba60Sopenharmony_ci    if ((!saMode_) && (!COMMON::IsBetaVersion())) {
60606f6ba60Sopenharmony_ci        if (!COMMON::CheckApplicationPermission(hookConfig_.pid(), hookConfig_.process_name())) {
60706f6ba60Sopenharmony_ci            return false;
60806f6ba60Sopenharmony_ci        }
60906f6ba60Sopenharmony_ci    }
61006f6ba60Sopenharmony_ci    for (const auto& item : hookCtx_) {
61106f6ba60Sopenharmony_ci        if (item->pid > 0) {
61206f6ba60Sopenharmony_ci            PROFILER_LOG_INFO(LOG_CORE, "stop command : send 37 signal to process  %d", item->pid);
61306f6ba60Sopenharmony_ci            if (kill(item->pid, SIGNAL_STOP_HOOK) == -1) {
61406f6ba60Sopenharmony_ci                const int bufSize = 256;
61506f6ba60Sopenharmony_ci                char buf[bufSize] = {0};
61606f6ba60Sopenharmony_ci                strerror_r(errno, buf, bufSize);
61706f6ba60Sopenharmony_ci                PROFILER_LOG_ERROR(LOG_CORE, "send 37 signal to process %d , error = %s", item->pid, buf);
61806f6ba60Sopenharmony_ci            }
61906f6ba60Sopenharmony_ci        } else {
62006f6ba60Sopenharmony_ci            PROFILER_LOG_INFO(LOG_CORE, "StopPluginSession: pid(%d) is less or equal zero.", item->pid);
62106f6ba60Sopenharmony_ci        }
62206f6ba60Sopenharmony_ci        CHECK_TRUE(item->stackPreprocess != nullptr, false, "stop StackPreprocess FAIL");
62306f6ba60Sopenharmony_ci        item->stackPreprocess->StopTakeResults();
62406f6ba60Sopenharmony_ci        PROFILER_LOG_INFO(LOG_CORE, "StopTakeResults success");
62506f6ba60Sopenharmony_ci        if (hookConfig_.statistics_interval() > 0) {
62606f6ba60Sopenharmony_ci            item->stackPreprocess->FlushRecordStatistics();
62706f6ba60Sopenharmony_ci        }
62806f6ba60Sopenharmony_ci        if (hookConfig_.malloc_free_matching_interval() > 0) {
62906f6ba60Sopenharmony_ci            item->stackPreprocess->FlushRecordApplyAndReleaseMatchData();
63006f6ba60Sopenharmony_ci        }
63106f6ba60Sopenharmony_ci        if (item->stackData != nullptr) {
63206f6ba60Sopenharmony_ci            item->stackData->Close();
63306f6ba60Sopenharmony_ci        }
63406f6ba60Sopenharmony_ci        item->stackPreprocess->FinishTraceFile();
63506f6ba60Sopenharmony_ci    }
63606f6ba60Sopenharmony_ci    return true;
63706f6ba60Sopenharmony_ci}
63806f6ba60Sopenharmony_ci
63906f6ba60Sopenharmony_civoid HookManager::ResetStartupParam()
64006f6ba60Sopenharmony_ci{
64106f6ba60Sopenharmony_ci    const std::string resetParam = "startup:disabled";
64206f6ba60Sopenharmony_ci    if (hookConfig_.startup_mode()) {
64306f6ba60Sopenharmony_ci        int ret = SystemSetParameter(PARAM_NAME.c_str(), resetParam.c_str());
64406f6ba60Sopenharmony_ci        if (ret < 0) {
64506f6ba60Sopenharmony_ci            PROFILER_LOG_WARN(LOG_CORE, "set param failed, please reset param(%s)", PARAM_NAME.c_str());
64606f6ba60Sopenharmony_ci        } else {
64706f6ba60Sopenharmony_ci            PROFILER_LOG_INFO(LOG_CORE, "reset param success");
64806f6ba60Sopenharmony_ci        }
64906f6ba60Sopenharmony_ci    }
65006f6ba60Sopenharmony_ci}
65106f6ba60Sopenharmony_ci
65206f6ba60Sopenharmony_cibool HookManager::ReportPluginBasicData(const std::vector<uint32_t>& pluginIds)
65306f6ba60Sopenharmony_ci{
65406f6ba60Sopenharmony_ci    return true;
65506f6ba60Sopenharmony_ci}
65606f6ba60Sopenharmony_ci
65706f6ba60Sopenharmony_cibool HookManager::CreateWriter(std::string pluginName, uint32_t bufferSize, int smbFd, int eventFd,
65806f6ba60Sopenharmony_ci                               bool isProtobufSerialize)
65906f6ba60Sopenharmony_ci{
66006f6ba60Sopenharmony_ci    PROFILER_LOG_DEBUG(LOG_CORE, "agentIndex_ %d", agentIndex_);
66106f6ba60Sopenharmony_ci    writer_ = std::make_shared<BufferWriter>(pluginName, VERSION, bufferSize, smbFd, eventFd, agentIndex_);
66206f6ba60Sopenharmony_ci    isProtobufSerialize_ = isProtobufSerialize;
66306f6ba60Sopenharmony_ci    shareMemorySize_ = bufferSize;
66406f6ba60Sopenharmony_ci    return true;
66506f6ba60Sopenharmony_ci}
66606f6ba60Sopenharmony_ci
66706f6ba60Sopenharmony_civoid HookManager::CreateWriter()
66806f6ba60Sopenharmony_ci{
66906f6ba60Sopenharmony_ci    PROFILER_LOG_INFO(LOG_CORE, "CreateWriter isProtobufSerialize: %d, noDataQueue_: %d",
67006f6ba60Sopenharmony_ci                      isProtobufSerialize_, noDataQueue_);
67106f6ba60Sopenharmony_ci    if (isProtobufSerialize_) {
67206f6ba60Sopenharmony_ci        RegisterWriter(writer_);
67306f6ba60Sopenharmony_ci    } else {
67406f6ba60Sopenharmony_ci        writerAdapter_ = std::make_shared<WriterAdapter>(isProtobufSerialize_);
67506f6ba60Sopenharmony_ci        writerAdapter_->SetWriter(writer_);
67606f6ba60Sopenharmony_ci    }
67706f6ba60Sopenharmony_ci}
67806f6ba60Sopenharmony_ci
67906f6ba60Sopenharmony_cibool HookManager::ResetWriter(uint32_t pluginId)
68006f6ba60Sopenharmony_ci{
68106f6ba60Sopenharmony_ci    RegisterWriter(nullptr);
68206f6ba60Sopenharmony_ci    return true;
68306f6ba60Sopenharmony_ci}
68406f6ba60Sopenharmony_ci
68506f6ba60Sopenharmony_civoid HookManager::RegisterWriter(const std::shared_ptr<Writer> writer)
68606f6ba60Sopenharmony_ci{
68706f6ba60Sopenharmony_ci    g_buffWriter = writer;
68806f6ba60Sopenharmony_ci    return;
68906f6ba60Sopenharmony_ci}
69006f6ba60Sopenharmony_ci
69106f6ba60Sopenharmony_civoid HookManager::SetHookConfig(const NativeHookConfig& hookConfig)
69206f6ba60Sopenharmony_ci{
69306f6ba60Sopenharmony_ci    hookConfig_ = hookConfig;
69406f6ba60Sopenharmony_ci}
69506f6ba60Sopenharmony_ci
69606f6ba60Sopenharmony_civoid HookManager::SethookStandalone(bool HookStandalone)
69706f6ba60Sopenharmony_ci{
69806f6ba60Sopenharmony_ci    isHookStandalone_ = HookStandalone;
69906f6ba60Sopenharmony_ci}
70006f6ba60Sopenharmony_ci
70106f6ba60Sopenharmony_civoid HookManager::SetHookConfig(const std::shared_ptr<NativeMemoryProfilerSaConfig>& config)
70206f6ba60Sopenharmony_ci{
70306f6ba60Sopenharmony_ci    hookConfig_.set_pid(config->pid_);
70406f6ba60Sopenharmony_ci    if (!config->processName_.empty()) {
70506f6ba60Sopenharmony_ci        hookConfig_.set_process_name(config->processName_);
70606f6ba60Sopenharmony_ci    }
70706f6ba60Sopenharmony_ci    hookConfig_.set_filter_size(config->filterSize_);
70806f6ba60Sopenharmony_ci    hookConfig_.set_smb_pages(config->shareMemorySize_);
70906f6ba60Sopenharmony_ci    hookConfig_.set_max_stack_depth(config->maxStackDepth_);
71006f6ba60Sopenharmony_ci    hookConfig_.set_malloc_disable(config->mallocDisable_);
71106f6ba60Sopenharmony_ci    hookConfig_.set_mmap_disable(config->mmapDisable_);
71206f6ba60Sopenharmony_ci    hookConfig_.set_free_stack_report(config->freeStackData_);
71306f6ba60Sopenharmony_ci    hookConfig_.set_munmap_stack_report(config->munmapStackData_);
71406f6ba60Sopenharmony_ci    hookConfig_.set_malloc_free_matching_interval(config->mallocFreeMatchingInterval_);
71506f6ba60Sopenharmony_ci    hookConfig_.set_malloc_free_matching_cnt(config->mallocFreeMatchingCnt_);
71606f6ba60Sopenharmony_ci    hookConfig_.set_string_compressed(config->stringCompressed_);
71706f6ba60Sopenharmony_ci    hookConfig_.set_fp_unwind(config->fpUnwind_);
71806f6ba60Sopenharmony_ci    hookConfig_.set_blocked(config->blocked_);
71906f6ba60Sopenharmony_ci    hookConfig_.set_record_accurately(config->recordAccurately_);
72006f6ba60Sopenharmony_ci    hookConfig_.set_startup_mode(config->startupMode_);
72106f6ba60Sopenharmony_ci    hookConfig_.set_memtrace_enable(config->memtraceEnable_);
72206f6ba60Sopenharmony_ci    hookConfig_.set_offline_symbolization(config->offlineSymbolization_);
72306f6ba60Sopenharmony_ci    hookConfig_.set_callframe_compress(config->callframeCompress_);
72406f6ba60Sopenharmony_ci    hookConfig_.set_statistics_interval(config->statisticsInterval_);
72506f6ba60Sopenharmony_ci    hookConfig_.set_clock(COMMON::GetClockStr(config->clockId_));
72606f6ba60Sopenharmony_ci    hookConfig_.set_sample_interval(config->sampleInterval_);
72706f6ba60Sopenharmony_ci    hookConfig_.set_response_library_mode(config->responseLibraryMode_);
72806f6ba60Sopenharmony_ci    hookConfig_.set_js_stack_report(config->jsStackReport_);
72906f6ba60Sopenharmony_ci    hookConfig_.set_max_js_stack_depth(config->maxJsStackDepth_);
73006f6ba60Sopenharmony_ci    hookConfig_.set_filter_napi_name(config->filterNapiName_);
73106f6ba60Sopenharmony_ci    printMallocNmd_ = config->printNmd_;
73206f6ba60Sopenharmony_ci}
73306f6ba60Sopenharmony_ci
73406f6ba60Sopenharmony_ciint32_t HookManager::CreatePluginSession()
73506f6ba60Sopenharmony_ci{
73606f6ba60Sopenharmony_ci    if (CreatePluginSession({})) {
73706f6ba60Sopenharmony_ci        return RET_OK;
73806f6ba60Sopenharmony_ci    }
73906f6ba60Sopenharmony_ci    return RET_ERR;
74006f6ba60Sopenharmony_ci}
74106f6ba60Sopenharmony_ci
74206f6ba60Sopenharmony_civoid HookManager::StartPluginSession()
74306f6ba60Sopenharmony_ci{
74406f6ba60Sopenharmony_ci    for (const auto& item : hookCtx_) {
74506f6ba60Sopenharmony_ci        if (item->stackPreprocess == nullptr) {
74606f6ba60Sopenharmony_ci            continue;
74706f6ba60Sopenharmony_ci        }
74806f6ba60Sopenharmony_ci        PROFILER_LOG_ERROR(LOG_CORE, "StartPluginSession name: %s", item->processName.c_str());
74906f6ba60Sopenharmony_ci        if (!noDataQueue_) {
75006f6ba60Sopenharmony_ci            item->stackPreprocess->StartTakeResults();
75106f6ba60Sopenharmony_ci        }
75206f6ba60Sopenharmony_ci        item->stackPreprocess->InitStatisticsTime();
75306f6ba60Sopenharmony_ci        if (item->pid > 0) {
75406f6ba60Sopenharmony_ci            PROFILER_LOG_INFO(LOG_CORE, "start command : send 36 signal to process  %d", item->pid);
75506f6ba60Sopenharmony_ci            if (kill(item->pid, SIGNAL_START_HOOK) == -1) {
75606f6ba60Sopenharmony_ci                const int bufSize = 256;
75706f6ba60Sopenharmony_ci                char buf[bufSize] = {0};
75806f6ba60Sopenharmony_ci                strerror_r(errno, buf, bufSize);
75906f6ba60Sopenharmony_ci                PROFILER_LOG_ERROR(LOG_CORE, "send 36 signal error = %s", buf);
76006f6ba60Sopenharmony_ci            }
76106f6ba60Sopenharmony_ci        } else {
76206f6ba60Sopenharmony_ci            PROFILER_LOG_INFO(LOG_CORE, "StartPluginSession: pid(%d) is less or equal zero.", item->pid);
76306f6ba60Sopenharmony_ci        }
76406f6ba60Sopenharmony_ci    }
76506f6ba60Sopenharmony_ci}
76606f6ba60Sopenharmony_ci
76706f6ba60Sopenharmony_civoid HookManager::WriteHookConfig()
76806f6ba60Sopenharmony_ci{
76906f6ba60Sopenharmony_ci    for (const auto& item : hookCtx_) {
77006f6ba60Sopenharmony_ci        if (item == nullptr) {
77106f6ba60Sopenharmony_ci            PROFILER_LOG_ERROR(LOG_CORE, "HookManager WriteHookConfig failed");
77206f6ba60Sopenharmony_ci            return;
77306f6ba60Sopenharmony_ci        }
77406f6ba60Sopenharmony_ci        item->stackPreprocess->WriteHookConfig();
77506f6ba60Sopenharmony_ci    }
77606f6ba60Sopenharmony_ci}
77706f6ba60Sopenharmony_ci
77806f6ba60Sopenharmony_cistd::pair<int, int> HookManager::GetFds(int32_t pid, const std::string& name)
77906f6ba60Sopenharmony_ci{
78006f6ba60Sopenharmony_ci    for (const auto& item : hookCtx_) {
78106f6ba60Sopenharmony_ci        if (item->pid == pid || item->processName == name) {
78206f6ba60Sopenharmony_ci            if (item->pid == -1) {
78306f6ba60Sopenharmony_ci                item->pid = pid;
78406f6ba60Sopenharmony_ci            }
78506f6ba60Sopenharmony_ci            item->stackPreprocess->SetPid(pid);
78606f6ba60Sopenharmony_ci            return {item->eventNotifier->GetFd(), item->shareMemoryBlock->GetfileDescriptor()};
78706f6ba60Sopenharmony_ci        }
78806f6ba60Sopenharmony_ci    }
78906f6ba60Sopenharmony_ci    return {-1, -1};
79006f6ba60Sopenharmony_ci}
79106f6ba60Sopenharmony_ci
79206f6ba60Sopenharmony_civoid HookManager::SetNmdInfo(std::pair<uint32_t, uint32_t> info)
79306f6ba60Sopenharmony_ci{
79406f6ba60Sopenharmony_ci    printMallocNmd_ = true;
79506f6ba60Sopenharmony_ci    nmdParamInfo_.fd = info.first;
79606f6ba60Sopenharmony_ci    nmdParamInfo_.type = info.second;
79706f6ba60Sopenharmony_ci}
79806f6ba60Sopenharmony_ci}