1e509ee18Sopenharmony_ci/* 2e509ee18Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3e509ee18Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e509ee18Sopenharmony_ci * you may not use this file except in compliance with the License. 5e509ee18Sopenharmony_ci * You may obtain a copy of the License at 6e509ee18Sopenharmony_ci * 7e509ee18Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e509ee18Sopenharmony_ci * 9e509ee18Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e509ee18Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e509ee18Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e509ee18Sopenharmony_ci * See the License for the specific language governing permissions and 13e509ee18Sopenharmony_ci * limitations under the License. 14e509ee18Sopenharmony_ci */ 15e509ee18Sopenharmony_ci 16e509ee18Sopenharmony_ci#include "inspector.h" 17e509ee18Sopenharmony_ci 18e509ee18Sopenharmony_ci#include <chrono> 19e509ee18Sopenharmony_ci#include <shared_mutex> 20e509ee18Sopenharmony_ci#if defined(OHOS_PLATFORM) 21e509ee18Sopenharmony_ci#include <syscall.h> 22e509ee18Sopenharmony_ci#endif 23e509ee18Sopenharmony_ci#include <thread> 24e509ee18Sopenharmony_ci#if defined(OHOS_PLATFORM) 25e509ee18Sopenharmony_ci#include <unistd.h> 26e509ee18Sopenharmony_ci#endif 27e509ee18Sopenharmony_ci#include <unordered_map> 28e509ee18Sopenharmony_ci 29e509ee18Sopenharmony_ci#include "common/log_wrapper.h" 30e509ee18Sopenharmony_ci#include "library_loader.h" 31e509ee18Sopenharmony_ci 32e509ee18Sopenharmony_ci#if defined(IOS_PLATFORM) 33e509ee18Sopenharmony_ci#include "tooling/debugger_service.h" 34e509ee18Sopenharmony_ci#endif 35e509ee18Sopenharmony_ci 36e509ee18Sopenharmony_ci#if defined(ENABLE_FFRT_INTERFACES) 37e509ee18Sopenharmony_ci#include "ffrt.h" 38e509ee18Sopenharmony_ci#endif 39e509ee18Sopenharmony_ci 40e509ee18Sopenharmony_cinamespace OHOS::ArkCompiler::Toolchain { 41e509ee18Sopenharmony_cinamespace { 42e509ee18Sopenharmony_cienum DispatchStatus : int32_t { 43e509ee18Sopenharmony_ci UNKNOWN = 0, 44e509ee18Sopenharmony_ci DISPATCHING, 45e509ee18Sopenharmony_ci DISPATCHED 46e509ee18Sopenharmony_ci}; 47e509ee18Sopenharmony_ci 48e509ee18Sopenharmony_ciusing InitializeDebugger = void(*)(void*, const std::function<void(const void*, const std::string&)>&); 49e509ee18Sopenharmony_ciusing UninitializeDebugger = void(*)(void*); 50e509ee18Sopenharmony_ciusing WaitForDebugger = void(*)(void*); 51e509ee18Sopenharmony_ciusing OnMessage = void(*)(void*, std::string&&); 52e509ee18Sopenharmony_ciusing ProcessMessage = void(*)(void*); 53e509ee18Sopenharmony_ciusing GetDispatchStatus = int32_t(*)(void*); 54e509ee18Sopenharmony_ci 55e509ee18Sopenharmony_ciOnMessage g_onMessage = nullptr; 56e509ee18Sopenharmony_ciInitializeDebugger g_initializeDebugger = nullptr; 57e509ee18Sopenharmony_ciUninitializeDebugger g_uninitializeDebugger = nullptr; 58e509ee18Sopenharmony_ciWaitForDebugger g_waitForDebugger = nullptr; 59e509ee18Sopenharmony_ciProcessMessage g_processMessage = nullptr; 60e509ee18Sopenharmony_ciGetDispatchStatus g_getDispatchStatus = nullptr; 61e509ee18Sopenharmony_ci 62e509ee18Sopenharmony_cistd::atomic<bool> g_hasArkFuncsInited = false; 63e509ee18Sopenharmony_cistd::unordered_map<const void*, Inspector*> g_inspectors; 64e509ee18Sopenharmony_cistd::unordered_map<int, std::pair<void*, const DebuggerPostTask>> g_debuggerInfo; 65e509ee18Sopenharmony_cistd::shared_mutex g_mutex; 66e509ee18Sopenharmony_ci 67e509ee18Sopenharmony_ci#if !defined(IOS_PLATFORM) 68e509ee18Sopenharmony_cithread_local void* g_handle = nullptr; 69e509ee18Sopenharmony_ci#endif 70e509ee18Sopenharmony_cithread_local void* g_vm = nullptr; 71e509ee18Sopenharmony_ci 72e509ee18Sopenharmony_ci#if !defined(IOS_PLATFORM) 73e509ee18Sopenharmony_ci#if defined(WINDOWS_PLATFORM) 74e509ee18Sopenharmony_ciconstexpr char ARK_DEBUGGER_SHARED_LIB[] = "libark_tooling.dll"; 75e509ee18Sopenharmony_ci#elif defined(MAC_PLATFORM) 76e509ee18Sopenharmony_ciconstexpr char ARK_DEBUGGER_SHARED_LIB[] = "libark_tooling.dylib"; 77e509ee18Sopenharmony_ci#else 78e509ee18Sopenharmony_ciconstexpr char ARK_DEBUGGER_SHARED_LIB[] = "libark_tooling.so"; 79e509ee18Sopenharmony_ci#endif 80e509ee18Sopenharmony_ci#endif 81e509ee18Sopenharmony_ci 82e509ee18Sopenharmony_civoid* HandleClient(void* const server) 83e509ee18Sopenharmony_ci{ 84e509ee18Sopenharmony_ci LOGI("HandleClient"); 85e509ee18Sopenharmony_ci if (server == nullptr) { 86e509ee18Sopenharmony_ci LOGE("HandleClient server nullptr"); 87e509ee18Sopenharmony_ci return nullptr; 88e509ee18Sopenharmony_ci } 89e509ee18Sopenharmony_ci 90e509ee18Sopenharmony_ci#if defined(IOS_PLATFORM) || defined(MAC_PLATFORM) 91e509ee18Sopenharmony_ci pthread_setname_np("OS_DebugThread"); 92e509ee18Sopenharmony_ci#else 93e509ee18Sopenharmony_ci pthread_setname_np(pthread_self(), "OS_DebugThread"); 94e509ee18Sopenharmony_ci#endif 95e509ee18Sopenharmony_ci 96e509ee18Sopenharmony_ci static_cast<WsServer*>(server)->RunServer(); 97e509ee18Sopenharmony_ci return nullptr; 98e509ee18Sopenharmony_ci} 99e509ee18Sopenharmony_ci 100e509ee18Sopenharmony_ci#if !defined(IOS_PLATFORM) 101e509ee18Sopenharmony_cibool LoadArkDebuggerLibrary() 102e509ee18Sopenharmony_ci{ 103e509ee18Sopenharmony_ci if (g_handle != nullptr) { 104e509ee18Sopenharmony_ci LOGI("LoadArkDebuggerLibrary, handle has already loaded"); 105e509ee18Sopenharmony_ci return true; 106e509ee18Sopenharmony_ci } 107e509ee18Sopenharmony_ci g_handle = Load(ARK_DEBUGGER_SHARED_LIB); 108e509ee18Sopenharmony_ci if (g_handle == nullptr) { 109e509ee18Sopenharmony_ci LOGE("LoadArkDebuggerLibrary, handle load failed"); 110e509ee18Sopenharmony_ci return false; 111e509ee18Sopenharmony_ci } 112e509ee18Sopenharmony_ci return true; 113e509ee18Sopenharmony_ci} 114e509ee18Sopenharmony_ci 115e509ee18Sopenharmony_civoid* GetArkDynFunction(const char* symbol) 116e509ee18Sopenharmony_ci{ 117e509ee18Sopenharmony_ci return ResolveSymbol(g_handle, symbol); 118e509ee18Sopenharmony_ci} 119e509ee18Sopenharmony_ci#endif 120e509ee18Sopenharmony_ci 121e509ee18Sopenharmony_civoid SendReply(const void* vm, const std::string& message) 122e509ee18Sopenharmony_ci{ 123e509ee18Sopenharmony_ci std::shared_lock<std::shared_mutex> lock(g_mutex); 124e509ee18Sopenharmony_ci auto iter = g_inspectors.find(vm); 125e509ee18Sopenharmony_ci if (iter != g_inspectors.end() && iter->second != nullptr && 126e509ee18Sopenharmony_ci iter->second->websocketServer_ != nullptr) { 127e509ee18Sopenharmony_ci iter->second->websocketServer_->SendReply(message); 128e509ee18Sopenharmony_ci } 129e509ee18Sopenharmony_ci} 130e509ee18Sopenharmony_ci 131e509ee18Sopenharmony_civoid ResetServiceLocked(void *vm, bool isCloseHandle) 132e509ee18Sopenharmony_ci{ 133e509ee18Sopenharmony_ci auto iter = g_inspectors.find(vm); 134e509ee18Sopenharmony_ci if (iter != g_inspectors.end() && iter->second != nullptr && 135e509ee18Sopenharmony_ci iter->second->websocketServer_ != nullptr) { 136e509ee18Sopenharmony_ci iter->second->websocketServer_->StopServer(); 137e509ee18Sopenharmony_ci delete iter->second; 138e509ee18Sopenharmony_ci iter->second = nullptr; 139e509ee18Sopenharmony_ci g_inspectors.erase(iter); 140e509ee18Sopenharmony_ci } 141e509ee18Sopenharmony_ci#if !defined(IOS_PLATFORM) 142e509ee18Sopenharmony_ci if (g_handle != nullptr && isCloseHandle) { 143e509ee18Sopenharmony_ci CloseHandle(g_handle); 144e509ee18Sopenharmony_ci g_handle = nullptr; 145e509ee18Sopenharmony_ci } 146e509ee18Sopenharmony_ci#endif 147e509ee18Sopenharmony_ci} 148e509ee18Sopenharmony_ci 149e509ee18Sopenharmony_cibool InitializeInspector( 150e509ee18Sopenharmony_ci void* vm, const DebuggerPostTask& debuggerPostTask, const DebugInfo& debugInfo, int tidForSocketPair = 0) 151e509ee18Sopenharmony_ci{ 152e509ee18Sopenharmony_ci std::unique_lock<std::shared_mutex> lock(g_mutex); 153e509ee18Sopenharmony_ci auto iter = g_inspectors.find(vm); 154e509ee18Sopenharmony_ci if (iter != g_inspectors.end()) { 155e509ee18Sopenharmony_ci LOGW("Inspector already exist!"); 156e509ee18Sopenharmony_ci return true; 157e509ee18Sopenharmony_ci } 158e509ee18Sopenharmony_ci 159e509ee18Sopenharmony_ci Inspector *newInspector = new Inspector(); 160e509ee18Sopenharmony_ci g_inspectors.emplace(vm, newInspector); 161e509ee18Sopenharmony_ci 162e509ee18Sopenharmony_ci newInspector->tidForSocketPair_ = tidForSocketPair; 163e509ee18Sopenharmony_ci newInspector->tid_ = pthread_self(); 164e509ee18Sopenharmony_ci newInspector->vm_ = vm; 165e509ee18Sopenharmony_ci newInspector->debuggerPostTask_ = debuggerPostTask; 166e509ee18Sopenharmony_ci newInspector->websocketServer_ = std::make_unique<WsServer>(debugInfo, 167e509ee18Sopenharmony_ci std::bind(&Inspector::OnMessage, newInspector, std::placeholders::_1)); 168e509ee18Sopenharmony_ci 169e509ee18Sopenharmony_ci pthread_t tid; 170e509ee18Sopenharmony_ci if (pthread_create(&tid, nullptr, &HandleClient, static_cast<void *>( 171e509ee18Sopenharmony_ci newInspector->websocketServer_.get())) != 0) { 172e509ee18Sopenharmony_ci LOGE("Create inspector thread failed"); 173e509ee18Sopenharmony_ci return false; 174e509ee18Sopenharmony_ci } 175e509ee18Sopenharmony_ci newInspector->websocketServer_->tid_ = tid; 176e509ee18Sopenharmony_ci 177e509ee18Sopenharmony_ci return true; 178e509ee18Sopenharmony_ci} 179e509ee18Sopenharmony_ci 180e509ee18Sopenharmony_ci#if !defined(IOS_PLATFORM) 181e509ee18Sopenharmony_cibool InitializeArkFunctionsOthers() 182e509ee18Sopenharmony_ci{ 183e509ee18Sopenharmony_ci g_initializeDebugger = reinterpret_cast<InitializeDebugger>( 184e509ee18Sopenharmony_ci GetArkDynFunction("InitializeDebugger")); 185e509ee18Sopenharmony_ci if (g_initializeDebugger == nullptr) { 186e509ee18Sopenharmony_ci ResetServiceLocked(g_vm, true); 187e509ee18Sopenharmony_ci return false; 188e509ee18Sopenharmony_ci } 189e509ee18Sopenharmony_ci g_uninitializeDebugger = reinterpret_cast<UninitializeDebugger>( 190e509ee18Sopenharmony_ci GetArkDynFunction("UninitializeDebugger")); 191e509ee18Sopenharmony_ci if (g_uninitializeDebugger == nullptr) { 192e509ee18Sopenharmony_ci ResetServiceLocked(g_vm, true); 193e509ee18Sopenharmony_ci return false; 194e509ee18Sopenharmony_ci } 195e509ee18Sopenharmony_ci g_waitForDebugger = reinterpret_cast<WaitForDebugger>( 196e509ee18Sopenharmony_ci GetArkDynFunction("WaitForDebugger")); 197e509ee18Sopenharmony_ci if (g_waitForDebugger == nullptr) { 198e509ee18Sopenharmony_ci ResetServiceLocked(g_vm, true); 199e509ee18Sopenharmony_ci return false; 200e509ee18Sopenharmony_ci } 201e509ee18Sopenharmony_ci g_onMessage = reinterpret_cast<OnMessage>( 202e509ee18Sopenharmony_ci GetArkDynFunction("OnMessage")); 203e509ee18Sopenharmony_ci if (g_onMessage == nullptr) { 204e509ee18Sopenharmony_ci ResetServiceLocked(g_vm, true); 205e509ee18Sopenharmony_ci return false; 206e509ee18Sopenharmony_ci } 207e509ee18Sopenharmony_ci g_getDispatchStatus = reinterpret_cast<GetDispatchStatus>( 208e509ee18Sopenharmony_ci GetArkDynFunction("GetDispatchStatus")); 209e509ee18Sopenharmony_ci if (g_getDispatchStatus == nullptr) { 210e509ee18Sopenharmony_ci ResetServiceLocked(g_vm, true); 211e509ee18Sopenharmony_ci return false; 212e509ee18Sopenharmony_ci } 213e509ee18Sopenharmony_ci g_processMessage = reinterpret_cast<ProcessMessage>( 214e509ee18Sopenharmony_ci GetArkDynFunction("ProcessMessage")); 215e509ee18Sopenharmony_ci if (g_processMessage == nullptr) { 216e509ee18Sopenharmony_ci ResetServiceLocked(g_vm, true); 217e509ee18Sopenharmony_ci return false; 218e509ee18Sopenharmony_ci } 219e509ee18Sopenharmony_ci return true; 220e509ee18Sopenharmony_ci} 221e509ee18Sopenharmony_ci#else 222e509ee18Sopenharmony_cibool InitializeArkFunctionsIOS() 223e509ee18Sopenharmony_ci{ 224e509ee18Sopenharmony_ci using namespace panda::ecmascript; 225e509ee18Sopenharmony_ci g_initializeDebugger = reinterpret_cast<InitializeDebugger>(&tooling::InitializeDebugger); 226e509ee18Sopenharmony_ci g_uninitializeDebugger = reinterpret_cast<UninitializeDebugger>(&tooling::UninitializeDebugger); 227e509ee18Sopenharmony_ci g_waitForDebugger = reinterpret_cast<WaitForDebugger>(&tooling::WaitForDebugger); 228e509ee18Sopenharmony_ci g_onMessage = reinterpret_cast<OnMessage>(&tooling::OnMessage); 229e509ee18Sopenharmony_ci g_getDispatchStatus = reinterpret_cast<GetDispatchStatus>(&tooling::GetDispatchStatus); 230e509ee18Sopenharmony_ci g_processMessage = reinterpret_cast<ProcessMessage>(&tooling::ProcessMessage); 231e509ee18Sopenharmony_ci return true; 232e509ee18Sopenharmony_ci} 233e509ee18Sopenharmony_ci#endif 234e509ee18Sopenharmony_ci 235e509ee18Sopenharmony_cibool InitializeArkFunctions() 236e509ee18Sopenharmony_ci{ 237e509ee18Sopenharmony_ci // no need to initialize again in case of multi-instance 238e509ee18Sopenharmony_ci if (g_hasArkFuncsInited) { 239e509ee18Sopenharmony_ci return true; 240e509ee18Sopenharmony_ci } 241e509ee18Sopenharmony_ci 242e509ee18Sopenharmony_ci std::unique_lock<std::shared_mutex> lock(g_mutex); 243e509ee18Sopenharmony_ci if (g_hasArkFuncsInited) { 244e509ee18Sopenharmony_ci return true; 245e509ee18Sopenharmony_ci } 246e509ee18Sopenharmony_ci#if !defined(IOS_PLATFORM) 247e509ee18Sopenharmony_ci if (!InitializeArkFunctionsOthers()) { 248e509ee18Sopenharmony_ci return false; 249e509ee18Sopenharmony_ci } 250e509ee18Sopenharmony_ci#else 251e509ee18Sopenharmony_ci InitializeArkFunctionsIOS() 252e509ee18Sopenharmony_ci#endif 253e509ee18Sopenharmony_ci 254e509ee18Sopenharmony_ci g_hasArkFuncsInited = true; 255e509ee18Sopenharmony_ci return true; 256e509ee18Sopenharmony_ci} 257e509ee18Sopenharmony_ci 258e509ee18Sopenharmony_ci} // namespace 259e509ee18Sopenharmony_ci 260e509ee18Sopenharmony_civoid Inspector::OnMessage(std::string&& msg) 261e509ee18Sopenharmony_ci{ 262e509ee18Sopenharmony_ci g_onMessage(vm_, std::move(msg)); 263e509ee18Sopenharmony_ci 264e509ee18Sopenharmony_ci // message will be processed soon if the debugger thread is in running or waiting status 265e509ee18Sopenharmony_ci if (g_getDispatchStatus(vm_) != DispatchStatus::UNKNOWN) { 266e509ee18Sopenharmony_ci return; 267e509ee18Sopenharmony_ci } 268e509ee18Sopenharmony_ci std::this_thread::sleep_for(std::chrono::microseconds(DELAY_CHECK_DISPATCH_STATUS)); 269e509ee18Sopenharmony_ci if (g_getDispatchStatus(vm_) != DispatchStatus::UNKNOWN) { 270e509ee18Sopenharmony_ci return; 271e509ee18Sopenharmony_ci } 272e509ee18Sopenharmony_ci 273e509ee18Sopenharmony_ci // the debugger thread maybe in idle status, so try to post a task to wake it up 274e509ee18Sopenharmony_ci if (debuggerPostTask_ != nullptr) { 275e509ee18Sopenharmony_ci if (tidForSocketPair_ == 0) { 276e509ee18Sopenharmony_ci debuggerPostTask_([tid = tid_, vm = vm_] { 277e509ee18Sopenharmony_ci if (tid != pthread_self()) { 278e509ee18Sopenharmony_ci LOGE("Task not in debugger thread"); 279e509ee18Sopenharmony_ci return; 280e509ee18Sopenharmony_ci } 281e509ee18Sopenharmony_ci g_processMessage(vm); 282e509ee18Sopenharmony_ci }); 283e509ee18Sopenharmony_ci } else { 284e509ee18Sopenharmony_ci#if defined(OHOS_PLATFORM) 285e509ee18Sopenharmony_ci debuggerPostTask_([tid = tidForSocketPair_, vm = vm_, this] { 286e509ee18Sopenharmony_ci uint64_t threadOrTaskId = GetThreadOrTaskId(); 287e509ee18Sopenharmony_ci if (tid != static_cast<pid_t>(threadOrTaskId)) { 288e509ee18Sopenharmony_ci LOGE("Task not in debugger thread for socketpair"); 289e509ee18Sopenharmony_ci return; 290e509ee18Sopenharmony_ci } 291e509ee18Sopenharmony_ci g_processMessage(vm); 292e509ee18Sopenharmony_ci }); 293e509ee18Sopenharmony_ci#endif // defined(OHOS_PLATFORM) 294e509ee18Sopenharmony_ci } 295e509ee18Sopenharmony_ci } else { 296e509ee18Sopenharmony_ci LOGW("No debuggerPostTask provided"); 297e509ee18Sopenharmony_ci } 298e509ee18Sopenharmony_ci} 299e509ee18Sopenharmony_ci 300e509ee18Sopenharmony_ci#if defined(OHOS_PLATFORM) 301e509ee18Sopenharmony_ciuint64_t Inspector::GetThreadOrTaskId() 302e509ee18Sopenharmony_ci{ 303e509ee18Sopenharmony_ci#if defined(ENABLE_FFRT_INTERFACES) 304e509ee18Sopenharmony_ci uint64_t threadOrTaskId = ffrt_this_task_get_id(); 305e509ee18Sopenharmony_ci if (threadOrTaskId != 0) { 306e509ee18Sopenharmony_ci return threadOrTaskId; 307e509ee18Sopenharmony_ci } else { 308e509ee18Sopenharmony_ci return static_cast<uint64_t>(getproctid()); 309e509ee18Sopenharmony_ci } 310e509ee18Sopenharmony_ci#else 311e509ee18Sopenharmony_ci return static_cast<uint64_t>(getproctid()); 312e509ee18Sopenharmony_ci#endif // defined(ENABLE_FFRT_INTERFACES) 313e509ee18Sopenharmony_ci} 314e509ee18Sopenharmony_ci#endif // defined(OHOS_PLATFORM) 315e509ee18Sopenharmony_ci 316e509ee18Sopenharmony_ciconst DebuggerPostTask &GetDebuggerPostTask(int tid) 317e509ee18Sopenharmony_ci{ 318e509ee18Sopenharmony_ci std::shared_lock<std::shared_mutex> lock(g_mutex); 319e509ee18Sopenharmony_ci if (g_debuggerInfo.find(tid) == g_debuggerInfo.end()) { 320e509ee18Sopenharmony_ci static DebuggerPostTask tempTask; 321e509ee18Sopenharmony_ci return tempTask; 322e509ee18Sopenharmony_ci } 323e509ee18Sopenharmony_ci return g_debuggerInfo[tid].second; 324e509ee18Sopenharmony_ci} 325e509ee18Sopenharmony_ci 326e509ee18Sopenharmony_civoid *GetEcmaVM(int tid) 327e509ee18Sopenharmony_ci{ 328e509ee18Sopenharmony_ci std::shared_lock<std::shared_mutex> lock(g_mutex); 329e509ee18Sopenharmony_ci if (g_debuggerInfo.find(tid) == g_debuggerInfo.end()) { 330e509ee18Sopenharmony_ci return nullptr; 331e509ee18Sopenharmony_ci } 332e509ee18Sopenharmony_ci return g_debuggerInfo[tid].first; 333e509ee18Sopenharmony_ci} 334e509ee18Sopenharmony_ci 335e509ee18Sopenharmony_cibool InitializeDebuggerForSocketpair(void* vm) 336e509ee18Sopenharmony_ci{ 337e509ee18Sopenharmony_ci#if !defined(IOS_PLATFORM) 338e509ee18Sopenharmony_ci if (!LoadArkDebuggerLibrary()) { 339e509ee18Sopenharmony_ci return false; 340e509ee18Sopenharmony_ci } 341e509ee18Sopenharmony_ci#endif 342e509ee18Sopenharmony_ci if (!InitializeArkFunctions()) { 343e509ee18Sopenharmony_ci LOGE("Initialize ark functions failed"); 344e509ee18Sopenharmony_ci return false; 345e509ee18Sopenharmony_ci } 346e509ee18Sopenharmony_ci g_initializeDebugger(vm, std::bind(&SendReply, vm, std::placeholders::_2)); 347e509ee18Sopenharmony_ci return true; 348e509ee18Sopenharmony_ci} 349e509ee18Sopenharmony_ci 350e509ee18Sopenharmony_ci// for ohos platform. 351e509ee18Sopenharmony_cibool StartDebugForSocketpair(int tid, int socketfd) 352e509ee18Sopenharmony_ci{ 353e509ee18Sopenharmony_ci LOGI("StartDebugForSocketpair, tid = %{private}d, socketfd = %{private}d", tid, socketfd); 354e509ee18Sopenharmony_ci void* vm = GetEcmaVM(tid); 355e509ee18Sopenharmony_ci if (vm == nullptr) { 356e509ee18Sopenharmony_ci LOGD("VM has already been destroyed"); 357e509ee18Sopenharmony_ci return false; 358e509ee18Sopenharmony_ci } 359e509ee18Sopenharmony_ci g_vm = vm; 360e509ee18Sopenharmony_ci if (!InitializeDebuggerForSocketpair(vm)) { 361e509ee18Sopenharmony_ci return false; 362e509ee18Sopenharmony_ci } 363e509ee18Sopenharmony_ci const DebuggerPostTask &debuggerPostTask = GetDebuggerPostTask(tid); 364e509ee18Sopenharmony_ci DebugInfo debugInfo = {socketfd}; 365e509ee18Sopenharmony_ci if (!InitializeInspector(vm, debuggerPostTask, debugInfo, tid)) { 366e509ee18Sopenharmony_ci LOGE("Initialize inspector failed"); 367e509ee18Sopenharmony_ci return false; 368e509ee18Sopenharmony_ci } 369e509ee18Sopenharmony_ci 370e509ee18Sopenharmony_ci return true; 371e509ee18Sopenharmony_ci} 372e509ee18Sopenharmony_ci 373e509ee18Sopenharmony_ci// for cross-platform, previewer and old process of StartDebugger. 374e509ee18Sopenharmony_cibool StartDebug(const std::string& componentName, void* vm, bool isDebugMode, 375e509ee18Sopenharmony_ci int32_t instanceId, const DebuggerPostTask& debuggerPostTask, int port) 376e509ee18Sopenharmony_ci{ 377e509ee18Sopenharmony_ci LOGI("StartDebug, componentName = %{private}s, isDebugMode = %{private}d, instanceId = %{private}d", 378e509ee18Sopenharmony_ci componentName.c_str(), isDebugMode, instanceId); 379e509ee18Sopenharmony_ci g_vm = vm; 380e509ee18Sopenharmony_ci#if !defined(IOS_PLATFORM) 381e509ee18Sopenharmony_ci if (!LoadArkDebuggerLibrary()) { 382e509ee18Sopenharmony_ci return false; 383e509ee18Sopenharmony_ci } 384e509ee18Sopenharmony_ci#endif 385e509ee18Sopenharmony_ci if (!InitializeArkFunctions()) { 386e509ee18Sopenharmony_ci LOGE("Initialize ark functions failed"); 387e509ee18Sopenharmony_ci return false; 388e509ee18Sopenharmony_ci } 389e509ee18Sopenharmony_ci 390e509ee18Sopenharmony_ci g_initializeDebugger(vm, std::bind(&SendReply, vm, std::placeholders::_2)); 391e509ee18Sopenharmony_ci 392e509ee18Sopenharmony_ci int startDebugInOldProcess = -2; // start debug in old process. 393e509ee18Sopenharmony_ci DebugInfo debugInfo = {startDebugInOldProcess, componentName, instanceId, port}; 394e509ee18Sopenharmony_ci if (!InitializeInspector(vm, debuggerPostTask, debugInfo)) { 395e509ee18Sopenharmony_ci LOGE("Initialize inspector failed"); 396e509ee18Sopenharmony_ci return false; 397e509ee18Sopenharmony_ci } 398e509ee18Sopenharmony_ci 399e509ee18Sopenharmony_ci if (isDebugMode && port > 0) { 400e509ee18Sopenharmony_ci LOGI("Wait for debugger for previewer"); 401e509ee18Sopenharmony_ci g_waitForDebugger(vm); 402e509ee18Sopenharmony_ci } 403e509ee18Sopenharmony_ci return true; 404e509ee18Sopenharmony_ci} 405e509ee18Sopenharmony_ci 406e509ee18Sopenharmony_civoid WaitForDebugger(void* vm) 407e509ee18Sopenharmony_ci{ 408e509ee18Sopenharmony_ci LOGI("WaitForDebugger"); 409e509ee18Sopenharmony_ci g_waitForDebugger(vm); 410e509ee18Sopenharmony_ci} 411e509ee18Sopenharmony_ci 412e509ee18Sopenharmony_civoid StopDebug(void* vm) 413e509ee18Sopenharmony_ci{ 414e509ee18Sopenharmony_ci LOGI("StopDebug start, vm is %{private}p", vm); 415e509ee18Sopenharmony_ci std::unique_lock<std::shared_mutex> lock(g_mutex); 416e509ee18Sopenharmony_ci auto iter = g_inspectors.find(vm); 417e509ee18Sopenharmony_ci if (iter == g_inspectors.end() || iter->second == nullptr) { 418e509ee18Sopenharmony_ci return; 419e509ee18Sopenharmony_ci } 420e509ee18Sopenharmony_ci#ifdef PANDA_TARGET_MACOS 421e509ee18Sopenharmony_ci uint32_t tid = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(g_inspectors[vm]->tid_)); 422e509ee18Sopenharmony_ci#else 423e509ee18Sopenharmony_ci uint32_t tid = g_inspectors[vm]->tid_; 424e509ee18Sopenharmony_ci#endif 425e509ee18Sopenharmony_ci auto debuggerInfo = g_debuggerInfo.find(tid); 426e509ee18Sopenharmony_ci if (debuggerInfo != g_debuggerInfo.end()) { 427e509ee18Sopenharmony_ci g_debuggerInfo.erase(debuggerInfo); 428e509ee18Sopenharmony_ci } 429e509ee18Sopenharmony_ci g_uninitializeDebugger(vm); 430e509ee18Sopenharmony_ci ResetServiceLocked(vm, true); 431e509ee18Sopenharmony_ci LOGI("StopDebug end"); 432e509ee18Sopenharmony_ci} 433e509ee18Sopenharmony_ci 434e509ee18Sopenharmony_civoid StopOldDebug(int tid, const std::string& componentName) 435e509ee18Sopenharmony_ci{ 436e509ee18Sopenharmony_ci LOGI("StopDebug start, componentName = %{private}s, tid = %{private}d", componentName.c_str(), tid); 437e509ee18Sopenharmony_ci void* vm = GetEcmaVM(tid); 438e509ee18Sopenharmony_ci if (vm == nullptr) { 439e509ee18Sopenharmony_ci return; 440e509ee18Sopenharmony_ci } 441e509ee18Sopenharmony_ci std::unique_lock<std::shared_mutex> lock(g_mutex); 442e509ee18Sopenharmony_ci auto iter = g_inspectors.find(vm); 443e509ee18Sopenharmony_ci if (iter == g_inspectors.end() || iter->second == nullptr) { 444e509ee18Sopenharmony_ci return; 445e509ee18Sopenharmony_ci } 446e509ee18Sopenharmony_ci 447e509ee18Sopenharmony_ci ResetServiceLocked(vm, false); 448e509ee18Sopenharmony_ci LOGI("StopDebug end"); 449e509ee18Sopenharmony_ci} 450e509ee18Sopenharmony_ci 451e509ee18Sopenharmony_ci// for socketpair process. 452e509ee18Sopenharmony_civoid StoreDebuggerInfo(int tid, void* vm, const DebuggerPostTask& debuggerPostTask) 453e509ee18Sopenharmony_ci{ 454e509ee18Sopenharmony_ci std::unique_lock<std::shared_mutex> lock(g_mutex); 455e509ee18Sopenharmony_ci if (g_debuggerInfo.find(tid) == g_debuggerInfo.end()) { 456e509ee18Sopenharmony_ci g_debuggerInfo.emplace(tid, std::make_pair(vm, debuggerPostTask)); 457e509ee18Sopenharmony_ci } 458e509ee18Sopenharmony_ci} 459e509ee18Sopenharmony_ci} // namespace OHOS::ArkCompiler::Toolchain 460