From ad76f3e926ce2b43eccc2b46b2076ef6c059a251 Mon Sep 17 00:00:00 2001 From: yanpeng Date: Tue, 24 Oct 2023 21:04:13 +0800 Subject: [PATCH] client support multi-sessions Signed-off-by: yanpeng --- tooling/client/BUILD.gn | 1 + tooling/client/ark_cli/main.cpp | 114 +++------ tooling/client/domain/debugger_client.cpp | 228 +++++++++++------- tooling/client/domain/debugger_client.h | 53 ++-- tooling/client/domain/heapprofiler_client.cpp | 133 +++++++--- tooling/client/domain/heapprofiler_client.h | 21 +- tooling/client/domain/profiler_client.cpp | 97 +++++--- tooling/client/domain/profiler_client.h | 19 +- tooling/client/domain/runtime_client.cpp | 104 +++++--- tooling/client/domain/runtime_client.h | 17 +- tooling/client/domain/test_client.cpp | 40 ++- tooling/client/domain/test_client.h | 11 +- tooling/client/manager/breakpoint_manager.cpp | 7 +- tooling/client/manager/breakpoint_manager.h | 5 +- tooling/client/manager/domain_manager.cpp | 7 + tooling/client/manager/domain_manager.h | 13 +- tooling/client/manager/message_manager.h | 70 ++++++ tooling/client/manager/stack_manager.cpp | 7 +- tooling/client/manager/stack_manager.h | 5 +- tooling/client/manager/variable_manager.cpp | 6 - tooling/client/manager/variable_manager.h | 5 +- tooling/client/session/session.cpp | 208 ++++++++++++++++ tooling/client/session/session.h | 166 +++++++++++++ tooling/client/utils/cli_command.cpp | 159 +++++++----- tooling/client/utils/cli_command.h | 18 +- tooling/client/utils/utils.cpp | 11 + tooling/client/utils/utils.h | 1 + tooling/client/websocket/websocket_client.cpp | 22 +- tooling/client/websocket/websocket_client.h | 3 +- tooling/test/BUILD.gn | 1 + tooling/test/client_utils/test_util.cpp | 35 ++- tooling/test/client_utils/test_util.h | 4 +- 32 files changed, 1140 insertions(+), 451 deletions(-) create mode 100755 tooling/client/manager/message_manager.h create mode 100755 tooling/client/session/session.cpp create mode 100755 tooling/client/session/session.h diff --git a/tooling/client/BUILD.gn b/tooling/client/BUILD.gn index ba992144..e87bfff8 100644 --- a/tooling/client/BUILD.gn +++ b/tooling/client/BUILD.gn @@ -38,6 +38,7 @@ ohos_source_set("libark_client_set") { "manager/domain_manager.cpp", "manager/stack_manager.cpp", "manager/variable_manager.cpp", + "session/session.cpp", "utils/cli_command.cpp", "utils/utils.cpp", "websocket/websocket_client.cpp", diff --git a/tooling/client/ark_cli/main.cpp b/tooling/client/ark_cli/main.cpp index f3b7df10..42380a4c 100644 --- a/tooling/client/ark_cli/main.cpp +++ b/tooling/client/ark_cli/main.cpp @@ -22,28 +22,14 @@ #include #include "tooling/client/utils/cli_command.h" +#include "tooling/client/session/session.h" +#include "manager/message_manager.h" namespace OHOS::ArkCompiler::Toolchain { -uint32_t g_messageId = 0; -uv_async_t* g_socketSignal; uv_async_t* g_inputSignal; uv_async_t* g_releaseHandle; uv_loop_t* g_loop; -DomainManager g_domainManager; -WebsocketClient g_cliSocket; - -bool StrToUInt(const char *content, uint32_t *result) -{ - const int dec = 10; - char *endPtr = nullptr; - *result = std::strtoul(content, &endPtr, dec); - if (endPtr == content || *endPtr != '\0') { - return false; - } - return true; -} - void ReleaseHandle([[maybe_unused]] uv_async_t *releaseHandle) { uv_close(reinterpret_cast(g_inputSignal), [](uv_handle_t* handle) { @@ -72,21 +58,36 @@ void ReleaseHandle([[maybe_unused]] uv_async_t *releaseHandle) } } +void InputMessageInSession(uint32_t sessionId, std::vector& cliCmdStr) +{ + CliCommand cmd(cliCmdStr, sessionId); + cmd.ExecCommand(); + return; +} + void InputOnMessage(uv_async_t *handle) { char* msg = static_cast(handle->data); std::string inputStr = std::string(msg); + if (msg != nullptr) { + free(msg); + } std::vector cliCmdStr = Utils::SplitString(inputStr, " "); - g_messageId += 1; - CliCommand cmd(cliCmdStr, g_messageId, g_domainManager, g_cliSocket); - if (cmd.ExecCommand() == ErrCode::ERR_FAIL) { - g_messageId -= 1; + if (cliCmdStr[0] == "forall") { + if (strstr(cliCmdStr[1].c_str(), "session") != nullptr) { + std::cout << "command " << cliCmdStr[1] << " not support forall" << std::endl; + } else { + cliCmdStr.erase(cliCmdStr.begin()); + SessionManager::getInstance().CmdForAllSessions(std::bind(InputMessageInSession, std::placeholders::_1, + cliCmdStr)); + } + } else { + uint32_t sessionId = SessionManager::getInstance().GetCurrentSessionId(); + InputMessageInSession(sessionId, cliCmdStr); } + std::cout << ">>> "; fflush(stdout); - if (msg != nullptr) { - free(msg); - } } void GetInputCommand([[maybe_unused]] void *arg) @@ -100,7 +101,6 @@ void GetInputCommand([[maybe_unused]] void *arg) } if ((!strcmp(inputStr.c_str(), "quit")) || (!strcmp(inputStr.c_str(), "q"))) { LOGE("arkdb: quit"); - g_cliSocket.Close(); if (uv_is_active(reinterpret_cast(g_releaseHandle))) { uv_async_send(g_releaseHandle); } @@ -111,7 +111,6 @@ void GetInputCommand([[maybe_unused]] void *arg) char* msg = (char*)malloc(len + 1); if ((msg != nullptr) && uv_is_active(reinterpret_cast(g_inputSignal))) { if (strncpy_s(msg, len + 1, inputStr.c_str(), len) != 0) { - g_cliSocket.Close(); if (uv_is_active(reinterpret_cast(g_releaseHandle))) { uv_async_send(g_releaseHandle); } @@ -124,69 +123,31 @@ void GetInputCommand([[maybe_unused]] void *arg) } } -void SocketOnMessage(uv_async_t *handle) -{ - char* msg = static_cast(handle->data); - g_domainManager.DispatcherReply(msg); - if (msg != nullptr) { - free(msg); - } -} - -void GetSocketMessage([[maybe_unused]] void *arg) +void SocketOnMessage([[maybe_unused]] uv_async_t *handle) { - while (g_cliSocket.IsConnected()) { - std::string decMessage = g_cliSocket.Decode(); - uint32_t len = decMessage.length(); - if (len == 0) { + uint32_t sessionId = 0; + std::string message; + while (MessageManager::getInstance().MessagePop(sessionId, message)) { + Session *session = SessionManager::getInstance().GetSessionById(sessionId); + if (session == nullptr) { + LOGE("arkdb get session by id %{public}u failed", sessionId); continue; } - char* msg = (char*)malloc(len + 1); - if ((msg != nullptr) && uv_is_active(reinterpret_cast(g_socketSignal))) { - if (strncpy_s(msg, len + 1, decMessage.c_str(), len) != 0) { - g_cliSocket.Close(); - if (uv_is_active(reinterpret_cast(g_releaseHandle))) { - uv_async_send(g_releaseHandle); - } - break; - } - g_socketSignal->data = std::move(msg); - uv_async_send(g_socketSignal); - } + + session->ProcSocketMsg(const_cast(message.c_str())); } } int Main(const int argc, const char** argv) { - uint32_t port = 0; - if (argc < 2) { // 2: two parameters LOGE("arkdb is missing a parameter"); return -1; } if (strstr(argv[0], "arkdb") != nullptr) { - if (StrToUInt(argv[1], &port)) { - if ((port <= 0) || (port >= 65535)) { // 65535: max port - LOGE("arkdb:InitToolchainWebSocketForPort the port = %{public}d is wrong.", port); - return -1; - } - if (!g_cliSocket.InitToolchainWebSocketForPort(port, 5)) { // 5: five times - LOGE("arkdb:InitToolchainWebSocketForPort failed"); - return -1; - } - } else { - if (!g_cliSocket.InitToolchainWebSocketForSockName(argv[1])) { - LOGE("arkdb:InitToolchainWebSocketForSockName failed"); - return -1; - } - } - - if (!g_cliSocket.ClientSendWSUpgradeReq()) { - LOGE("arkdb:ClientSendWSUpgradeReq failed"); - return -1; - } - if (!g_cliSocket.ClientRecvWSUpgradeRsp()) { - LOGE("arkdb:ClientRecvWSUpgradeRsp failed"); + std::string sockInfo(argv[1]); + if (SessionManager::getInstance().CreateDefaultSession(sockInfo)) { + LOGE("arkdb create default session failed"); return -1; } @@ -204,9 +165,6 @@ int Main(const int argc, const char** argv) uv_thread_t inputTid; uv_thread_create(&inputTid, GetInputCommand, nullptr); - uv_thread_t socketTid; - uv_thread_create(&socketTid, GetSocketMessage, nullptr); - uv_run(g_loop, UV_RUN_DEFAULT); } return 0; diff --git a/tooling/client/domain/debugger_client.cpp b/tooling/client/domain/debugger_client.cpp index cfb9eefb..376b3d56 100644 --- a/tooling/client/domain/debugger_client.cpp +++ b/tooling/client/domain/debugger_client.cpp @@ -21,53 +21,56 @@ #include "tooling/client/manager/breakpoint_manager.h" #include "tooling/client/manager/stack_manager.h" #include "tooling/base/pt_json.h" +#include "tooling/client/session/session.h" using PtJson = panda::ecmascript::tooling::PtJson; namespace OHOS::ArkCompiler::Toolchain { -bool DebuggerClient::DispatcherCmd(int id, const std::string &cmd, std::string* reqStr) +bool DebuggerClient::DispatcherCmd(const std::string &cmd) { - std::map> dispatcherTable { - { "break", std::bind(&DebuggerClient::BreakCommand, this, id)}, - { "backtrack", std::bind(&DebuggerClient::BacktrackCommand, this, id)}, - { "continue", std::bind(&DebuggerClient::ResumeCommand, this, id)}, - { "delete", std::bind(&DebuggerClient::DeleteCommand, this, id)}, - { "jump", std::bind(&DebuggerClient::JumpCommand, this, id)}, - { "disable", std::bind(&DebuggerClient::DisableCommand, this, id)}, - { "display", std::bind(&DebuggerClient::DisplayCommand, this, id)}, - { "enable", std::bind(&DebuggerClient::EnableCommand, this, id)}, - { "finish", std::bind(&DebuggerClient::FinishCommand, this, id)}, - { "frame", std::bind(&DebuggerClient::FrameCommand, this, id)}, - { "ignore", std::bind(&DebuggerClient::IgnoreCommand, this, id)}, - { "infobreakpoints", std::bind(&DebuggerClient::InfobreakpointsCommand, this, id)}, - { "infosource", std::bind(&DebuggerClient::InfosourceCommand, this, id)}, - { "list", std::bind(&DebuggerClient::ListCommand, this, id)}, - { "next", std::bind(&DebuggerClient::NextCommand, this, id)}, - { "ptype", std::bind(&DebuggerClient::PtypeCommand, this, id)}, - { "run", std::bind(&DebuggerClient::RunCommand, this, id)}, - { "setvar", std::bind(&DebuggerClient::SetvarCommand, this, id)}, - { "step", std::bind(&DebuggerClient::StepCommand, this, id)}, - { "undisplay", std::bind(&DebuggerClient::UndisplayCommand, this, id)}, - { "watch", std::bind(&DebuggerClient::WatchCommand, this, id)}, - { "resume", std::bind(&DebuggerClient::ResumeCommand, this, id)}, - { "step-into", std::bind(&DebuggerClient::StepIntoCommand, this, id)}, - { "step-out", std::bind(&DebuggerClient::StepOutCommand, this, id)}, - { "step-over", std::bind(&DebuggerClient::StepOverCommand, this, id)}, + std::map> dispatcherTable { + { "break", std::bind(&DebuggerClient::BreakCommand, this)}, + { "backtrack", std::bind(&DebuggerClient::BacktrackCommand, this)}, + { "continue", std::bind(&DebuggerClient::ResumeCommand, this)}, + { "delete", std::bind(&DebuggerClient::DeleteCommand, this)}, + { "jump", std::bind(&DebuggerClient::JumpCommand, this)}, + { "disable", std::bind(&DebuggerClient::DisableCommand, this)}, + { "display", std::bind(&DebuggerClient::DisplayCommand, this)}, + { "enable", std::bind(&DebuggerClient::EnableCommand, this)}, + { "finish", std::bind(&DebuggerClient::FinishCommand, this)}, + { "frame", std::bind(&DebuggerClient::FrameCommand, this)}, + { "ignore", std::bind(&DebuggerClient::IgnoreCommand, this)}, + { "infobreakpoints", std::bind(&DebuggerClient::InfobreakpointsCommand, this)}, + { "infosource", std::bind(&DebuggerClient::InfosourceCommand, this)}, + { "list", std::bind(&DebuggerClient::ListCommand, this)}, + { "next", std::bind(&DebuggerClient::NextCommand, this)}, + { "ptype", std::bind(&DebuggerClient::PtypeCommand, this)}, + { "run", std::bind(&DebuggerClient::RunCommand, this)}, + { "setvar", std::bind(&DebuggerClient::SetvarCommand, this)}, + { "step", std::bind(&DebuggerClient::StepCommand, this)}, + { "undisplay", std::bind(&DebuggerClient::UndisplayCommand, this)}, + { "watch", std::bind(&DebuggerClient::WatchCommand, this)}, + { "resume", std::bind(&DebuggerClient::ResumeCommand, this)}, + { "step-into", std::bind(&DebuggerClient::StepIntoCommand, this)}, + { "step-out", std::bind(&DebuggerClient::StepOutCommand, this)}, + { "step-over", std::bind(&DebuggerClient::StepOverCommand, this)}, }; auto entry = dispatcherTable.find(cmd); if (entry != dispatcherTable.end()) { - *reqStr = entry->second(); - LOGI("DebuggerClient DispatcherCmd reqStr1: %{public}s", reqStr->c_str()); + entry->second(); + LOGI("DebuggerClient DispatcherCmd cmd: %{public}s", cmd.c_str()); return true; } - *reqStr = "Unknown commond: " + cmd; - LOGI("DebuggerClient DispatcherCmd reqStr2: %{public}s", reqStr->c_str()); + LOGI("unknown command: %{public}s", cmd.c_str()); return false; } -std::string DebuggerClient::BreakCommand(int id) +int DebuggerClient::BreakCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); request->Add("method", "Debugger.setBreakpointByUrl"); @@ -77,16 +80,24 @@ std::string DebuggerClient::BreakCommand(int id) params->Add("lineNumber", breakPointInfoList_.back().lineNumber); params->Add("url", breakPointInfoList_.back().url.c_str()); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Debugger"); + } + return 0; } -std::string DebuggerClient::BacktrackCommand([[maybe_unused]] int id) +int DebuggerClient::BacktrackCommand() { - return "backtrack"; + return 0; } -std::string DebuggerClient::DeleteCommand(int id) +int DebuggerClient::DeleteCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); request->Add("method", "Debugger.removeBreakpoint"); @@ -95,148 +106,201 @@ std::string DebuggerClient::DeleteCommand(int id) std::string breakpointId = breakPointInfoList_.back().url; params->Add("breakpointId", breakpointId.c_str()); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Debugger"); + } + return 0; } -std::string DebuggerClient::DisableCommand(int id) +int DebuggerClient::DisableCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); request->Add("method", "Debugger.disable"); std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Debugger"); + } + return 0; } -std::string DebuggerClient::DisplayCommand([[maybe_unused]] int id) +int DebuggerClient::DisplayCommand() { - return "display"; + return 0; } -std::string DebuggerClient::EnableCommand(int id) +int DebuggerClient::EnableCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); request->Add("method", "Debugger.enable"); std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Debugger"); + } + return 0; } -std::string DebuggerClient::FinishCommand([[maybe_unused]] int id) +int DebuggerClient::FinishCommand() { - return "finish"; + return 0; } -std::string DebuggerClient::FrameCommand([[maybe_unused]] int id) +int DebuggerClient::FrameCommand() { - return "frame"; + return 0; } -std::string DebuggerClient::IgnoreCommand([[maybe_unused]] int id) +int DebuggerClient::IgnoreCommand() { - return "ignore"; + return 0; } -std::string DebuggerClient::InfobreakpointsCommand([[maybe_unused]] int id) +int DebuggerClient::InfobreakpointsCommand() { - return "infobreakpoint"; + return 0; } -std::string DebuggerClient::InfosourceCommand([[maybe_unused]] int id) +int DebuggerClient::InfosourceCommand() { - return "infosource"; + return 0; } -std::string DebuggerClient::JumpCommand([[maybe_unused]] int id) +int DebuggerClient::JumpCommand() { - return "jump"; + return 0; } -std::string DebuggerClient::NextCommand([[maybe_unused]] int id) +int DebuggerClient::NextCommand() { - return "next"; + return 0; } -std::string DebuggerClient::ListCommand([[maybe_unused]] int id) +int DebuggerClient::ListCommand() { - return "list"; + return 0; } -std::string DebuggerClient::PtypeCommand([[maybe_unused]] int id) +int DebuggerClient::PtypeCommand() { - return "ptype"; + return 0; } -std::string DebuggerClient::RunCommand([[maybe_unused]] int id) +int DebuggerClient::RunCommand() { - return "run"; + return 0; } -std::string DebuggerClient::SetvarCommand([[maybe_unused]] int id) +int DebuggerClient::SetvarCommand() { - return "Debugger.setVariableValue"; + return 0; } -std::string DebuggerClient::StepCommand([[maybe_unused]] int id) +int DebuggerClient::StepCommand() { - return "step"; + return 0; } -std::string DebuggerClient::UndisplayCommand([[maybe_unused]] int id) +int DebuggerClient::UndisplayCommand() { - return "undisplay"; + return 0; } -std::string DebuggerClient::WatchCommand([[maybe_unused]] int id) +int DebuggerClient::WatchCommand() { - return "Debugger.evaluateOnCallFrame"; + return 0; } -std::string DebuggerClient::ResumeCommand(int id) +int DebuggerClient::ResumeCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); request->Add("method", "Debugger.resume"); std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Debugger"); + } + return 0; } -std::string DebuggerClient::StepIntoCommand(int id) +int DebuggerClient::StepIntoCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); request->Add("method", "Debugger.stepInto"); std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Debugger"); + } + return 0; } -std::string DebuggerClient::StepOutCommand(int id) +int DebuggerClient::StepOutCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); request->Add("method", "Debugger.stepOut"); std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Debugger"); + } + return 0; } -std::string DebuggerClient::StepOverCommand(int id) +int DebuggerClient::StepOverCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); request->Add("method", "Debugger.stepOver"); std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Debugger"); + } + return 0; } void DebuggerClient::AddBreakPointInfo(const std::string& url, const int& lineNumber, const int& columnNumber) @@ -290,7 +354,8 @@ void DebuggerClient::RecvReply(std::unique_ptr json) std::string breakpointId; ret = result->GetString("breakpointId", &breakpointId); if (ret == Result::SUCCESS) { - BreakPointManager &breakpoint = BreakPointManager::GetInstance(); + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + BreakPointManager& breakpoint = session->GetBreakPointManager(); breakpoint.Createbreaklocation(std::move(json)); } } @@ -328,7 +393,8 @@ void DebuggerClient::PausedReply(const std::unique_ptr json) data.emplace(i + 1, std::move(callFrameInfo)); } - StackManager &stackManager = StackManager::GetInstance(); + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + StackManager& stackManager = session->GetStackManager(); stackManager.ClearCallFrame(); stackManager.SetCallFrames(std::move(data)); } diff --git a/tooling/client/domain/debugger_client.h b/tooling/client/domain/debugger_client.h index 1864275e..204644b4 100644 --- a/tooling/client/domain/debugger_client.h +++ b/tooling/client/domain/debugger_client.h @@ -31,34 +31,34 @@ struct BreakPointInfo { }; class DebuggerClient final { public: - DebuggerClient() = default; + DebuggerClient(int32_t sessionId) : sessionId_(sessionId) {} ~DebuggerClient() = default; - bool DispatcherCmd(int id, const std::string &cmd, std::string* reqStr); - std::string BreakCommand(int id); - std::string BacktrackCommand(int id); - std::string DeleteCommand(int id); - std::string DisableCommand(int id); - std::string DisplayCommand(int id); - std::string EnableCommand(int id); - std::string FinishCommand(int id); - std::string FrameCommand(int id); - std::string IgnoreCommand(int id); - std::string InfobreakpointsCommand(int id); - std::string InfosourceCommand(int id); - std::string JumpCommand(int id); - std::string NextCommand(int id); - std::string ListCommand(int id); - std::string PtypeCommand(int id); - std::string RunCommand(int id); - std::string SetvarCommand(int id); - std::string StepCommand(int id); - std::string UndisplayCommand(int id); - std::string WatchCommand(int id); - std::string ResumeCommand(int id); - std::string StepIntoCommand(int id); - std::string StepOutCommand(int id); - std::string StepOverCommand(int id); + bool DispatcherCmd(const std::string &cmd); + int BreakCommand(); + int BacktrackCommand(); + int DeleteCommand(); + int DisableCommand(); + int DisplayCommand(); + int EnableCommand(); + int FinishCommand(); + int FrameCommand(); + int IgnoreCommand(); + int InfobreakpointsCommand(); + int InfosourceCommand(); + int JumpCommand(); + int NextCommand(); + int ListCommand(); + int PtypeCommand(); + int RunCommand(); + int SetvarCommand(); + int StepCommand(); + int UndisplayCommand(); + int WatchCommand(); + int ResumeCommand(); + int StepIntoCommand(); + int StepOutCommand(); + int StepOverCommand(); void AddBreakPointInfo(const std::string& url, const int& lineNumber, const int& columnNumber = 0); void RecvReply(std::unique_ptr json); @@ -66,6 +66,7 @@ public: private: std::vector breakPointInfoList_ {}; + int32_t sessionId_; }; } // OHOS::ArkCompiler::Toolchain #endif \ No newline at end of file diff --git a/tooling/client/domain/heapprofiler_client.cpp b/tooling/client/domain/heapprofiler_client.cpp index bde7a0da..e730b623 100644 --- a/tooling/client/domain/heapprofiler_client.cpp +++ b/tooling/client/domain/heapprofiler_client.cpp @@ -16,6 +16,7 @@ #include "tooling/client/domain/heapprofiler_client.h" #include "common/log_wrapper.h" #include "tooling/client/utils/utils.h" +#include "tooling/client/session/session.h" #include #include @@ -24,38 +25,37 @@ using Result = panda::ecmascript::tooling::Result; namespace OHOS::ArkCompiler::Toolchain { static constexpr int32_t SAMPLING_INTERVAL = 16384; -bool HeapProfilerClient::DispatcherCmd(int id, const std::string &cmd, const std::string &arg, std::string* reqStr) +bool HeapProfilerClient::DispatcherCmd(const std::string &cmd, const std::string &arg) { - if (reqStr == nullptr) { - return false; - } path_ = arg; - std::map> dispatcherTable { - { "allocationtrack", std::bind(&HeapProfilerClient::AllocationTrackCommand, this, id)}, - { "allocationtrack-stop", std::bind(&HeapProfilerClient::AllocationTrackStopCommand, this, id)}, - { "heapdump", std::bind(&HeapProfilerClient::HeapDumpCommand, this, id)}, - { "heapprofiler-enable", std::bind(&HeapProfilerClient::Enable, this, id)}, - { "heapprofiler-disable", std::bind(&HeapProfilerClient::Disable, this, id)}, - { "sampling", std::bind(&HeapProfilerClient::Samping, this, id)}, - { "sampling-stop", std::bind(&HeapProfilerClient::SampingStop, this, id)}, - { "collectgarbage", std::bind(&HeapProfilerClient::CollectGarbage, this, id)} + std::map> dispatcherTable { + { "allocationtrack", std::bind(&HeapProfilerClient::AllocationTrackCommand, this)}, + { "allocationtrack-stop", std::bind(&HeapProfilerClient::AllocationTrackStopCommand, this)}, + { "heapdump", std::bind(&HeapProfilerClient::HeapDumpCommand, this)}, + { "heapprofiler-enable", std::bind(&HeapProfilerClient::Enable, this)}, + { "heapprofiler-disable", std::bind(&HeapProfilerClient::Disable, this)}, + { "sampling", std::bind(&HeapProfilerClient::Samping, this)}, + { "sampling-stop", std::bind(&HeapProfilerClient::SampingStop, this)}, + { "collectgarbage", std::bind(&HeapProfilerClient::CollectGarbage, this)} }; auto entry = dispatcherTable.find(cmd); if (entry != dispatcherTable.end() && entry->second != nullptr) { - *reqStr = entry->second(); - LOGI("DispatcherCmd reqStr1: %{public}s", reqStr->c_str()); + entry->second(); + LOGI("DispatcherCmd reqStr1: %{public}s", cmd.c_str()); return true; } - *reqStr = "Unknown commond: " + cmd; - LOGI("DispatcherCmd reqStr2: %{public}s", reqStr->c_str()); + LOGI("unknown command: %{public}s", cmd.c_str()); return false; } -std::string HeapProfilerClient::HeapDumpCommand(int id) +int HeapProfilerClient::HeapDumpCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, HEAPDUMP); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -66,11 +66,19 @@ std::string HeapProfilerClient::HeapDumpCommand(int id) params->Add("captureNumericValue", true); params->Add("exposeInternals", false); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "HeapProfiler"); + } + return 0; } -std::string HeapProfilerClient::AllocationTrackCommand(int id) +int HeapProfilerClient::AllocationTrackCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, ALLOCATION); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -79,11 +87,19 @@ std::string HeapProfilerClient::AllocationTrackCommand(int id) std::unique_ptr params = PtJson::CreateObject(); params->Add("trackAllocations", true); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "HeapProfiler"); + } + return 0; } -std::string HeapProfilerClient::AllocationTrackStopCommand(int id) +int HeapProfilerClient::AllocationTrackStopCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, ALLOCATION_STOP); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -92,11 +108,19 @@ std::string HeapProfilerClient::AllocationTrackStopCommand(int id) std::unique_ptr params = PtJson::CreateObject(); params->Add("reportProgress", true); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "HeapProfiler"); + } + return 0; } -std::string HeapProfilerClient::Enable(int id) +int HeapProfilerClient::Enable() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, ENABLE); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -104,11 +128,19 @@ std::string HeapProfilerClient::Enable(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "HeapProfiler"); + } + return 0; } -std::string HeapProfilerClient::Disable(int id) +int HeapProfilerClient::Disable() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, DISABLE); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -116,11 +148,19 @@ std::string HeapProfilerClient::Disable(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "HeapProfiler"); + } + return 0; } -std::string HeapProfilerClient::Samping(int id) +int HeapProfilerClient::Samping() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, SAMPLING); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -129,11 +169,19 @@ std::string HeapProfilerClient::Samping(int id) std::unique_ptr params = PtJson::CreateObject(); params->Add("samplingInterval", SAMPLING_INTERVAL); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "HeapProfiler"); + } + return 0; } -std::string HeapProfilerClient::SampingStop(int id) +int HeapProfilerClient::SampingStop() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, SAMPLING_STOP); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -141,11 +189,19 @@ std::string HeapProfilerClient::SampingStop(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "HeapProfiler"); + } + return 0; } -std::string HeapProfilerClient::CollectGarbage(int id) +int HeapProfilerClient::CollectGarbage() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, COLLECT_GARBAGE); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -153,7 +209,12 @@ std::string HeapProfilerClient::CollectGarbage(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "HeapProfiler"); + } + return 0; } void HeapProfilerClient::RecvReply(std::unique_ptr json) @@ -213,10 +274,12 @@ void HeapProfilerClient::RecvReply(std::unique_ptr json) return; } if (isAllocationMsg_) { - fileName_ = "Heap-" + std::string(date) + "T" + std::string(time) + ".heaptimeline"; + fileName_ = "Heap-" + std::to_string(sessionId_) + "-" + std::string(date) + "T" + std::string(time) + + ".heaptimeline"; std::cout << "heaptimeline file name is " << fileName_ << std::endl; } else { - fileName_ = "Heap-" + std::string(date) + "T" + std::string(time) + ".heapsnapshot"; + fileName_ = "Heap-"+ std::to_string(sessionId_) + "-" + std::string(date) + "T" + std::string(time) + + ".heapsnapshot"; std::cout << "heapsnapshot file name is " << fileName_ << std::endl; } std::cout << ">>> "; diff --git a/tooling/client/domain/heapprofiler_client.h b/tooling/client/domain/heapprofiler_client.h index bb4f99f0..b1071756 100644 --- a/tooling/client/domain/heapprofiler_client.h +++ b/tooling/client/domain/heapprofiler_client.h @@ -38,18 +38,18 @@ enum HeapProfilerEvent { }; class HeapProfilerClient final { public: - HeapProfilerClient() = default; + HeapProfilerClient(uint32_t sessionId) : sessionId_(sessionId) {} ~HeapProfilerClient() = default; - bool DispatcherCmd(int id, const std::string &cmd, const std::string &arg, std::string* reqStr); - std::string HeapDumpCommand(int id); - std::string AllocationTrackCommand(int id); - std::string AllocationTrackStopCommand(int id); - std::string Enable(int id); - std::string Disable(int id); - std::string Samping(int id); - std::string SampingStop(int id); - std::string CollectGarbage(int id); + bool DispatcherCmd(const std::string &cmd, const std::string &arg); + int HeapDumpCommand(); + int AllocationTrackCommand(); + int AllocationTrackStopCommand(); + int Enable(); + int Disable(); + int Samping(); + int SampingStop(); + int CollectGarbage(); void RecvReply(std::unique_ptr json); bool WriteHeapProfilerForFile(const std::string &fileName, const std::string &data); @@ -58,6 +58,7 @@ private: std::map idEventMap_; std::string path_; bool isAllocationMsg_ {false}; + uint32_t sessionId_; }; } // OHOS::ArkCompiler::Toolchain #endif \ No newline at end of file diff --git a/tooling/client/domain/profiler_client.cpp b/tooling/client/domain/profiler_client.cpp index f56b7954..6221d946 100644 --- a/tooling/client/domain/profiler_client.cpp +++ b/tooling/client/domain/profiler_client.cpp @@ -17,6 +17,7 @@ #include "tooling/base/pt_types.h" #include "common/log_wrapper.h" #include "tooling/client/utils/utils.h" +#include "tooling/client/session/session.h" #include #include @@ -26,30 +27,31 @@ using Result = panda::ecmascript::tooling::Result; using Profile = panda::ecmascript::tooling::Profile; namespace OHOS::ArkCompiler::Toolchain { -ProfilerSingleton ProfilerSingleton::instance_; -bool ProfilerClient::DispatcherCmd(int id, const std::string &cmd, std::string* reqStr) +bool ProfilerClient::DispatcherCmd(const std::string &cmd) { - std::map> dispatcherTable { - { "cpuprofile", std::bind(&ProfilerClient::CpuprofileCommand, this, id)}, - { "cpuprofile-stop", std::bind(&ProfilerClient::CpuprofileStopCommand, this, id)}, - { "cpuprofile-setSamplingInterval", std::bind(&ProfilerClient::SetSamplingIntervalCommand, this, id)}, - { "cpuprofile-enable", std::bind(&ProfilerClient::CpuprofileEnableCommand, this, id)}, - { "cpuprofile-disable", std::bind(&ProfilerClient::CpuprofileDisableCommand, this, id)}, + std::map> dispatcherTable { + { "cpuprofile", std::bind(&ProfilerClient::CpuprofileCommand, this)}, + { "cpuprofile-stop", std::bind(&ProfilerClient::CpuprofileStopCommand, this)}, + { "cpuprofile-setSamplingInterval", std::bind(&ProfilerClient::SetSamplingIntervalCommand, this)}, + { "cpuprofile-enable", std::bind(&ProfilerClient::CpuprofileEnableCommand, this)}, + { "cpuprofile-disable", std::bind(&ProfilerClient::CpuprofileDisableCommand, this)}, }; auto entry = dispatcherTable.find(cmd); if (entry == dispatcherTable.end()) { - *reqStr = "Unknown commond: " + cmd; - LOGI("DispatcherCmd reqStr2: %{public}s", reqStr->c_str()); + LOGI("Unknown commond: %{public}s", cmd.c_str()); return false; } - *reqStr = entry->second(); - LOGI("DispatcherCmd reqStr1: %{public}s", reqStr->c_str()); + entry->second(); + LOGI("DispatcherCmd cmd: %{public}s", cmd.c_str()); return true; } -std::string ProfilerClient::CpuprofileEnableCommand(int id) +int ProfilerClient::CpuprofileEnableCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, "cpuprofileenable"); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -57,11 +59,19 @@ std::string ProfilerClient::CpuprofileEnableCommand(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Profiler"); + } + return 0; } -std::string ProfilerClient::CpuprofileDisableCommand(int id) +int ProfilerClient::CpuprofileDisableCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, "cpuprofiledisable"); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -69,11 +79,19 @@ std::string ProfilerClient::CpuprofileDisableCommand(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Profiler"); + } + return 0; } -std::string ProfilerClient::CpuprofileCommand(int id) +int ProfilerClient::CpuprofileCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, "cpuprofile"); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -81,11 +99,19 @@ std::string ProfilerClient::CpuprofileCommand(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Profiler"); + } + return 0; } -std::string ProfilerClient::CpuprofileStopCommand(int id) +int ProfilerClient::CpuprofileStopCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, "cpuprofilestop"); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -93,11 +119,19 @@ std::string ProfilerClient::CpuprofileStopCommand(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Profiler"); + } + return 0; } -std::string ProfilerClient::SetSamplingIntervalCommand(int id) +int ProfilerClient::SetSamplingIntervalCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idEventMap_.emplace(id, "setsamplinginterval"); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -106,12 +140,12 @@ std::string ProfilerClient::SetSamplingIntervalCommand(int id) std::unique_ptr params = PtJson::CreateObject(); params->Add("interval", interval_); request->Add("params", params); - return request->Stringify(); -} -ProfilerSingleton& ProfilerSingleton::GetInstance() -{ - return instance_; + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Profiler"); + } + return 0; } void ProfilerClient::RecvProfilerResult(std::unique_ptr json) @@ -149,10 +183,12 @@ void ProfilerClient::RecvProfilerResult(std::unique_ptr json) return; } - ProfilerSingleton& pro = ProfilerSingleton::GetInstance(); - std::string fileName = "CPU-" + std::string(date) + "T" + std::string(time) + ".cpuprofile"; + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + ProfilerSingleton &pro = session->GetProfilerSingleton(); + std::string fileName = "CPU-" + std::to_string(sessionId_) + "-" + std::string(date) + "T" + std::string(time) + + ".cpuprofile"; std::string cpufile = pro.GetAddress() + fileName; - std::cout << "cpuprofile file name is " << cpufile << std::endl; + std::cout << "session " << sessionId_ << " cpuprofile file name is " << cpufile << std::endl; std::cout << ">>> "; fflush(stdout); WriteCpuProfileForFile(cpufile, profile->Stringify()); @@ -171,7 +207,8 @@ bool ProfilerClient::WriteCpuProfileForFile(const std::string &fileName, const s ofs.write(data.c_str(), strSize); ofs.close(); ofs.clear(); - ProfilerSingleton& pro = ProfilerSingleton::GetInstance(); + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + ProfilerSingleton &pro = session->GetProfilerSingleton(); pro.SetAddress(""); return true; } diff --git a/tooling/client/domain/profiler_client.h b/tooling/client/domain/profiler_client.h index 7f2ee833..5c1681b7 100644 --- a/tooling/client/domain/profiler_client.h +++ b/tooling/client/domain/profiler_client.h @@ -27,7 +27,7 @@ namespace OHOS::ArkCompiler::Toolchain { using PtJson = panda::ecmascript::tooling::PtJson; class ProfilerSingleton { public: - static ProfilerSingleton& GetInstance(); + ProfilerSingleton() = default; void AddCpuName(const std::string &data) { @@ -55,29 +55,28 @@ public: private: std::vector cpulist_; std::string address_ = ""; - static ProfilerSingleton instance_; - ProfilerSingleton() = default; ProfilerSingleton(const ProfilerSingleton&) = delete; ProfilerSingleton& operator=(const ProfilerSingleton&) = delete; }; class ProfilerClient final { public: - ProfilerClient() = default; + ProfilerClient(uint32_t sessionId) : sessionId_(sessionId) {} ~ProfilerClient() = default; - bool DispatcherCmd(int id, const std::string &cmd, std::string* reqStr); - std::string CpuprofileCommand(int id); - std::string CpuprofileStopCommand(int id); - std::string SetSamplingIntervalCommand(int id); - std::string CpuprofileEnableCommand(int id); - std::string CpuprofileDisableCommand(int id); + bool DispatcherCmd(const std::string &cmd); + int CpuprofileCommand(); + int CpuprofileStopCommand(); + int SetSamplingIntervalCommand(); + int CpuprofileEnableCommand(); + int CpuprofileDisableCommand(); bool WriteCpuProfileForFile(const std::string &fileName, const std::string &data); void RecvProfilerResult(std::unique_ptr json); void SetSamplingInterval(int interval); private: int32_t interval_ = 0; + int32_t sessionId_; std::map idEventMap_ {}; }; } // OHOS::ArkCompiler::Toolchain diff --git a/tooling/client/domain/runtime_client.cpp b/tooling/client/domain/runtime_client.cpp index 3731c4dd..33ca8e51 100644 --- a/tooling/client/domain/runtime_client.cpp +++ b/tooling/client/domain/runtime_client.cpp @@ -18,34 +18,37 @@ #include "common/log_wrapper.h" #include "tooling/client/manager/variable_manager.h" #include "tooling/base/pt_json.h" +#include "tooling/client/session/session.h" using PtJson = panda::ecmascript::tooling::PtJson; namespace OHOS::ArkCompiler::Toolchain { -bool RuntimeClient::DispatcherCmd(int id, const std::string &cmd, std::string* reqStr) +bool RuntimeClient::DispatcherCmd(const std::string &cmd) { - std::map> dispatcherTable { - { "heapusage", std::bind(&RuntimeClient::HeapusageCommand, this, id)}, - { "runtime-enable", std::bind(&RuntimeClient::RuntimeEnableCommand, this, id)}, - { "runtime-disable", std::bind(&RuntimeClient::RuntimeDisableCommand, this, id)}, - { "print", std::bind(&RuntimeClient::GetPropertiesCommand, this, id)}, - { "print2", std::bind(&RuntimeClient::GetPropertiesCommand2, this, id)}, - { "run", std::bind(&RuntimeClient::RunIfWaitingForDebuggerCommand, this, id)}, + std::map> dispatcherTable { + { "heapusage", std::bind(&RuntimeClient::HeapusageCommand, this)}, + { "runtime-enable", std::bind(&RuntimeClient::RuntimeEnableCommand, this)}, + { "runtime-disable", std::bind(&RuntimeClient::RuntimeDisableCommand, this)}, + { "print", std::bind(&RuntimeClient::GetPropertiesCommand, this)}, + { "print2", std::bind(&RuntimeClient::GetPropertiesCommand2, this)}, + { "run", std::bind(&RuntimeClient::RunIfWaitingForDebuggerCommand, this)}, }; auto entry = dispatcherTable.find(cmd); if (entry != dispatcherTable.end()) { - *reqStr = entry->second(); - LOGI("RuntimeClient DispatcherCmd reqStr1: %{public}s", reqStr->c_str()); + entry->second(); + LOGI("RuntimeClient DispatcherCmd reqStr1: %{public}s", cmd.c_str()); return true; } else { - *reqStr = "Unknown commond: " + cmd; - LOGI("RuntimeClient DispatcherCmd reqStr2: %{public}s", reqStr->c_str()); + LOGI("Unknown commond: %{public}s", cmd.c_str()); return false; } } -std::string RuntimeClient::HeapusageCommand(int id) +int RuntimeClient::HeapusageCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idMethodMap_[id] = std::make_tuple("getHeapUsage", ""); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -53,11 +56,19 @@ std::string RuntimeClient::HeapusageCommand(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Runtime"); + } + return 0; } -std::string RuntimeClient::RuntimeEnableCommand(int id) +int RuntimeClient::RuntimeEnableCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idMethodMap_[id] = std::make_tuple("enable", ""); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -65,11 +76,19 @@ std::string RuntimeClient::RuntimeEnableCommand(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Runtime"); + } + return 0; } -std::string RuntimeClient::RuntimeDisableCommand(int id) +int RuntimeClient::RuntimeDisableCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idMethodMap_[id] = std::make_tuple("disable", ""); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -77,11 +96,19 @@ std::string RuntimeClient::RuntimeDisableCommand(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Runtime"); + } + return 0; } -std::string RuntimeClient::RunIfWaitingForDebuggerCommand(int id) +int RuntimeClient::RunIfWaitingForDebuggerCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idMethodMap_[id] = std::make_tuple("runIfWaitingForDebugger", ""); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -89,11 +116,19 @@ std::string RuntimeClient::RunIfWaitingForDebuggerCommand(int id) std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Runtime"); + } + return 0; } -std::string RuntimeClient::GetPropertiesCommand(int id) +int RuntimeClient::GetPropertiesCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idMethodMap_[id] = std::make_tuple("getProperties", objectId_); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -105,11 +140,19 @@ std::string RuntimeClient::GetPropertiesCommand(int id) params->Add("objectId", objectId_.c_str()); params->Add("ownProperties", true); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Runtime"); + } + return 0; } -std::string RuntimeClient::GetPropertiesCommand2(int id) +int RuntimeClient::GetPropertiesCommand2() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + idMethodMap_[id] = std::make_tuple("getProperties", objectId_); std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); @@ -121,7 +164,12 @@ std::string RuntimeClient::GetPropertiesCommand2(int id) params->Add("objectId", "0"); params->Add("ownProperties", false); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Runtime"); + } + return 0; } void RuntimeClient::RecvReply(std::unique_ptr json) @@ -198,8 +246,9 @@ void RuntimeClient::HandleGetProperties(std::unique_ptr json, const int return; } - StackManager &stackManager = StackManager::GetInstance(); - VariableManager &variableManager = VariableManager::GetInstance(); + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + StackManager &stackManager = session->GetStackManager(); + VariableManager &variableManager = session->GetVariableManager(); std::map> treeInfo = stackManager.GetScopeChainInfo(); if (isInitializeTree_) { variableManager.ClearVariableInfo(); @@ -242,7 +291,8 @@ void RuntimeClient::HandleHeapUsage(std::unique_ptr json) return; } - VariableManager &variableManager = VariableManager::GetInstance(); + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + VariableManager &variableManager = session->GetVariableManager(); std::unique_ptr heapUsageReturns = GetHeapUsageReturns::Create(*result); variableManager.SetHeapUsageInfo(std::move(heapUsageReturns)); variableManager.ShowHeapUsageInfo(); diff --git a/tooling/client/domain/runtime_client.h b/tooling/client/domain/runtime_client.h index 3d428c19..12e12705 100644 --- a/tooling/client/domain/runtime_client.h +++ b/tooling/client/domain/runtime_client.h @@ -26,16 +26,16 @@ using Result = panda::ecmascript::tooling::Result; namespace OHOS::ArkCompiler::Toolchain { class RuntimeClient final { public: - RuntimeClient() = default; + RuntimeClient(int32_t sessionId) : sessionId_(sessionId) {} ~RuntimeClient() = default; - bool DispatcherCmd(int id, const std::string &cmd, std::string *reqStr); - std::string HeapusageCommand(int id); - std::string RuntimeEnableCommand(int id); - std::string RuntimeDisableCommand(int id); - std::string RunIfWaitingForDebuggerCommand(int id); - std::string GetPropertiesCommand(int id); - std::string GetPropertiesCommand2(int id); + bool DispatcherCmd(const std::string &cmd); + int HeapusageCommand(); + int RuntimeEnableCommand(); + int RuntimeDisableCommand(); + int RunIfWaitingForDebuggerCommand(); + int GetPropertiesCommand(); + int GetPropertiesCommand2(); std::string GetMethodById(const int &id); std::string GetRequestObjectIdById(const int &id); void RecvReply(std::unique_ptr json); @@ -61,6 +61,7 @@ private: std::map> idMethodMap_ {}; std::string objectId_ {"0"}; bool isInitializeTree_ {true}; + int32_t sessionId_; }; } // OHOS::ArkCompiler::Toolchain #endif \ No newline at end of file diff --git a/tooling/client/domain/test_client.cpp b/tooling/client/domain/test_client.cpp index 66355941..40439be0 100644 --- a/tooling/client/domain/test_client.cpp +++ b/tooling/client/domain/test_client.cpp @@ -18,47 +18,63 @@ #include "common/log_wrapper.h" #include "tooling/client/manager/variable_manager.h" #include "tooling/base/pt_json.h" +#include "tooling/client/session/session.h" using PtJson = panda::ecmascript::tooling::PtJson; namespace OHOS::ArkCompiler::Toolchain { -bool TestClient::DispatcherCmd(int id, const std::string &cmd, std::string* reqStr) +bool TestClient::DispatcherCmd(const std::string &cmd) { - std::map> dispatcherTable { - { "success", std::bind(&TestClient::SuccessCommand, this, id)}, - { "fail", std::bind(&TestClient::FailCommand, this, id)}, + std::map> dispatcherTable { + { "success", std::bind(&TestClient::SuccessCommand, this)}, + { "fail", std::bind(&TestClient::FailCommand, this)}, }; auto entry = dispatcherTable.find(cmd); if (entry != dispatcherTable.end()) { - *reqStr = entry->second(); - LOGI("TestClient DispatcherCmd reqStr1: %{public}s", reqStr->c_str()); + entry->second(); + LOGI("TestClient DispatcherCmd cmd: %{public}s", cmd.c_str()); return true; } else { - *reqStr = "Unknown commond: " + cmd; - LOGI("TestClient DispatcherCmd reqStr2: %{public}s", reqStr->c_str()); + LOGI("Unknown commond: %{public}s", cmd.c_str()); return false; } } -std::string TestClient::SuccessCommand(int id) +int TestClient::SuccessCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); request->Add("method", "Test.success"); std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Test"); + } + return 0; } -std::string TestClient::FailCommand(int id) +int TestClient::FailCommand() { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + uint32_t id = session->GetMessageId(); + std::unique_ptr request = PtJson::CreateObject(); request->Add("id", id); request->Add("method", "Test.fail"); std::unique_ptr params = PtJson::CreateObject(); request->Add("params", params); - return request->Stringify(); + + std::string message = request->Stringify(); + if (session->ClientSendReq(message)) { + session->GetDomainManager().SetDomainById(id, "Test"); + } + return 0; } } // OHOS::ArkCompiler::Toolchain \ No newline at end of file diff --git a/tooling/client/domain/test_client.h b/tooling/client/domain/test_client.h index c46b6667..6a768730 100644 --- a/tooling/client/domain/test_client.h +++ b/tooling/client/domain/test_client.h @@ -26,12 +26,15 @@ using Result = panda::ecmascript::tooling::Result; namespace OHOS::ArkCompiler::Toolchain { class TestClient final { public: - TestClient() = default; + TestClient(uint32_t sessionId) : sessionId_(sessionId) {} ~TestClient() = default; - bool DispatcherCmd(int id, const std::string &cmd, std::string *reqStr); - std::string SuccessCommand(int id); - std::string FailCommand(int id); + bool DispatcherCmd(const std::string &cmd); + int SuccessCommand(); + int FailCommand(); + +private: + uint32_t sessionId_; }; } // OHOS::ArkCompiler::Toolchain #endif // ECMASCRIPT_TOOLING_CLIENT_DOMAIN_TEST_CLIENT_H \ No newline at end of file diff --git a/tooling/client/manager/breakpoint_manager.cpp b/tooling/client/manager/breakpoint_manager.cpp index 83b94a55..c143ef6a 100644 --- a/tooling/client/manager/breakpoint_manager.cpp +++ b/tooling/client/manager/breakpoint_manager.cpp @@ -17,16 +17,11 @@ #include "common/log_wrapper.h" #include "tooling/client/utils/utils.h" +#include "tooling/client/session/session.h" using PtJson = panda::ecmascript::tooling::PtJson; using Result = panda::ecmascript::tooling::Result; namespace OHOS::ArkCompiler::Toolchain { -BreakPointManager BreakPointManager::instance_; -BreakPointManager& BreakPointManager::GetInstance() -{ - return instance_; -} - void BreakPointManager::Createbreaklocation(const std::unique_ptr json) { if (json == nullptr) { diff --git a/tooling/client/manager/breakpoint_manager.h b/tooling/client/manager/breakpoint_manager.h index 115702b3..76958898 100644 --- a/tooling/client/manager/breakpoint_manager.h +++ b/tooling/client/manager/breakpoint_manager.h @@ -36,7 +36,7 @@ struct Breaklocation { }; class BreakPointManager { public: - static BreakPointManager& GetInstance(); + BreakPointManager(int32_t sessionId) : sessionId_(sessionId) {} void Createbreaklocation(const std::unique_ptr json); void Show(); @@ -44,9 +44,8 @@ public: std::vector Getbreaklist() const; private: - static BreakPointManager instance_; + [[maybe_unused]] int32_t sessionId_; std::vector breaklist_ {}; - BreakPointManager() = default; BreakPointManager(const BreakPointManager&) = delete; BreakPointManager& operator=(const BreakPointManager&) = delete; }; diff --git a/tooling/client/manager/domain_manager.cpp b/tooling/client/manager/domain_manager.cpp index 75a35546..92464890 100644 --- a/tooling/client/manager/domain_manager.cpp +++ b/tooling/client/manager/domain_manager.cpp @@ -18,10 +18,17 @@ #include "common/log_wrapper.h" #include "tooling/client/manager/breakpoint_manager.h" #include "tooling/base/pt_json.h" +#include "tooling/client/session/session.h" using PtJson = panda::ecmascript::tooling::PtJson; using Result = panda::ecmascript::tooling::Result; namespace OHOS::ArkCompiler::Toolchain { +DomainManager::DomainManager(uint32_t sessionId) + : sessionId_(sessionId), heapProfilerClient_(sessionId), profilerClient_(sessionId), + debuggerClient_(sessionId), runtimeClient_(sessionId), testClient_(sessionId) +{ +} + void DomainManager::DispatcherReply(char* msg) { std::string decMessage = std::string(msg); diff --git a/tooling/client/manager/domain_manager.h b/tooling/client/manager/domain_manager.h index 0c6dc586..893a2fe3 100644 --- a/tooling/client/manager/domain_manager.h +++ b/tooling/client/manager/domain_manager.h @@ -27,7 +27,7 @@ namespace OHOS::ArkCompiler::Toolchain { class DomainManager { public: - DomainManager() = default; + explicit DomainManager(uint32_t sessionId); ~DomainManager() = default; void DispatcherReply(char* msg); @@ -80,11 +80,12 @@ public: } private: - HeapProfilerClient heapProfilerClient_ {}; - ProfilerClient profilerClient_ {}; - DebuggerClient debuggerClient_ {}; - RuntimeClient runtimeClient_ {}; - TestClient testClient_ {}; + [[maybe_unused]] uint32_t sessionId_; + HeapProfilerClient heapProfilerClient_; + ProfilerClient profilerClient_; + DebuggerClient debuggerClient_; + RuntimeClient runtimeClient_; + TestClient testClient_; std::map idDomainMap_ {}; }; } // OHOS::ArkCompiler::Toolchain diff --git a/tooling/client/manager/message_manager.h b/tooling/client/manager/message_manager.h new file mode 100755 index 00000000..028dced8 --- /dev/null +++ b/tooling/client/manager/message_manager.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ECMASCRIPT_TOOLING_CLIENT_MANAGER_MESSAGE_MANAGER_H +#define ECMASCRIPT_TOOLING_CLIENT_MANAGER_MESSAGE_MANAGER_H + +#include + +namespace OHOS::ArkCompiler::Toolchain { +class MessageManager final { +public: + ~MessageManager() + { + uv_mutex_destroy(&messageMutex_); + } + + static MessageManager& getInstance() + { + static MessageManager instance; + return instance; + } + + void MessagePush(uint32_t sessionId, std::string& message) + { + uv_mutex_lock(&messageMutex_); + messageQue_.push(std::make_pair(sessionId, message)); + uv_mutex_unlock(&messageMutex_); + } + + bool MessagePop(uint32_t& sessionId, std::string& message) + { + uv_mutex_lock(&messageMutex_); + if (messageQue_.empty()) { + uv_mutex_unlock(&messageMutex_); + return false; + } + + sessionId = messageQue_.front().first; + message = messageQue_.front().second; + messageQue_.pop(); + + uv_mutex_unlock(&messageMutex_); + return true; + } + +private: + MessageManager() + { + uv_mutex_init(&messageMutex_); + } + MessageManager(const MessageManager&) = delete; + MessageManager& operator=(const MessageManager&) = delete; + + uv_mutex_t messageMutex_; + std::queue> messageQue_; +}; +} // OHOS::ArkCompiler::Toolchain +#endif \ No newline at end of file diff --git a/tooling/client/manager/stack_manager.cpp b/tooling/client/manager/stack_manager.cpp index 0dd28a25..a9940cb5 100644 --- a/tooling/client/manager/stack_manager.cpp +++ b/tooling/client/manager/stack_manager.cpp @@ -15,14 +15,9 @@ #include "tooling/client/manager/stack_manager.h" #include "common/log_wrapper.h" +#include "tooling/client/session/session.h" namespace OHOS::ArkCompiler::Toolchain { -StackManager StackManager::instance_; -StackManager& StackManager::GetInstance() -{ - return instance_; -} - void StackManager::SetCallFrames(std::map> callFrames) { for (auto &callFrame : callFrames) { diff --git a/tooling/client/manager/stack_manager.h b/tooling/client/manager/stack_manager.h index bca47157..99c65e32 100644 --- a/tooling/client/manager/stack_manager.h +++ b/tooling/client/manager/stack_manager.h @@ -30,7 +30,7 @@ using Scope = panda::ecmascript::tooling::Scope; namespace OHOS::ArkCompiler::Toolchain { class StackManager final { public: - static StackManager& GetInstance(); + StackManager(int32_t sessionId) : sessionId_(sessionId) {} std::map> GetScopeChainInfo(); void SetCallFrames(std::map> callFrames); @@ -39,9 +39,8 @@ public: void PrintScopeChainInfo(const std::map>& scopeInfos); private: - static StackManager instance_; + [[maybe_unused]] int32_t sessionId_; std::map> callFrames_ {}; - StackManager() = default; StackManager(const StackManager&) = delete; StackManager& operator=(const StackManager&) = delete; }; diff --git a/tooling/client/manager/variable_manager.cpp b/tooling/client/manager/variable_manager.cpp index 08b2cf3b..38e3b259 100644 --- a/tooling/client/manager/variable_manager.cpp +++ b/tooling/client/manager/variable_manager.cpp @@ -21,7 +21,6 @@ using PtJson = panda::ecmascript::tooling::PtJson; namespace OHOS::ArkCompiler::Toolchain { -VariableManager VariableManager::instance_; void TreeNode::AddChild(std::unique_ptr descriptor) { children.push_back(std::make_unique(std::move(descriptor))); @@ -253,11 +252,6 @@ int32_t Tree::FindObjectByIndexRecursive(const TreeNode* node, int32_t index) co return 0; } -VariableManager& VariableManager::GetInstance() -{ - return instance_; -} - void VariableManager::SetHeapUsageInfo(std::unique_ptr heapUsageReturns) { heapUsageInfo_.SetUsedSize(heapUsageReturns->GetUsedSize()); diff --git a/tooling/client/manager/variable_manager.h b/tooling/client/manager/variable_manager.h index 0b4eaacc..7bd72b7e 100644 --- a/tooling/client/manager/variable_manager.h +++ b/tooling/client/manager/variable_manager.h @@ -74,7 +74,7 @@ private: class VariableManager final { public: - static VariableManager& GetInstance(); + VariableManager(int32_t sessionId) : sessionId_(sessionId) {} void SetHeapUsageInfo(std::unique_ptr heapUsageReturns); void ShowHeapUsageInfo() const; void ShowVariableInfos() const; @@ -88,8 +88,7 @@ public: void Printinfo() const; private: - VariableManager() = default; - static VariableManager instance_; + [[maybe_unused]] int32_t sessionId_; GetHeapUsageReturns heapUsageInfo_ {}; Tree variableInfo_ {0}; VariableManager(const VariableManager&) = delete; diff --git a/tooling/client/session/session.cpp b/tooling/client/session/session.cpp new file mode 100755 index 00000000..d3f6cd00 --- /dev/null +++ b/tooling/client/session/session.cpp @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tooling/client/session/session.h" + +#include "common/log_wrapper.h" +#include "tooling/client/manager/message_manager.h" +#include "tooling/base/pt_json.h" +#include "tooling/client/utils/utils.h" + +#include + +using PtJson = panda::ecmascript::tooling::PtJson; +using Result = panda::ecmascript::tooling::Result; +namespace OHOS::ArkCompiler::Toolchain { +uv_async_t* g_socketSignal; +void SocketMessageThread(void *arg) +{ + int sessionId = *(uint32_t *)arg; + Session *session = SessionManager::getInstance().GetSessionById(sessionId); + + session->SocketMessageLoop(); +} + +Session::Session(uint32_t sessionId, std::string& sockInfo) + : sessionId_(sessionId), sockInfo_(sockInfo), domainManager_(sessionId), breakpoint_(sessionId), + stackManager_(sessionId), variableManager_(sessionId) +{ +} + +void Session::SocketMessageLoop() +{ + while (cliSocket_.IsConnected()) { + std::string decMessage = cliSocket_.Decode(); + uint32_t len = decMessage.length(); + if (len == 0) { + continue; + } + LOGI("arkdb [%{public}u] message = %{public}s", sessionId_, decMessage.c_str()); + + MessageManager::getInstance().MessagePush(sessionId_, decMessage); + + if (uv_is_active(reinterpret_cast(g_socketSignal))) { + uv_async_send(g_socketSignal); + } + } +} + +int Session::CreateSocket() +{ + uint32_t port = 0; + if (Utils::StrToUInt(sockInfo_.c_str(), &port)) { + if ((port <= 0) || (port >= 65535)) { // 65535: max port + LOGE("arkdb:InitToolchainWebSocketForPort the port = %{public}d is wrong.", port); + return -1; + } + if (!cliSocket_.InitToolchainWebSocketForPort(port, 5)) { // 5: five times + LOGE("arkdb:InitToolchainWebSocketForPort failed"); + return -1; + } + } else { + if (!cliSocket_.InitToolchainWebSocketForSockName(sockInfo_)) { + LOGE("arkdb:InitToolchainWebSocketForSockName failed"); + return -1; + } + } + + if (!cliSocket_.ClientSendWSUpgradeReq()) { + LOGE("arkdb:ClientSendWSUpgradeReq failed"); + return -1; + } + if (!cliSocket_.ClientRecvWSUpgradeRsp()) { + LOGE("arkdb:ClientRecvWSUpgradeRsp failed"); + return -1; + } + + return 0; +} + +int Session::Start() +{ + if (CreateSocket()) { + return -1; + } + + uv_thread_create(&socketTid_, SocketMessageThread, &sessionId_); + return 0; +} + +int Session::Stop() +{ + cliSocket_.Close(); + return 0; +} + +int SessionManager::CreateSessionById(uint32_t sessionId, std::string& sockInfo) +{ + sessions_[sessionId] = std::make_unique(sessionId, sockInfo); + if (sessions_[sessionId]->Start()) { + sessions_[sessionId] = nullptr; + return -1; + } + + return 0; +} + +int SessionManager::CreateNewSession(std::string& sockInfo) +{ + uint32_t sessionId = MAX_SESSION_NUM; + for (uint32_t i = 0; i < MAX_SESSION_NUM; ++i) { + if (sessions_[i] == nullptr) { + if (sessionId == MAX_SESSION_NUM) { + sessionId = i; + } + continue; + } + if (sessions_[i]->GetSockInfo() == sockInfo) { + return -1; + } + } + + if (sessionId < MAX_SESSION_NUM) { + return CreateSessionById(sessionId, sockInfo); + } + + return -1; +} + +int SessionManager::CreateDefaultSession(std::string& sockInfo) +{ + return CreateSessionById(0, sockInfo); +} + +int SessionManager::DelSessionById(uint32_t sessionId) +{ + Session *session = GetSessionById(sessionId); + if (session == nullptr) { + return -1; + } + session->Stop(); + sessions_[sessionId] = nullptr; + + if (sessionId == currentSessionId_) { + currentSessionId_ = 0; + std::cout << "session switch to 0" << std::endl; + } + + return 0; +} + +int SessionManager::SessionList() +{ + for (uint32_t i = 0; i < MAX_SESSION_NUM; ++i) { + if (sessions_[i] != nullptr) { + std::string flag = (i == currentSessionId_) ? "* " : " "; + std::string sockState = sessions_[i]->GetSocketStateString(); + std::cout << flag << i << ": "; + std::cout << std::setw(32) << std::left << sessions_[i]->GetSockInfo(); // 32: max length of socket info + std::cout << sockState << std::endl; + } + } + return 0; +} + +int SessionManager::SessionSwitch(uint32_t sessionId) +{ + Session *session = GetSessionById(sessionId); + if (session == nullptr) { + return -1; + } + currentSessionId_ = sessionId; + return 0; +} + +void SessionManager::CmdForAllSessions(CmdForAllCB callback) +{ + for (uint32_t sessionId = 0; sessionId < MAX_SESSION_NUM; ++sessionId) { + if (sessions_[sessionId] != nullptr) { + std::cout << "Executing command in session " << sessionId << ":" << std::endl; + callback(sessionId); + } + } +} + +int SessionManager::CreateTestSession(std::string& sockInfo) +{ + uint32_t sessionId = 0; + sessions_[sessionId] = std::make_unique(sessionId, sockInfo); + if (sessions_[sessionId]->CreateSocket()) { + sessions_[sessionId] = nullptr; + return -1; + } + + return 0; +} +} \ No newline at end of file diff --git a/tooling/client/session/session.h b/tooling/client/session/session.h new file mode 100755 index 00000000..b577fa13 --- /dev/null +++ b/tooling/client/session/session.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ECMASCRIPT_TOOLING_CLIENT_SESSION_H +#define ECMASCRIPT_TOOLING_CLIENT_SESSION_H + +#include +#include +#include +#include +#include +#include +#include + +#include "tooling/client/manager/domain_manager.h" +#include "tooling/client/manager/breakpoint_manager.h" +#include "tooling/client/manager/stack_manager.h" +#include "tooling/client/manager/variable_manager.h" +#include "tooling/client/websocket/websocket_client.h" + +namespace OHOS::ArkCompiler::Toolchain { +using CmdForAllCB = std::function; +extern uv_async_t* g_socketSignal; +class Session { +public: + explicit Session(uint32_t sessionId, std::string& sockInfo); + ~Session() + { + Stop(); + } + + void SocketMessageLoop(); + int CreateSocket(); + int Start(); + int Stop(); + void CmdForAllSession(CmdForAllCB callback); + + uint32_t GetMessageId() + { + return messageId_.fetch_add(1); + } + + std::string& GetSockInfo() + { + return sockInfo_; + } + + bool ClientSendReq(const std::string &message) + { + return cliSocket_.ClientSendReq(message); + } + + DomainManager& GetDomainManager() + { + return domainManager_; + } + + BreakPointManager& GetBreakPointManager() + { + return breakpoint_; + } + + StackManager& GetStackManager() + { + return stackManager_; + } + + VariableManager& GetVariableManager() + { + return variableManager_; + } + + WebsocketClient& GetWebsocketClient() + { + return cliSocket_; + } + + ProfilerSingleton& GetProfilerSingleton() + { + return profiler_; + } + + std::string GetSocketStateString() + { + return cliSocket_.GetSocketStateString(); + } + + void ProcSocketMsg(char* msg) + { + domainManager_.DispatcherReply(msg); + } + +private: + uint32_t sessionId_; + std::string sockInfo_; + DomainManager domainManager_; + WebsocketClient cliSocket_; + uv_thread_t socketTid_; + std::atomic messageId_ {1}; + BreakPointManager breakpoint_; + StackManager stackManager_; + VariableManager variableManager_; + ProfilerSingleton profiler_; +}; + +constexpr uint32_t MAX_SESSION_NUM = 8; +class SessionManager { +public: + static SessionManager& getInstance() + { + static SessionManager instance; + return instance; + } + + uint32_t GetCurrentSessionId() + { + return currentSessionId_; + } + + Session *GetCurrentSession() + { + if (currentSessionId_ >= MAX_SESSION_NUM || sessions_[currentSessionId_] == nullptr) { + return nullptr; + } + return sessions_[currentSessionId_].get(); + } + + Session *GetSessionById(uint32_t sessionId) + { + if (sessionId >= MAX_SESSION_NUM || sessions_[sessionId] == nullptr) { + return nullptr; + } + return sessions_[sessionId].get(); + } + + int CreateSessionById(uint32_t sessionId, std::string& sockInfo); + int CreateNewSession(std::string& sockInfo); + int CreateDefaultSession(std::string& sockInfo); + int DelSessionById(uint32_t sessionId); + int SessionList(); + int SessionSwitch(uint32_t sessionId); + void CmdForAllSessions(CmdForAllCB callback); + int CreateTestSession(std::string& sockInfo); + +private: + SessionManager() = default; + SessionManager(const SessionManager&) = delete; + SessionManager& operator=(const SessionManager&) = delete; + + std::unique_ptr sessions_[MAX_SESSION_NUM]; + uint32_t currentSessionId_ = 0; +}; +} // namespace OHOS::ArkCompiler::Toolchain +#endif \ No newline at end of file diff --git a/tooling/client/utils/cli_command.cpp b/tooling/client/utils/cli_command.cpp index 686ef585..501a052a 100644 --- a/tooling/client/utils/cli_command.cpp +++ b/tooling/client/utils/cli_command.cpp @@ -25,6 +25,7 @@ #include "tooling/client/manager/domain_manager.h" #include "tooling/client/manager/stack_manager.h" #include "tooling/client/manager/variable_manager.h" +#include "tooling/client/session/session.h" namespace OHOS::ArkCompiler::Toolchain { const std::string HELP_MSG = "usage: \n" @@ -75,6 +76,11 @@ const std::string HELP_MSG = "usage: \n" " step-out(so) step-out\n" " step-over(sov) step-over\n" " runtime-disable rt-disable\n" + " session-new add new session\n" + " session-remove del a session\n" + " session-list list all sessions\n" + " session switch session\n" + " forall command for all sessions\n" " success test success\n" " fail test fail\n"; @@ -123,6 +129,10 @@ const std::vector cmdList = { "step-out", "step-over", "runtime-disable", + "session-new", + "session-remove", + "session-list", + "session", "success", "fail" }; @@ -194,6 +204,14 @@ void CliCommand::CreateCommandMap() {std::make_pair("step-over", "sov"), std::bind(&CliCommand::DebuggerCommand, this, "step-over")}, {std::make_pair("runtime-disable", "rt-disable"), std::bind(&CliCommand::RuntimeCommand, this, "runtime-disable")}, + {std::make_pair("session-new", "session-new"), + std::bind(&CliCommand::SessionAddCommand, this, "session-new")}, + {std::make_pair("session-remove", "session-remove"), + std::bind(&CliCommand::SessionDelCommand, this, "session-remove")}, + {std::make_pair("session-list", "session-list"), + std::bind(&CliCommand::SessionListCommand, this, "session-list")}, + {std::make_pair("session", "session"), + std::bind(&CliCommand::SessionSwitchCommand, this, "session")}, {std::make_pair("success", "success"), std::bind(&CliCommand::TestCommand, this, "success")}, {std::make_pair("fail", "fail"), @@ -204,32 +222,25 @@ void CliCommand::CreateCommandMap() ErrCode CliCommand::HeapProfilerCommand(const std::string &cmd) { std::cout << "exe success, cmd is " << cmd << std::endl; - std::string request; - bool result = false; - HeapProfilerClient &heapProfilerClient = domainManager_.GetHeapProfilerClient(); + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + DomainManager &domainManager = session->GetDomainManager(); + HeapProfilerClient &heapProfilerClient = domainManager.GetHeapProfilerClient(); VecStr argList = GetArgList(); if (argList.empty()) { argList.push_back("/data/"); } - result = heapProfilerClient.DispatcherCmd(id_, cmd, argList[0], &request); - if (result) { - cliSocket_.ClientSendReq(request); - if (domainManager_.GetDomainById(id_).empty()) { - domainManager_.SetDomainById(id_, "HeapProfiler"); - } - } else { - return ErrCode::ERR_FAIL; - } - return ErrCode::ERR_OK; + + bool result = heapProfilerClient.DispatcherCmd(cmd, argList[0]); + return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL; } ErrCode CliCommand::CpuProfileCommand(const std::string &cmd) { std::cout << "exe success, cmd is " << cmd << std::endl; - std::string request; - bool result = false; - ProfilerClient &profilerClient = domainManager_.GetProfilerClient(); - ProfilerSingleton& pro = ProfilerSingleton::GetInstance(); + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + DomainManager &domainManager = session->GetDomainManager(); + ProfilerClient &profilerClient = domainManager.GetProfilerClient(); + ProfilerSingleton &pro = session->GetProfilerSingleton(); if (cmd == "cpuprofile-show") { pro.ShowCpuFile(); return ErrCode::ERR_OK; @@ -240,25 +251,17 @@ ErrCode CliCommand::CpuProfileCommand(const std::string &cmd) if (cmd == "cpuprofile-stop" && GetArgList().size() == 1) { pro.SetAddress(GetArgList()[0]); } - result = profilerClient.DispatcherCmd(id_, cmd, &request); - if (result) { - cliSocket_.ClientSendReq(request); - if (domainManager_.GetDomainById(id_).empty()) { - domainManager_.SetDomainById(id_, "Profiler"); - } - } else { - return ErrCode::ERR_FAIL; - } - return ErrCode::ERR_OK; + bool result = profilerClient.DispatcherCmd(cmd); + return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL; } ErrCode CliCommand::DebuggerCommand(const std::string &cmd) { std::cout << "exe success, cmd is " << cmd << std::endl; - std::string request; bool result = false; - DebuggerClient &debuggerCli = domainManager_.GetDebuggerClient(); - BreakPointManager &breakpoint = BreakPointManager::GetInstance(); + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + DebuggerClient &debuggerCli = session->GetDomainManager().GetDebuggerClient(); + BreakPointManager &breakpoint = session->GetBreakPointManager(); if (cmd == "display") { breakpoint.Show(); return ErrCode::ERR_OK; @@ -276,12 +279,12 @@ ErrCode CliCommand::DebuggerCommand(const std::string &cmd) } if (cmd == "step-into" || cmd == "step-out" || cmd == "step-over") { - RuntimeClient &runtimeClient = domainManager_.GetRuntimeClient(); + RuntimeClient &runtimeClient = session->GetDomainManager().GetRuntimeClient(); runtimeClient.SetIsInitializeTree(true); } if (cmd == "showstack") { - StackManager &stackManager = StackManager::GetInstance(); + StackManager &stackManager = session->GetStackManager(); stackManager.ShowCallFrames(); } @@ -289,58 +292,94 @@ ErrCode CliCommand::DebuggerCommand(const std::string &cmd) debuggerCli.AddBreakPointInfo(GetArgList()[0], std::stoi(GetArgList()[1])); } - result = debuggerCli.DispatcherCmd(id_, cmd, &request); - if (result) { - cliSocket_.ClientSendReq(request); - if (domainManager_.GetDomainById(id_).empty()) { - domainManager_.SetDomainById(id_, "Debugger"); - } - } else { - return ErrCode::ERR_FAIL; - } - return ErrCode::ERR_OK; + result = debuggerCli.DispatcherCmd(cmd); + return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL; } ErrCode CliCommand::RuntimeCommand(const std::string &cmd) { std::cout << "exe success, cmd is " << cmd << std::endl; - std::string request; bool result = false; - RuntimeClient &runtimeClient = domainManager_.GetRuntimeClient(); + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + RuntimeClient &runtimeClient = session->GetDomainManager().GetRuntimeClient(); if (cmd == "print" && GetArgList().size() == 1) { runtimeClient.SetIsInitializeTree(false); - VariableManager &variableManager = VariableManager::GetInstance(); + VariableManager &variableManager = session->GetVariableManager(); int32_t objectId = variableManager.FindObjectIdWithIndex(std::stoi(GetArgList()[0])); runtimeClient.SetObjectId(std::to_string(objectId)); } - result = runtimeClient.DispatcherCmd(id_, cmd, &request); + result = runtimeClient.DispatcherCmd(cmd); if (result) { - cliSocket_.ClientSendReq(request); runtimeClient.SetObjectId("0"); - if (domainManager_.GetDomainById(id_).empty()) { - domainManager_.SetDomainById(id_, "Runtime"); - } } else { return ErrCode::ERR_FAIL; } return ErrCode::ERR_OK; } -ErrCode CliCommand::TestCommand(const std::string &cmd) +ErrCode CliCommand::SessionAddCommand([[maybe_unused]] const std::string &cmd) { - std::string request; - bool result = false; - if (cmd == "success" || cmd == "fail") { - TestClient &testClient = domainManager_.GetTestClient(); - result = testClient.DispatcherCmd(id_, cmd, &request); - if (result) { - cliSocket_.ClientSendReq(request); - if (domainManager_.GetDomainById(id_).empty()) { - domainManager_.SetDomainById(id_, "Test"); + VecStr argList = GetArgList(); + if (argList.size() >= 1) { + if (!SessionManager::getInstance().CreateNewSession(argList[0])) { + std::cout << "session create success" << std::endl; + return ErrCode::ERR_OK; + } + } + + std::cout << "session add failed" << std::endl; + return ErrCode::ERR_FAIL; +} + +ErrCode CliCommand::SessionDelCommand([[maybe_unused]] const std::string &cmd) +{ + VecStr argList = GetArgList(); + if (argList.size() >= 1) { + uint32_t sessionId = 0; + if (Utils::StrToUInt(argList[0].c_str(), &sessionId)) { + if (sessionId == 0) { + std::cout << "cannot remove default session 0" << std::endl; + return ErrCode::ERR_OK; + } + if (SessionManager::getInstance().DelSessionById(sessionId) == 0) { + std::cout << "session remove success" << std::endl; + return ErrCode::ERR_OK; } } + } + + return ErrCode::ERR_FAIL; +} + +ErrCode CliCommand::SessionListCommand([[maybe_unused]] const std::string &cmd) +{ + SessionManager::getInstance().SessionList(); + return ErrCode::ERR_OK; +} + +ErrCode CliCommand::SessionSwitchCommand([[maybe_unused]] const std::string &cmd) +{ + VecStr argList = GetArgList(); + if (argList.size() >= 1) { + uint32_t sessionId = 0; + if (Utils::StrToUInt(argList[0].c_str(), &sessionId)) { + if (SessionManager::getInstance().SessionSwitch(sessionId) == 0) { + std::cout << "session switch success" << std::endl; + return ErrCode::ERR_OK; + } + } + } + return ErrCode::ERR_OK; +} + +ErrCode CliCommand::TestCommand(const std::string &cmd) +{ + if (cmd == "success" || cmd == "fail") { + Session *session = SessionManager::getInstance().GetSessionById(sessionId_); + TestClient &testClient = session->GetDomainManager().GetTestClient(); + testClient.DispatcherCmd(cmd); } else { return ErrCode::ERR_FAIL; } diff --git a/tooling/client/utils/cli_command.h b/tooling/client/utils/cli_command.h index 4b6b7f34..5055173d 100644 --- a/tooling/client/utils/cli_command.h +++ b/tooling/client/utils/cli_command.h @@ -27,6 +27,7 @@ #include "tooling/client/manager/domain_manager.h" #include "tooling/client/utils/utils.h" #include "tooling/client/websocket/websocket_client.h" +#include "tooling/client/session/session.h" namespace OHOS::ArkCompiler::Toolchain { using StrPair = std::pair; @@ -39,8 +40,8 @@ enum class ErrCode : uint8_t { class CliCommand { public: - CliCommand(std::vector cliCmdStr, int cmdId, DomainManager &domainManager, WebsocketClient &cliSocket) - : cmd_(cliCmdStr[0]), id_(cmdId), domainManager_(domainManager), cliSocket_(cliSocket) + CliCommand(std::vector cliCmdStr, uint32_t sessionId) + : cmd_(cliCmdStr[0]), sessionId_(sessionId) { for (size_t i = 1; i < cliCmdStr.size(); i++) { argList_.push_back(cliCmdStr[i]); @@ -56,14 +57,13 @@ public: ErrCode DebuggerCommand(const std::string &cmd); ErrCode CpuProfileCommand(const std::string &cmd); ErrCode RuntimeCommand(const std::string &cmd); + ErrCode SessionAddCommand(const std::string &cmd); + ErrCode SessionDelCommand(const std::string &cmd); + ErrCode SessionListCommand(const std::string &cmd); + ErrCode SessionSwitchCommand(const std::string &cmd); ErrCode TestCommand(const std::string &cmd); ErrCode ExecHelpCommand(); - uint32_t GetId() const - { - return id_; - } - VecStr GetArgList() { return argList_; @@ -74,9 +74,7 @@ private: VecStr argList_ {}; std::map> commandMap_; std::string resultReceiver_ = ""; - uint32_t id_ = 0; - DomainManager &domainManager_; - WebsocketClient &cliSocket_; + uint32_t sessionId_; }; } // namespace OHOS::ArkCompiler::Toolchain diff --git a/tooling/client/utils/utils.cpp b/tooling/client/utils/utils.cpp index d35ddc72..dd9c33c2 100644 --- a/tooling/client/utils/utils.cpp +++ b/tooling/client/utils/utils.cpp @@ -53,6 +53,17 @@ bool Utils::GetCurrentTime(char *date, char *tim, size_t size) return true; } +bool Utils::StrToUInt(const char *content, uint32_t *result) +{ + const int dec = 10; + char *endPtr = nullptr; + *result = std::strtoul(content, &endPtr, dec); + if (endPtr == content || *endPtr != '\0') { + return false; + } + return true; +} + std::vector Utils::SplitString(const std::string &str, const std::string &delimiter) { std::size_t strIndex = 0; diff --git a/tooling/client/utils/utils.h b/tooling/client/utils/utils.h index 606df61c..90c61c98 100644 --- a/tooling/client/utils/utils.h +++ b/tooling/client/utils/utils.h @@ -23,6 +23,7 @@ namespace OHOS::ArkCompiler::Toolchain { class Utils { public: static bool GetCurrentTime(char *date, char *tim, size_t size); + static bool StrToUInt(const char *content, uint32_t *result); static std::vector SplitString(const std::string &str, const std::string &delimiter); }; } // OHOS::ArkCompiler::Toolchain diff --git a/tooling/client/websocket/websocket_client.cpp b/tooling/client/websocket/websocket_client.cpp index 15af1887..9cc9f21d 100644 --- a/tooling/client/websocket/websocket_client.cpp +++ b/tooling/client/websocket/websocket_client.cpp @@ -254,11 +254,14 @@ std::string WebsocketClient::Decode() return ""; } char recvbuf[SOCKET_HEADER_LEN + 1]; + errno = 0; if (!Recv(client_, recvbuf, SOCKET_HEADER_LEN, 0)) { - LOGE("WebsocketClient:Decode failed, client websocket disconnect"); - socketState_ = ToolchainSocketState::INITED; - close(client_); - client_ = -1; + if (errno != EAGAIN) { + LOGE("WebsocketClient:Decode failed, client websocket disconnect"); + socketState_ = ToolchainSocketState::INITED; + close(client_); + client_ = -1; + } return ""; } ToolchainWebSocketFrame wsFrame; @@ -425,4 +428,15 @@ bool WebsocketClient::IsConnected() { return socketState_ == ToolchainSocketState::CONNECTED; } + +std::string WebsocketClient::GetSocketStateString() +{ + std::vector stateStr = { + "uninited", + "inited", + "connected" + }; + + return stateStr[socketState_]; +} } // namespace OHOS::ArkCompiler::Toolchain \ No newline at end of file diff --git a/tooling/client/websocket/websocket_client.h b/tooling/client/websocket/websocket_client.h index 56772e03..3fb7f6bb 100644 --- a/tooling/client/websocket/websocket_client.h +++ b/tooling/client/websocket/websocket_client.h @@ -43,7 +43,7 @@ public: WebsocketClient() = default; ~WebsocketClient() = default; bool InitToolchainWebSocketForPort(int port, uint32_t timeoutLimit = 5); - bool InitToolchainWebSocketForSockName(const std::string &sockName, uint32_t timeoutLimit = 0); + bool InitToolchainWebSocketForSockName(const std::string &sockName, uint32_t timeoutLimit = 5); bool ClientSendWSUpgradeReq(); bool ClientRecvWSUpgradeRsp(); bool ClientSendReq(const std::string &message); @@ -56,6 +56,7 @@ public: void Close(); bool SetWebSocketTimeOut(int32_t fd, uint32_t timeoutLimit); bool IsConnected(); + std::string GetSocketStateString(); private: int32_t client_ {-1}; diff --git a/tooling/test/BUILD.gn b/tooling/test/BUILD.gn index 2fc6294e..9c2b4655 100644 --- a/tooling/test/BUILD.gn +++ b/tooling/test/BUILD.gn @@ -28,6 +28,7 @@ config("debug_api_test") { "//arkcompiler/ets_runtime", "../..", "//third_party/cJSON", + "//third_party/libuv/include", ] } diff --git a/tooling/test/client_utils/test_util.cpp b/tooling/test/client_utils/test_util.cpp index 7fa96836..db52114a 100644 --- a/tooling/test/client_utils/test_util.cpp +++ b/tooling/test/client_utils/test_util.cpp @@ -18,6 +18,7 @@ #include "tooling/client/domain/debugger_client.h" #include "tooling/client/domain/runtime_client.h" #include "tooling/client/utils/cli_command.h" +#include "tooling/client/session/session.h" namespace panda::ecmascript::tooling::test { TestMap TestUtil::testMap_; @@ -67,19 +68,19 @@ std::ostream &operator<<(std::ostream &out, ActionRule value) return out << s; } -void TestUtil::NotifySuccess(int cmdId, DomainManager &domainManager, WebsocketClient &client) +void TestUtil::NotifySuccess() { std::vector cliCmdStr = { "success" }; - CliCommand cmd(cliCmdStr, cmdId, domainManager, client); + CliCommand cmd(cliCmdStr, 0); if (cmd.ExecCommand() == ErrCode::ERR_FAIL) { LOG_DEBUGGER(ERROR) << "ExecCommand Test.success fail"; } } -void TestUtil::NotifyFail(int cmdId, DomainManager &domainManager, WebsocketClient &client) +void TestUtil::NotifyFail() { std::vector cliCmdStr = { "fail" }; - CliCommand cmd(cliCmdStr, cmdId, domainManager, client); + CliCommand cmd(cliCmdStr, 0); if (cmd.ExecCommand() == ErrCode::ERR_FAIL) { LOG_DEBUGGER(ERROR) << "ExecCommand Test.fail fail"; } @@ -87,7 +88,6 @@ void TestUtil::NotifyFail(int cmdId, DomainManager &domainManager, WebsocketClie void TestUtil::ForkSocketClient([[maybe_unused]] int port, const std::string &name) { - int cmdId = 0; #ifdef OHOS_PLATFORM auto correntPid = getpid(); #endif @@ -98,28 +98,23 @@ void TestUtil::ForkSocketClient([[maybe_unused]] int port, const std::string &na } else if (pid == 0) { LOG_DEBUGGER(INFO) << "fork son pid: " << getpid(); std::this_thread::sleep_for(std::chrono::microseconds(500000)); // 500000: 500ms for wait debugger - DomainManager domainManager; - WebsocketClient client; #ifdef OHOS_PLATFORM std::string pidStr = std::to_string(correntPid); - std::string sockName = pidStr + "PandaDebugger"; - bool ret = client.InitToolchainWebSocketForSockName(sockName, 120); + std::string sockInfo = pidStr + "PandaDebugger"; #else - bool ret = client.InitToolchainWebSocketForPort(port, 120); + std::string sockInfo = std::to_string(port); #endif - LOG_ECMA_IF(!ret, FATAL) << "InitToolchainWebSocketForPort fail"; - ret = client.ClientSendWSUpgradeReq(); - LOG_ECMA_IF(!ret, FATAL) << "ClientSendWSUpgradeReq fail"; - ret = client.ClientRecvWSUpgradeRsp(); - LOG_ECMA_IF(!ret, FATAL) << "ClientRecvWSUpgradeRsp fail"; + int ret = SessionManager::getInstance().CreateTestSession(sockInfo); + LOG_ECMA_IF(ret, FATAL) << "CreateTestSession fail"; + WebsocketClient &client = SessionManager::getInstance().GetCurrentSession()->GetWebsocketClient(); auto &testAction = TestUtil::GetTest(name)->testAction; for (const auto &action: testAction) { LOG_DEBUGGER(INFO) << "message: " << action.message; bool success = true; if (action.action == SocketAction::SEND) { std::vector cliCmdStr = Utils::SplitString(action.message, " "); - CliCommand cmd(cliCmdStr, cmdId++, domainManager, client); + CliCommand cmd(cliCmdStr, 0); success = (cmd.ExecCommand() == ErrCode::ERR_OK); } else { ASSERT(action.action == SocketAction::RECV); @@ -143,14 +138,14 @@ void TestUtil::ForkSocketClient([[maybe_unused]] int port, const std::string &na } if (!success) { LOG_DEBUGGER(ERROR) << "Notify fail"; - NotifyFail(cmdId++, domainManager, client); - client.Close(); + NotifyFail(); + SessionManager::getInstance().DelSessionById(0); exit(-1); } } - NotifySuccess(cmdId++, domainManager, client); - client.Close(); + NotifySuccess(); + SessionManager::getInstance().DelSessionById(0); exit(0); } LOG_DEBUGGER(INFO) << "ForkSocketClient end"; diff --git a/tooling/test/client_utils/test_util.h b/tooling/test/client_utils/test_util.h index c7cb883b..f7839cce 100644 --- a/tooling/test/client_utils/test_util.h +++ b/tooling/test/client_utils/test_util.h @@ -63,8 +63,8 @@ public: static void ForkSocketClient(int port, const std::string &name); private: - static void NotifyFail(int cmdId, DomainManager &domainManager, WebsocketClient &client); - static void NotifySuccess(int cmdId, DomainManager &domainManager, WebsocketClient &client); + static void NotifyFail(); + static void NotifySuccess(); static TestMap testMap_; }; -- Gitee