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