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}