mirror of
https://gitee.com/openharmony/arkcompiler_toolchain
synced 2024-11-27 09:40:40 +00:00
!429 arkdb supports source code display and watch functionality
Merge pull request !429 from yp9522/client_source_watch_session
This commit is contained in:
commit
4bfe10501e
@ -36,8 +36,11 @@ ohos_source_set("libark_client_set") {
|
||||
"domain/test_client.cpp",
|
||||
"manager/breakpoint_manager.cpp",
|
||||
"manager/domain_manager.cpp",
|
||||
"manager/source_manager.cpp",
|
||||
"manager/stack_manager.cpp",
|
||||
"manager/variable_manager.cpp",
|
||||
"manager/watch_manager.cpp",
|
||||
"session/session.cpp",
|
||||
"utils/cli_command.cpp",
|
||||
"utils/utils.cpp",
|
||||
"websocket/websocket_client.cpp",
|
||||
|
@ -22,28 +22,14 @@
|
||||
#include <securec.h>
|
||||
|
||||
#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<uv_handle_t*>(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<std::string>& cliCmdStr)
|
||||
{
|
||||
CliCommand cmd(cliCmdStr, sessionId);
|
||||
cmd.ExecCommand();
|
||||
return;
|
||||
}
|
||||
|
||||
void InputOnMessage(uv_async_t *handle)
|
||||
{
|
||||
char* msg = static_cast<char*>(handle->data);
|
||||
std::string inputStr = std::string(msg);
|
||||
std::vector<std::string> 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;
|
||||
}
|
||||
std::cout << ">>> ";
|
||||
fflush(stdout);
|
||||
if (msg != nullptr) {
|
||||
free(msg);
|
||||
}
|
||||
std::vector<std::string> cliCmdStr = Utils::SplitString(inputStr, " ");
|
||||
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);
|
||||
}
|
||||
|
||||
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<uv_handle_t*>(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<uv_handle_t*>(g_inputSignal))) {
|
||||
if (strncpy_s(msg, len + 1, inputStr.c_str(), len) != 0) {
|
||||
g_cliSocket.Close();
|
||||
if (uv_is_active(reinterpret_cast<uv_handle_t*>(g_releaseHandle))) {
|
||||
uv_async_send(g_releaseHandle);
|
||||
}
|
||||
@ -124,69 +123,31 @@ void GetInputCommand([[maybe_unused]] void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
void SocketOnMessage(uv_async_t *handle)
|
||||
void SocketOnMessage([[maybe_unused]] uv_async_t *handle)
|
||||
{
|
||||
char* msg = static_cast<char*>(handle->data);
|
||||
g_domainManager.DispatcherReply(msg);
|
||||
if (msg != nullptr) {
|
||||
free(msg);
|
||||
}
|
||||
}
|
||||
|
||||
void GetSocketMessage([[maybe_unused]] void *arg)
|
||||
{
|
||||
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<uv_handle_t*>(g_socketSignal))) {
|
||||
if (strncpy_s(msg, len + 1, decMessage.c_str(), len) != 0) {
|
||||
g_cliSocket.Close();
|
||||
if (uv_is_active(reinterpret_cast<uv_handle_t*>(g_releaseHandle))) {
|
||||
uv_async_send(g_releaseHandle);
|
||||
}
|
||||
break;
|
||||
}
|
||||
g_socketSignal->data = std::move(msg);
|
||||
uv_async_send(g_socketSignal);
|
||||
}
|
||||
|
||||
session->ProcSocketMsg(const_cast<char *>(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;
|
||||
|
@ -19,55 +19,59 @@
|
||||
|
||||
#include "common/log_wrapper.h"
|
||||
#include "tooling/client/manager/breakpoint_manager.h"
|
||||
#include "tooling/client/manager/source_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<std::string, std::function<std::string()>> 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<std::string, std::function<int()>> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Debugger.setBreakpointByUrl");
|
||||
@ -77,16 +81,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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Debugger.removeBreakpoint");
|
||||
@ -95,155 +107,208 @@ 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Debugger.disable");
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Debugger.enable");
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Debugger.resume");
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Debugger.stepInto");
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Debugger.stepOut");
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Debugger.stepOver");
|
||||
|
||||
std::unique_ptr<PtJson> 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)
|
||||
{
|
||||
BreakPointInfo breakPointInfo;
|
||||
breakPointInfo.url = url;
|
||||
breakPointInfo.lineNumber = lineNumber;
|
||||
breakPointInfo.lineNumber = lineNumber - 1;
|
||||
breakPointInfo.columnNumber = columnNumber;
|
||||
breakPointInfoList_.emplace_back(breakPointInfo);
|
||||
}
|
||||
@ -261,14 +326,16 @@ void DebuggerClient::RecvReply(std::unique_ptr<PtJson> json)
|
||||
return;
|
||||
}
|
||||
|
||||
Result ret;
|
||||
std::string wholeMethod;
|
||||
std::string method;
|
||||
ret = json->GetString("method", &wholeMethod);
|
||||
Result ret = json->GetString("method", &wholeMethod);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: find method error");
|
||||
}
|
||||
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
SourceManager &sourceManager = session->GetSourceManager();
|
||||
|
||||
std::string::size_type length = wholeMethod.length();
|
||||
std::string::size_type indexPoint = 0;
|
||||
indexPoint = wholeMethod.find_first_of('.', 0);
|
||||
@ -276,23 +343,13 @@ void DebuggerClient::RecvReply(std::unique_ptr<PtJson> json)
|
||||
if (method == "paused") {
|
||||
PausedReply(std::move(json));
|
||||
return;
|
||||
} else if (method == "scriptParsed") {
|
||||
sourceManager.EnableReply(std::move(json));
|
||||
return;
|
||||
} else {
|
||||
LOGI("arkdb: Debugger reply is: %{public}s", json->Stringify().c_str());
|
||||
}
|
||||
|
||||
std::unique_ptr<PtJson> result;
|
||||
ret = json->GetObject("result", &result);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: find result error");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string breakpointId;
|
||||
ret = result->GetString("breakpointId", &breakpointId);
|
||||
if (ret == Result::SUCCESS) {
|
||||
BreakPointManager &breakpoint = BreakPointManager::GetInstance();
|
||||
breakpoint.Createbreaklocation(std::move(json));
|
||||
}
|
||||
handleResponse(std::move(json));
|
||||
}
|
||||
|
||||
void DebuggerClient::PausedReply(const std::unique_ptr<PtJson> json)
|
||||
@ -328,8 +385,49 @@ void DebuggerClient::PausedReply(const std::unique_ptr<PtJson> json)
|
||||
data.emplace(i + 1, std::move(callFrameInfo));
|
||||
}
|
||||
|
||||
StackManager &stackManager = StackManager::GetInstance();
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
StackManager& stackManager = session->GetStackManager();
|
||||
SourceManager &sourceManager = session->GetSourceManager();
|
||||
WatchManager &watchManager = session->GetWatchManager();
|
||||
stackManager.ClearCallFrame();
|
||||
stackManager.SetCallFrames(std::move(data));
|
||||
sourceManager.GetDebugSources(callFrames->Get(0));
|
||||
watchManager.RequestWatchInfo(callFrames->Get(0));
|
||||
watchManager.DebugTrueState();
|
||||
}
|
||||
|
||||
void DebuggerClient::handleResponse(std::unique_ptr<PtJson> json)
|
||||
{
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
SourceManager &sourceManager = session->GetSourceManager();
|
||||
WatchManager &watchManager = session->GetWatchManager();
|
||||
BreakPointManager& breakpoint = session->GetBreakPointManager();
|
||||
std::unique_ptr<PtJson> result;
|
||||
Result ret = json->GetObject("result", &result);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: find result error");
|
||||
return;
|
||||
}
|
||||
int32_t id;
|
||||
ret = json->GetInt("id", &id);
|
||||
if (ret == Result::SUCCESS) {
|
||||
std::string scriptSource;
|
||||
ret = result->GetString("scriptSource", &scriptSource);
|
||||
if (ret == Result::SUCCESS) {
|
||||
sourceManager.SetFileSource(id, scriptSource);
|
||||
return;
|
||||
}
|
||||
}
|
||||
std::string breakpointId;
|
||||
ret = result->GetString("breakpointId", &breakpointId);
|
||||
if (ret == Result::SUCCESS) {
|
||||
breakpoint.Createbreaklocation(std::move(json));
|
||||
sourceManager.GetDebugInfo(std::move(result));
|
||||
return;
|
||||
}
|
||||
if (watchManager.HandleWatchResult(std::move(json), id)) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
} // OHOS::ArkCompiler::Toolchain
|
@ -31,41 +31,43 @@ 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<PtJson> json);
|
||||
void PausedReply(const std::unique_ptr<PtJson> json);
|
||||
void handleResponse(std::unique_ptr<PtJson> json);
|
||||
|
||||
private:
|
||||
std::vector<BreakPointInfo> breakPointInfoList_ {};
|
||||
int32_t sessionId_;
|
||||
};
|
||||
} // OHOS::ArkCompiler::Toolchain
|
||||
#endif
|
@ -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 <map>
|
||||
#include <functional>
|
||||
@ -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<std::string, std::function<std::string()>> 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<std::string, std::function<int()>> 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<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -79,11 +87,19 @@ std::string HeapProfilerClient::AllocationTrackCommand(int id)
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -92,11 +108,19 @@ std::string HeapProfilerClient::AllocationTrackStopCommand(int id)
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -104,11 +128,19 @@ std::string HeapProfilerClient::Enable(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -116,11 +148,19 @@ std::string HeapProfilerClient::Disable(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -129,11 +169,19 @@ std::string HeapProfilerClient::Samping(int id)
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -141,11 +189,19 @@ std::string HeapProfilerClient::SampingStop(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -153,7 +209,12 @@ std::string HeapProfilerClient::CollectGarbage(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> json)
|
||||
@ -213,10 +274,12 @@ void HeapProfilerClient::RecvReply(std::unique_ptr<PtJson> json)
|
||||
return;
|
||||
}
|
||||
if (isAllocationMsg_) {
|
||||
fileName_ = "/data/Heap-" + std::string(date) + "T" + std::string(time) + ".heaptimeline";
|
||||
fileName_ = "/data/Heap-" + std::to_string(sessionId_) + "-" + std::string(date) + "T" + std::string(time) +
|
||||
".heaptimeline";
|
||||
std::cout << "heaptimeline file name is " << fileName_ << std::endl;
|
||||
} else {
|
||||
fileName_ = "/data/Heap-" + std::string(date) + "T" + std::string(time) + ".heapsnapshot";
|
||||
fileName_ = "/data/Heap-"+ std::to_string(sessionId_) + "-" + std::string(date) + "T" + std::string(time) +
|
||||
".heapsnapshot";
|
||||
std::cout << "heapsnapshot file name is " << fileName_ << std::endl;
|
||||
}
|
||||
std::cout << ">>> ";
|
||||
|
@ -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<PtJson> json);
|
||||
bool WriteHeapProfilerForFile(const std::string &fileName, const std::string &data);
|
||||
|
||||
@ -58,6 +58,7 @@ private:
|
||||
std::map<uint32_t, HeapProfilerEvent> idEventMap_;
|
||||
std::string path_;
|
||||
bool isAllocationMsg_ {false};
|
||||
uint32_t sessionId_;
|
||||
};
|
||||
} // OHOS::ArkCompiler::Toolchain
|
||||
#endif
|
@ -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 <map>
|
||||
#include <functional>
|
||||
@ -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<std::string, std::function<std::string()>> 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<std::string, std::function<int()>> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -57,11 +59,19 @@ std::string ProfilerClient::CpuprofileEnableCommand(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -69,11 +79,19 @@ std::string ProfilerClient::CpuprofileDisableCommand(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -81,11 +99,19 @@ std::string ProfilerClient::CpuprofileCommand(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -93,11 +119,19 @@ std::string ProfilerClient::CpuprofileStopCommand(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -106,12 +140,12 @@ std::string ProfilerClient::SetSamplingIntervalCommand(int id)
|
||||
std::unique_ptr<PtJson> 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<PtJson> json)
|
||||
@ -149,10 +183,12 @@ void ProfilerClient::RecvProfilerResult(std::unique_ptr<PtJson> json)
|
||||
return;
|
||||
}
|
||||
|
||||
ProfilerSingleton& pro = ProfilerSingleton::GetInstance();
|
||||
std::string fileName = "/data/CPU-" + std::string(date) + "T" + std::string(time) + ".cpuprofile";
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
ProfilerSingleton &pro = session->GetProfilerSingleton();
|
||||
std::string fileName = "/data/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());
|
||||
@ -177,7 +213,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;
|
||||
}
|
||||
|
@ -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<std::string> 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<PtJson> json);
|
||||
void SetSamplingInterval(int interval);
|
||||
|
||||
private:
|
||||
int32_t interval_ = 0;
|
||||
int32_t sessionId_;
|
||||
std::map<uint32_t, std::string> idEventMap_ {};
|
||||
};
|
||||
} // OHOS::ArkCompiler::Toolchain
|
||||
|
@ -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<std::string, std::function<std::string()>> 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<std::string, std::function<int()>> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -53,11 +56,19 @@ std::string RuntimeClient::HeapusageCommand(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -65,11 +76,19 @@ std::string RuntimeClient::RuntimeEnableCommand(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -77,11 +96,19 @@ std::string RuntimeClient::RuntimeDisableCommand(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
@ -89,11 +116,19 @@ std::string RuntimeClient::RunIfWaitingForDebuggerCommand(int id)
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> 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<PtJson> 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<PtJson> json)
|
||||
@ -198,8 +246,9 @@ void RuntimeClient::HandleGetProperties(std::unique_ptr<PtJson> 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<int32_t, std::map<int32_t, std::string>> treeInfo = stackManager.GetScopeChainInfo();
|
||||
if (isInitializeTree_) {
|
||||
variableManager.ClearVariableInfo();
|
||||
@ -242,7 +291,8 @@ void RuntimeClient::HandleHeapUsage(std::unique_ptr<PtJson> json)
|
||||
return;
|
||||
}
|
||||
|
||||
VariableManager &variableManager = VariableManager::GetInstance();
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
VariableManager &variableManager = session->GetVariableManager();
|
||||
std::unique_ptr<GetHeapUsageReturns> heapUsageReturns = GetHeapUsageReturns::Create(*result);
|
||||
variableManager.SetHeapUsageInfo(std::move(heapUsageReturns));
|
||||
variableManager.ShowHeapUsageInfo();
|
||||
|
@ -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<PtJson> json);
|
||||
@ -61,6 +61,7 @@ private:
|
||||
std::map<int, std::tuple<std::string, std::string>> idMethodMap_ {};
|
||||
std::string objectId_ {"0"};
|
||||
bool isInitializeTree_ {true};
|
||||
int32_t sessionId_;
|
||||
};
|
||||
} // OHOS::ArkCompiler::Toolchain
|
||||
#endif
|
@ -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<std::string, std::function<std::string()>> dispatcherTable {
|
||||
{ "success", std::bind(&TestClient::SuccessCommand, this, id)},
|
||||
{ "fail", std::bind(&TestClient::FailCommand, this, id)},
|
||||
std::map<std::string, std::function<int()>> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Test.success");
|
||||
|
||||
std::unique_ptr<PtJson> 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<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Test.fail");
|
||||
|
||||
std::unique_ptr<PtJson> 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
|
@ -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
|
@ -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<PtJson> json)
|
||||
{
|
||||
if (json == nullptr) {
|
||||
@ -68,7 +63,7 @@ void BreakPointManager::Show()
|
||||
size_t size = breaklist_.size();
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
std::cout << (i + 1) << ':' << " url:" << breaklist_[i].url;
|
||||
std::cout << " lineNumber:" << breaklist_[i].lineNumber
|
||||
std::cout << " lineNumber:" << (std::atoi(breaklist_[i].lineNumber.c_str()) + 1)
|
||||
<< " columnNumber:" << breaklist_[i].columnNumber << std::endl;
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ struct Breaklocation {
|
||||
};
|
||||
class BreakPointManager {
|
||||
public:
|
||||
static BreakPointManager& GetInstance();
|
||||
BreakPointManager(int32_t sessionId) : sessionId_(sessionId) {}
|
||||
|
||||
void Createbreaklocation(const std::unique_ptr<PtJson> json);
|
||||
void Show();
|
||||
@ -44,9 +44,8 @@ public:
|
||||
std::vector<Breaklocation> Getbreaklist() const;
|
||||
|
||||
private:
|
||||
static BreakPointManager instance_;
|
||||
[[maybe_unused]] int32_t sessionId_;
|
||||
std::vector<Breaklocation> breaklist_ {};
|
||||
BreakPointManager() = default;
|
||||
BreakPointManager(const BreakPointManager&) = delete;
|
||||
BreakPointManager& operator=(const BreakPointManager&) = delete;
|
||||
};
|
||||
|
@ -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);
|
||||
@ -45,6 +52,9 @@ void DomainManager::DispatcherReply(char* msg)
|
||||
domain = GetDomainById(id);
|
||||
RemoveDomainById(id);
|
||||
}
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
WatchManager &watchManager = session->GetWatchManager();
|
||||
watchManager.DebugFalseState();
|
||||
|
||||
std::string wholeMethod;
|
||||
ret = json->GetString("method", &wholeMethod);
|
||||
|
@ -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<uint32_t, std::string> idDomainMap_ {};
|
||||
};
|
||||
} // OHOS::ArkCompiler::Toolchain
|
||||
|
70
tooling/client/manager/message_manager.h
Executable file
70
tooling/client/manager/message_manager.h
Executable file
@ -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 <iostream>
|
||||
|
||||
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<std::pair<uint32_t, std::string>> messageQue_;
|
||||
};
|
||||
} // OHOS::ArkCompiler::Toolchain
|
||||
#endif
|
315
tooling/client/manager/source_manager.cpp
Normal file
315
tooling/client/manager/source_manager.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
/*
|
||||
* 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/manager/source_manager.h"
|
||||
|
||||
#include "common/log_wrapper.h"
|
||||
#include "tooling/client/session/session.h"
|
||||
|
||||
using PtJson = panda::ecmascript::tooling::PtJson;
|
||||
using Result = panda::ecmascript::tooling::Result;
|
||||
namespace OHOS::ArkCompiler::Toolchain {
|
||||
void SourceManager::SendRequeSource(int scriptId)
|
||||
{
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
uint32_t id = session->GetMessageId();
|
||||
scriptIdMap_.emplace(std::make_pair(id, scriptId));
|
||||
|
||||
std::unique_ptr<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Debugger.getScriptSource");
|
||||
|
||||
std::unique_ptr<PtJson> params = PtJson::CreateObject();
|
||||
params->Add("scriptId", std::to_string(scriptId).c_str());
|
||||
request->Add("params", params);
|
||||
|
||||
std::string message = request->Stringify();
|
||||
if (session->ClientSendReq(message)) {
|
||||
session->GetDomainManager().SetDomainById(id, "Debugger");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void SourceManager::EnableReply(const std::unique_ptr<PtJson> json)
|
||||
{
|
||||
if (json == nullptr) {
|
||||
LOGE("arkdb: json parse error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!json->IsObject()) {
|
||||
LOGE("arkdb: json parse format error");
|
||||
json->ReleaseRoot();
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<PtJson> params;
|
||||
Result ret = json->GetObject("params", ¶ms);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: find params error");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string scriptIdStr;
|
||||
ret = params->GetString("scriptId", &scriptIdStr);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: find scriptId error");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string fileName;
|
||||
ret = params->GetString("url", &fileName);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: find fileName error");
|
||||
return;
|
||||
}
|
||||
int scriptId = std::atoi(scriptIdStr.c_str());
|
||||
SetFileName(scriptId, fileName);
|
||||
SendRequeSource(scriptId);
|
||||
return;
|
||||
}
|
||||
|
||||
void SourceManager::SetFileName(int scriptId, const std::string& fileName)
|
||||
{
|
||||
fileSource_.insert(std::make_pair(scriptId, std::make_pair(fileName, std::vector<std::string> {})));
|
||||
return;
|
||||
}
|
||||
|
||||
void SourceManager::GetFileName()
|
||||
{
|
||||
for (auto it = fileSource_.begin(); it != fileSource_.end(); it++) {
|
||||
std::cout << "scriptID : " << it->first;
|
||||
std::cout << " fileName : " << it->second.first <<std::endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void SourceManager::SetFileSource(int scriptIdIndex, const std::string& fileSource)
|
||||
{
|
||||
const int IGNOR_NEWLINE_FLAG = 2;
|
||||
auto scriptIdIt = scriptIdMap_.find(scriptIdIndex);
|
||||
if (scriptIdIt == scriptIdMap_.end()) {
|
||||
return;
|
||||
}
|
||||
int scriptId = scriptIdIt->second;
|
||||
|
||||
auto it = fileSource_.find(scriptId);
|
||||
if (it != fileSource_.end() && it->second.second.empty()) {
|
||||
int startPos = 0;
|
||||
std::string::size_type endPos = fileSource.find("\r\n");
|
||||
while (endPos != std::string::npos) {
|
||||
std::string line = fileSource.substr(startPos, endPos - startPos);
|
||||
it->second.second.push_back(line);
|
||||
startPos = endPos + IGNOR_NEWLINE_FLAG; // ignore "\r\n"
|
||||
endPos = fileSource.find("\r\n", startPos);
|
||||
}
|
||||
it->second.second.push_back(fileSource.substr(startPos));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> SourceManager::GetFileSource(int scriptId)
|
||||
{
|
||||
int linNum = 0;
|
||||
auto it = fileSource_.find(scriptId);
|
||||
if (it != fileSource_.end()) {
|
||||
std::cout << "fileSource : " <<std::endl;
|
||||
for (const std::string& value : it->second.second) {
|
||||
std::cout << ++linNum << " " << value << std::endl;
|
||||
}
|
||||
return it->second.second;
|
||||
}
|
||||
return std::vector<std::string> {};
|
||||
}
|
||||
|
||||
void SourceManager::GetDebugSources(const std::unique_ptr<PtJson> json)
|
||||
{
|
||||
std::string funcName;
|
||||
Result ret = json->GetString("functionName", &funcName);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: get functionName error");
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_ptr<PtJson> location;
|
||||
ret = json->GetObject("location", &location);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: get location error");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string scriptIdStr;
|
||||
ret = location->GetString("scriptId", &scriptIdStr);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: get scriptId error");
|
||||
return;
|
||||
}
|
||||
scriptId_ = std::atoi(scriptIdStr.c_str());
|
||||
|
||||
ret = location->GetInt("lineNumber", &debugLineNum_);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: get lineNumber error");
|
||||
return;
|
||||
}
|
||||
|
||||
LOGE("arkdb: callFrames : funcName %{public}s, scriptid %{public}s, lineNum %{public}d",
|
||||
funcName.c_str(), scriptIdStr.c_str(), debugLineNum_);
|
||||
auto it = fileSource_.find(scriptId_);
|
||||
if (it != fileSource_.end()) {
|
||||
std::cout << (debugLineNum_ + 1) << " " << it->second.second[debugLineNum_] << std::endl;
|
||||
std::cout << ">>> ";
|
||||
fflush(stdout);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void SourceManager::ListSourceCodeWithParameters(int startLine, int endLine)
|
||||
{
|
||||
const int BLANK_LINE = std::numeric_limits<int>::max();
|
||||
const int STATR_LINE_OFFSET = 6;
|
||||
const int END_LINE_OFFSET = 4;
|
||||
const int END_LINE = 10;
|
||||
if (startLine != BLANK_LINE && endLine == BLANK_LINE) {
|
||||
auto it = fileSource_.find(scriptId_);
|
||||
if (it == fileSource_.end()) {
|
||||
LOGE("arkdb: get file source error");
|
||||
return;
|
||||
}
|
||||
if (startLine >= static_cast<int>(it->second.second.size()) + STATR_LINE_OFFSET ||
|
||||
startLine < 0) {
|
||||
std::cout << "Line number out of range, this file has " <<
|
||||
static_cast<int>(it->second.second.size()) << " lines" << std::endl;
|
||||
return;
|
||||
}
|
||||
int showLine = startLine - STATR_LINE_OFFSET;
|
||||
if (showLine < 0) {
|
||||
showLine = 0;
|
||||
endLine = END_LINE;
|
||||
} else {
|
||||
endLine = startLine + END_LINE_OFFSET;
|
||||
}
|
||||
if (endLine > static_cast<int>(it->second.second.size())) {
|
||||
endLine = static_cast<int>(it->second.second.size());
|
||||
}
|
||||
for (; showLine < endLine; showLine++) {
|
||||
std::cout << (showLine + 1) << " " << it->second.second[showLine] << std::endl;
|
||||
}
|
||||
} else if (startLine != BLANK_LINE && endLine != BLANK_LINE) {
|
||||
auto it = fileSource_.find(scriptId_);
|
||||
if (it == fileSource_.end()) {
|
||||
LOGE("arkdb: get file source error");
|
||||
return;
|
||||
}
|
||||
if (startLine > static_cast<int>(it->second.second.size()) ||
|
||||
endLine > static_cast<int>(it->second.second.size()) ||
|
||||
startLine < 1) {
|
||||
std::cout << "Line number out of range, this file has " <<
|
||||
static_cast<int>(it->second.second.size()) << " lines" << std::endl;
|
||||
return;
|
||||
}
|
||||
if (endLine > static_cast<int>(it->second.second.size())) {
|
||||
endLine = static_cast<int>(it->second.second.size());
|
||||
}
|
||||
for (int showLine = startLine - 1; showLine < endLine; showLine++) {
|
||||
std::cout << (showLine + 1) << " " << it->second.second[showLine] << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SourceManager::ListSource(int startLine, int endLine)
|
||||
{
|
||||
const int BLANK_LINE = std::numeric_limits<int>::max();
|
||||
const int STATR_LINE_OFFSET = 6;
|
||||
const int END_LINE_OFFSET = 4;
|
||||
const int END_LINE = 10;
|
||||
if (startLine == BLANK_LINE && endLine == BLANK_LINE) {
|
||||
auto it = fileSource_.find(scriptId_);
|
||||
if (it == fileSource_.end()) {
|
||||
LOGE("arkdb: get file source error");
|
||||
return;
|
||||
}
|
||||
int showLine = (debugLineNum_ + 1) - STATR_LINE_OFFSET;
|
||||
if (showLine < 0) {
|
||||
showLine = 0;
|
||||
endLine = END_LINE;
|
||||
} else {
|
||||
endLine = debugLineNum_ + END_LINE_OFFSET;
|
||||
}
|
||||
if (endLine > static_cast<int>(it->second.second.size())) {
|
||||
endLine = static_cast<int>(it->second.second.size());
|
||||
}
|
||||
for (; showLine <= endLine; showLine++) {
|
||||
std::cout << (showLine + 1) << " " << it->second.second[showLine] << std::endl;
|
||||
}
|
||||
} else {
|
||||
ListSourceCodeWithParameters(startLine, endLine);
|
||||
}
|
||||
}
|
||||
|
||||
bool SourceManager::IsNumer(const std::string& str)
|
||||
{
|
||||
for (char c : str) {
|
||||
if (std::isdigit(c)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SourceManager::GetListSource(std::string lineNum)
|
||||
{
|
||||
const int BLANK_LINE = std::numeric_limits<int>::max();
|
||||
if (lineNum != "") {
|
||||
size_t found = lineNum.find(",");
|
||||
if (found != std::string::npos) {
|
||||
std::string startLine = lineNum.substr(0, found);
|
||||
std::string endLine = lineNum.substr(found + 1);
|
||||
ListSource(std::atoi(startLine.c_str()), std::atoi(endLine.c_str()));
|
||||
} else {
|
||||
if (!IsNumer(lineNum)) {
|
||||
return;
|
||||
}
|
||||
ListSource(std::atoi(lineNum.c_str()), BLANK_LINE);
|
||||
}
|
||||
} else {
|
||||
ListSource(BLANK_LINE, BLANK_LINE);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void SourceManager::GetDebugInfo(const std::unique_ptr<PtJson> json)
|
||||
{
|
||||
Result ret;
|
||||
std::unique_ptr<PtJson> locations;
|
||||
ret = json->GetArray("locations", &locations);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse locations error");
|
||||
return;
|
||||
}
|
||||
std::string scriptId;
|
||||
ret = locations->Get(0)->GetString("scriptId", &scriptId);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse scriptId error");
|
||||
return;
|
||||
}
|
||||
scriptId_ = std::atoi(scriptId.c_str());
|
||||
ret = locations->Get(0)->GetInt("lineNumber", &debugLineNum_);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse lineNumber error");
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
57
tooling/client/manager/source_manager.h
Normal file
57
tooling/client/manager/source_manager.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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_SOURCE_MANAGER_H
|
||||
#define ECMASCRIPT_TOOLING_CLIENT_MANAGER_SOURCE_MANAGER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "tooling/base/pt_json.h"
|
||||
#include "tooling/base/pt_types.h"
|
||||
|
||||
namespace OHOS::ArkCompiler::Toolchain {
|
||||
using PtJson = panda::ecmascript::tooling::PtJson;
|
||||
using Result = panda::ecmascript::tooling::Result;
|
||||
class SourceManager {
|
||||
public:
|
||||
SourceManager(int32_t sessionId) : sessionId_(sessionId) {}
|
||||
|
||||
void SendRequeSource(int scriptId);
|
||||
void EnableReply(const std::unique_ptr<PtJson> json);
|
||||
void GetFileName();
|
||||
void SetFileName(int scriptId, const std::string& fileName);
|
||||
void SetFileSource(int scriptIdIndex, const std::string& fileSource);
|
||||
std::vector<std::string> GetFileSource(int scriptId);
|
||||
void GetDebugSources(const std::unique_ptr<PtJson> json);
|
||||
void ListSourceCodeWithParameters(int startLine, int endLine);
|
||||
void ListSource(int startLine, int endLine);
|
||||
void GetListSource(std::string lineNum);
|
||||
void GetDebugInfo(const std::unique_ptr<PtJson> json);
|
||||
bool IsNumer(const std::string& str);
|
||||
|
||||
private:
|
||||
[[maybe_unused]] int32_t sessionId_;
|
||||
int32_t scriptId_;
|
||||
int32_t debugLineNum_;
|
||||
std::unordered_map<int, int> scriptIdMap_ {};
|
||||
std::unordered_map<int, std::pair<std::string, std::vector<std::string>>> fileSource_ {};
|
||||
SourceManager(const SourceManager&) = delete;
|
||||
SourceManager& operator=(const SourceManager&) = delete;
|
||||
};
|
||||
} // OHOS::ArkCompiler::Toolchain
|
||||
#endif
|
@ -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<int32_t, std::unique_ptr<CallFrame>> callFrames)
|
||||
{
|
||||
for (auto &callFrame : callFrames) {
|
||||
|
@ -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<int32_t, std::map<int32_t, std::string>> GetScopeChainInfo();
|
||||
void SetCallFrames(std::map<int32_t, std::unique_ptr<CallFrame>> callFrames);
|
||||
@ -39,9 +39,8 @@ public:
|
||||
void PrintScopeChainInfo(const std::map<int32_t, std::map<int32_t, std::string>>& scopeInfos);
|
||||
|
||||
private:
|
||||
static StackManager instance_;
|
||||
[[maybe_unused]] int32_t sessionId_;
|
||||
std::map<int32_t, std::unique_ptr<CallFrame>> callFrames_ {};
|
||||
StackManager() = default;
|
||||
StackManager(const StackManager&) = delete;
|
||||
StackManager& operator=(const StackManager&) = delete;
|
||||
};
|
||||
|
@ -21,7 +21,6 @@
|
||||
|
||||
using PtJson = panda::ecmascript::tooling::PtJson;
|
||||
namespace OHOS::ArkCompiler::Toolchain {
|
||||
VariableManager VariableManager::instance_;
|
||||
void TreeNode::AddChild(std::unique_ptr<PropertyDescriptor> descriptor)
|
||||
{
|
||||
children.push_back(std::make_unique<TreeNode>(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<GetHeapUsageReturns> heapUsageReturns)
|
||||
{
|
||||
heapUsageInfo_.SetUsedSize(heapUsageReturns->GetUsedSize());
|
||||
|
@ -74,7 +74,7 @@ private:
|
||||
|
||||
class VariableManager final {
|
||||
public:
|
||||
static VariableManager& GetInstance();
|
||||
VariableManager(int32_t sessionId) : sessionId_(sessionId) {}
|
||||
void SetHeapUsageInfo(std::unique_ptr<GetHeapUsageReturns> 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;
|
||||
|
263
tooling/client/manager/watch_manager.cpp
Normal file
263
tooling/client/manager/watch_manager.cpp
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* 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/manager/watch_manager.h"
|
||||
|
||||
#include "common/log_wrapper.h"
|
||||
#include "tooling/client/session/session.h"
|
||||
|
||||
using PtJson = panda::ecmascript::tooling::PtJson;
|
||||
using Result = panda::ecmascript::tooling::Result;
|
||||
namespace OHOS::ArkCompiler::Toolchain {
|
||||
WatchManager::WatchManager(uint32_t sessionId)
|
||||
: sessionId_(sessionId), runtimeClient_(sessionId)
|
||||
{
|
||||
}
|
||||
|
||||
void WatchManager::SendRequestWatch(const int32_t &watchInfoIndex, const std::string &callFrameId)
|
||||
{
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
uint32_t id = session->GetMessageId();
|
||||
watchInfoMap_.emplace(id, watchInfoIndex);
|
||||
|
||||
std::unique_ptr<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Debugger.evaluateOnCallFrame");
|
||||
|
||||
std::unique_ptr<PtJson> params = PtJson::CreateObject();
|
||||
params->Add("callFrameId", callFrameId.c_str());
|
||||
params->Add("expression", watchInfoList_[watchInfoIndex].c_str());
|
||||
params->Add("objectGroup", "watch-group");
|
||||
params->Add("includeCommandLineAPI", false);
|
||||
params->Add("silent", true);
|
||||
params->Add("returnByValue", false);
|
||||
params->Add("generatePreview", false);
|
||||
params->Add("throwOnSideEffect", false);
|
||||
request->Add("params", params);
|
||||
|
||||
std::string message = request->Stringify();
|
||||
if (session->ClientSendReq(message)) {
|
||||
inputRowFlag_++;
|
||||
session->GetDomainManager().SetDomainById(id, "Debugger");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void WatchManager::GetPropertiesCommand(const int32_t &watchInfoIndex, const std::string &objectId)
|
||||
{
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
uint32_t id = session->GetMessageId();
|
||||
watchInfoMap_.emplace(id, watchInfoIndex);
|
||||
|
||||
std::unique_ptr<PtJson> request = PtJson::CreateObject();
|
||||
request->Add("id", id);
|
||||
request->Add("method", "Runtime.getProperties");
|
||||
|
||||
std::unique_ptr<PtJson> params = PtJson::CreateObject();
|
||||
params->Add("accessorPropertiesOnly", false);
|
||||
params->Add("generatePreview", true);
|
||||
params->Add("objectId", objectId.c_str());
|
||||
params->Add("ownProperties", true);
|
||||
request->Add("params", params);
|
||||
|
||||
std::string message = request->Stringify();
|
||||
if (session->ClientSendReq(message)) {
|
||||
session->GetDomainManager().SetDomainById(id, "Debugger");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void WatchManager::RequestWatchInfo(const std::unique_ptr<PtJson> &json)
|
||||
{
|
||||
Result ret = json->GetString("callFrameId", &callFrameId_);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("arkdb: find callFrameId error");
|
||||
return;
|
||||
}
|
||||
for (uint i = 0; i < watchInfoList_.size(); i++) {
|
||||
SendRequestWatch(i, callFrameId_);
|
||||
}
|
||||
}
|
||||
|
||||
std::string WatchManager::GetCallFrameId()
|
||||
{
|
||||
return callFrameId_;
|
||||
}
|
||||
|
||||
int WatchManager::GetWatchInfoSize()
|
||||
{
|
||||
return watchInfoList_.size();
|
||||
}
|
||||
|
||||
void WatchManager::AddWatchInfo(const std::string& watchInfo)
|
||||
{
|
||||
watchInfoList_.emplace_back(watchInfo);
|
||||
}
|
||||
|
||||
bool WatchManager::GetDebugState()
|
||||
{
|
||||
return IsDebug_;
|
||||
}
|
||||
void WatchManager::DebugFalseState()
|
||||
{
|
||||
IsDebug_ = false;
|
||||
}
|
||||
void WatchManager::DebugTrueState()
|
||||
{
|
||||
IsDebug_ = true;
|
||||
}
|
||||
|
||||
void WatchManager::SetWatchInfoMap(const int &id, const int &index)
|
||||
{
|
||||
watchInfoMap_.emplace(id, index);
|
||||
}
|
||||
|
||||
bool WatchManager::HandleWatchResult(const std::unique_ptr<PtJson> &json, int32_t id)
|
||||
{
|
||||
Result ret;
|
||||
std::unique_ptr<PtJson> result;
|
||||
ret = json->GetObject("result", &result);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse result error");
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<PtJson> watchResult;
|
||||
ret = result->GetObject("result", &watchResult);
|
||||
if (ret != Result::SUCCESS) {
|
||||
ShowWatchResult2(id, std::move(json));
|
||||
LOGE("json parse result error");
|
||||
return false;
|
||||
}
|
||||
if (!ShowWatchResult(std::move(watchResult), id)) {
|
||||
return false;
|
||||
}
|
||||
inputRowFlag_--;
|
||||
if (inputRowFlag_ == 0) {
|
||||
std::cout << ">>> ";
|
||||
fflush(stdout);
|
||||
isShowWatchInfo_ = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool WatchManager::ShowWatchResult(const std::unique_ptr<PtJson> &result, int32_t id)
|
||||
{
|
||||
std::string type;
|
||||
Result ret = result->GetString("type", &type);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse type error");
|
||||
return false;
|
||||
}
|
||||
if (inputRowFlag_ == GetWatchInfoSize() && isShowWatchInfo_) {
|
||||
std::cout << "watch info :" << std::endl;
|
||||
isShowWatchInfo_ = false;
|
||||
}
|
||||
if (type == "undefined") {
|
||||
auto it = watchInfoMap_.find(id);
|
||||
if (it == watchInfoMap_.end()) {
|
||||
return false;
|
||||
}
|
||||
std::cout << " " << watchInfoList_[it->second] << " = undefined" << std::endl;
|
||||
} else if (type == "object") {
|
||||
std::string objectId;
|
||||
ret = result->GetString("objectId", &objectId);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse object error");
|
||||
return false;
|
||||
}
|
||||
auto it = watchInfoMap_.find(id);
|
||||
if (it == watchInfoMap_.end()) {
|
||||
return false;
|
||||
}
|
||||
GetPropertiesCommand(it->second, objectId);
|
||||
inputRowFlag_++;
|
||||
} else {
|
||||
auto it = watchInfoMap_.find(id);
|
||||
if (it == watchInfoMap_.end()) {
|
||||
return false;
|
||||
}
|
||||
std::string description;
|
||||
ret = result->GetString("description", &description);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse description error");
|
||||
return false;
|
||||
}
|
||||
std::cout << " " << watchInfoList_[it->second] << " = " << description << std::endl;
|
||||
}
|
||||
watchInfoMap_.erase(id);
|
||||
DebugTrueState();
|
||||
return true;
|
||||
}
|
||||
|
||||
void WatchManager::OutputWatchResult(const std::unique_ptr<PtJson> &watchResult)
|
||||
{
|
||||
for (int32_t i = 0; i < watchResult->GetSize(); i++) {
|
||||
std::string name;
|
||||
Result ret = watchResult->Get(i)->GetString("name", &name);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse name error");
|
||||
continue;
|
||||
}
|
||||
std::unique_ptr<PtJson> value;
|
||||
ret = watchResult->Get(i)->GetObject("value", &value);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse value error");
|
||||
continue;
|
||||
}
|
||||
std::string description;
|
||||
ret = value->GetString("description", &description);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse description error");
|
||||
continue;
|
||||
}
|
||||
std::cout << name << " = " << description;
|
||||
if (i < watchResult->GetSize() - 1) {
|
||||
std::cout << ", ";
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool WatchManager::ShowWatchResult2(const int &id, const std::unique_ptr<PtJson> &result)
|
||||
{
|
||||
std::unique_ptr<PtJson> resultWatch;
|
||||
Result ret = result->GetObject("result", &resultWatch);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse result error");
|
||||
return false;
|
||||
}
|
||||
std::unique_ptr<PtJson> watchResult;
|
||||
ret = resultWatch->GetArray("result", &watchResult);
|
||||
if (ret != Result::SUCCESS) {
|
||||
LOGE("json parse result error");
|
||||
return false;
|
||||
}
|
||||
auto it = watchInfoMap_.find(id);
|
||||
if (it == watchInfoMap_.end()) {
|
||||
return false;
|
||||
}
|
||||
std::cout << " " << watchInfoList_[it->second] << " = { ";
|
||||
OutputWatchResult(std::move(watchResult));
|
||||
std::cout << " }" << std::endl;
|
||||
inputRowFlag_--;
|
||||
if (inputRowFlag_ == 0) {
|
||||
std::cout << ">>> ";
|
||||
fflush(stdout);
|
||||
isShowWatchInfo_ = true;
|
||||
}
|
||||
DebugTrueState();
|
||||
watchInfoMap_.erase(id);
|
||||
return true;
|
||||
}
|
||||
}
|
63
tooling/client/manager/watch_manager.h
Normal file
63
tooling/client/manager/watch_manager.h
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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_WATCH_MANAGER_H
|
||||
#define ECMASCRIPT_TOOLING_CLIENT_MANAGER_WATCH_MANAGER_H
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "tooling/base/pt_json.h"
|
||||
#include "tooling/base/pt_types.h"
|
||||
#include "tooling/client/domain/runtime_client.h"
|
||||
|
||||
namespace OHOS::ArkCompiler::Toolchain {
|
||||
using PtJson = panda::ecmascript::tooling::PtJson;
|
||||
using Result = panda::ecmascript::tooling::Result;
|
||||
class WatchManager {
|
||||
public:
|
||||
explicit WatchManager(uint32_t sessionId);
|
||||
~WatchManager() = default;
|
||||
|
||||
void SendRequestWatch(const int32_t &watchInfoIndex, const std::string &callFrameId);
|
||||
void GetPropertiesCommand(const int32_t &watchInfoIndex, const std::string &objectId);
|
||||
void RequestWatchInfo(const std::unique_ptr<PtJson> &json);
|
||||
void AddWatchInfo(const std::string& watchInfo);
|
||||
|
||||
bool GetDebugState();
|
||||
void DebugFalseState();
|
||||
void DebugTrueState();
|
||||
bool HandleWatchResult(const std::unique_ptr<PtJson> &json, int32_t id);
|
||||
bool ShowWatchResult(const std::unique_ptr<PtJson> &result, int32_t id);
|
||||
void OutputWatchResult(const std::unique_ptr<PtJson> &watchResult);
|
||||
bool ShowWatchResult2(const int &id, const std::unique_ptr<PtJson> &result);
|
||||
std::string GetCallFrameId();
|
||||
int GetWatchInfoSize();
|
||||
void SetWatchInfoMap(const int &id, const int &index);
|
||||
|
||||
private:
|
||||
[[maybe_unused]] int32_t sessionId_;
|
||||
std::vector<std::string> watchInfoList_;
|
||||
std::unordered_map<int, int> watchInfoMap_;
|
||||
bool IsDebug_;
|
||||
std::string callFrameId_;
|
||||
RuntimeClient runtimeClient_;
|
||||
int inputRowFlag_;
|
||||
bool isShowWatchInfo_ = true;
|
||||
};
|
||||
} // OHOS::ArkCompiler::Toolchain
|
||||
#endif
|
208
tooling/client/session/session.cpp
Executable file
208
tooling/client/session/session.cpp
Executable file
@ -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 <iomanip>
|
||||
|
||||
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), sourceManager_(sessionId), watchManager_(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<uv_handle_t*>(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<Session>(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<Session>(sessionId, sockInfo);
|
||||
if (sessions_[sessionId]->CreateSocket()) {
|
||||
sessions_[sessionId] = nullptr;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
180
tooling/client/session/session.h
Executable file
180
tooling/client/session/session.h
Executable file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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 <atomic>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <pthread.h>
|
||||
#include <thread>
|
||||
#include <uv.h>
|
||||
|
||||
#include "tooling/client/manager/domain_manager.h"
|
||||
#include "tooling/client/manager/breakpoint_manager.h"
|
||||
#include "tooling/client/manager/source_manager.h"
|
||||
#include "tooling/client/manager/stack_manager.h"
|
||||
#include "tooling/client/manager/variable_manager.h"
|
||||
#include "tooling/client/manager/watch_manager.h"
|
||||
#include "tooling/client/websocket/websocket_client.h"
|
||||
|
||||
namespace OHOS::ArkCompiler::Toolchain {
|
||||
using CmdForAllCB = std::function<void(uint32_t sessionId)>;
|
||||
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);
|
||||
}
|
||||
|
||||
SourceManager& GetSourceManager()
|
||||
{
|
||||
return sourceManager_;
|
||||
}
|
||||
|
||||
WatchManager& GetWatchManager()
|
||||
{
|
||||
return watchManager_;
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t sessionId_;
|
||||
std::string sockInfo_;
|
||||
DomainManager domainManager_;
|
||||
WebsocketClient cliSocket_;
|
||||
uv_thread_t socketTid_;
|
||||
std::atomic<uint32_t> messageId_ {1};
|
||||
BreakPointManager breakpoint_;
|
||||
StackManager stackManager_;
|
||||
VariableManager variableManager_;
|
||||
ProfilerSingleton profiler_;
|
||||
SourceManager sourceManager_;
|
||||
WatchManager watchManager_;
|
||||
};
|
||||
|
||||
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<Session> sessions_[MAX_SESSION_NUM];
|
||||
uint32_t currentSessionId_ = 0;
|
||||
};
|
||||
} // namespace OHOS::ArkCompiler::Toolchain
|
||||
#endif
|
@ -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: <command> <options>\n"
|
||||
@ -75,6 +76,11 @@ const std::string HELP_MSG = "usage: <command> <options>\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<std::string> 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,29 +251,56 @@ 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;
|
||||
bool result = profilerClient.DispatcherCmd(cmd);
|
||||
return result ? ErrCode::ERR_OK : ErrCode::ERR_FAIL;
|
||||
}
|
||||
|
||||
ErrCode CliCommand::HandleDebuggerCommand(const std::string &cmd)
|
||||
{
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
BreakPointManager &breakpoint = session->GetBreakPointManager();
|
||||
SourceManager &sourceManager = session->GetSourceManager();
|
||||
WatchManager &watchManager = session->GetWatchManager();
|
||||
if (cmd == "display") {
|
||||
breakpoint.Show();
|
||||
return ErrCode::ERR_OK;
|
||||
}
|
||||
return ErrCode::ERR_OK;
|
||||
|
||||
if (cmd == "infosource") {
|
||||
if (GetArgList().size() == 1) {
|
||||
sourceManager.GetFileSource(std::atoi(GetArgList()[0].c_str()));
|
||||
} else {
|
||||
sourceManager.GetFileName();
|
||||
}
|
||||
return ErrCode::ERR_OK;
|
||||
}
|
||||
|
||||
if (cmd == "list" && watchManager.GetDebugState()) {
|
||||
if (GetArgList().size() == 1) {
|
||||
sourceManager.GetListSource(GetArgList()[0]);
|
||||
} else {
|
||||
sourceManager.GetListSource("");
|
||||
}
|
||||
return ErrCode::ERR_OK;
|
||||
}
|
||||
|
||||
if (cmd == "watch" && GetArgList().size() == 1) {
|
||||
watchManager.AddWatchInfo(GetArgList()[0]);
|
||||
if (watchManager.GetDebugState()) {
|
||||
watchManager.SendRequestWatch(watchManager.GetWatchInfoSize() - 1, watchManager.GetCallFrameId());
|
||||
}
|
||||
return ErrCode::ERR_OK;
|
||||
}
|
||||
return 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();
|
||||
if (cmd == "display") {
|
||||
breakpoint.Show();
|
||||
return ErrCode::ERR_OK;
|
||||
}
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
DebuggerClient &debuggerCli = session->GetDomainManager().GetDebuggerClient();
|
||||
BreakPointManager &breakpoint = session->GetBreakPointManager();
|
||||
|
||||
if (cmd == "delete") {
|
||||
std::string bnumber = GetArgList()[0];
|
||||
@ -281,12 +319,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();
|
||||
}
|
||||
|
||||
@ -294,58 +332,98 @@ ErrCode CliCommand::DebuggerCommand(const std::string &cmd)
|
||||
debuggerCli.AddBreakPointInfo(GetArgList()[0], std::stoi(GetArgList()[1]));
|
||||
}
|
||||
|
||||
result = debuggerCli.DispatcherCmd(id_, cmd, &request);
|
||||
if (HandleDebuggerCommand(cmd) == ErrCode::ERR_OK) {
|
||||
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;
|
||||
bool result = false;
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
RuntimeClient &runtimeClient = session->GetDomainManager().GetRuntimeClient();
|
||||
|
||||
if (cmd == "print" && GetArgList().size() == 1) {
|
||||
runtimeClient.SetIsInitializeTree(false);
|
||||
VariableManager &variableManager = session->GetVariableManager();
|
||||
int32_t objectId = variableManager.FindObjectIdWithIndex(std::stoi(GetArgList()[0]));
|
||||
runtimeClient.SetObjectId(std::to_string(objectId));
|
||||
}
|
||||
|
||||
result = runtimeClient.DispatcherCmd(cmd);
|
||||
if (result) {
|
||||
cliSocket_.ClientSendReq(request);
|
||||
if (domainManager_.GetDomainById(id_).empty()) {
|
||||
domainManager_.SetDomainById(id_, "Debugger");
|
||||
}
|
||||
runtimeClient.SetObjectId("0");
|
||||
} else {
|
||||
return ErrCode::ERR_FAIL;
|
||||
}
|
||||
return ErrCode::ERR_OK;
|
||||
}
|
||||
|
||||
ErrCode CliCommand::RuntimeCommand(const std::string &cmd)
|
||||
ErrCode CliCommand::SessionAddCommand([[maybe_unused]] const std::string &cmd)
|
||||
{
|
||||
std::cout << "exe success, cmd is " << cmd << std::endl;
|
||||
std::string request;
|
||||
bool result = false;
|
||||
RuntimeClient &runtimeClient = domainManager_.GetRuntimeClient();
|
||||
|
||||
if (cmd == "print" && GetArgList().size() == 1) {
|
||||
runtimeClient.SetIsInitializeTree(false);
|
||||
VariableManager &variableManager = VariableManager::GetInstance();
|
||||
int32_t objectId = variableManager.FindObjectIdWithIndex(std::stoi(GetArgList()[0]));
|
||||
runtimeClient.SetObjectId(std::to_string(objectId));
|
||||
VecStr argList = GetArgList();
|
||||
if (argList.size() >= 1) {
|
||||
if (!SessionManager::getInstance().CreateNewSession(argList[0])) {
|
||||
std::cout << "session create success" << std::endl;
|
||||
return ErrCode::ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
result = runtimeClient.DispatcherCmd(id_, cmd, &request);
|
||||
if (result) {
|
||||
cliSocket_.ClientSendReq(request);
|
||||
runtimeClient.SetObjectId("0");
|
||||
if (domainManager_.GetDomainById(id_).empty()) {
|
||||
domainManager_.SetDomainById(id_, "Runtime");
|
||||
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;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ErrCode::ERR_FAIL;
|
||||
}
|
||||
return ErrCode::ERR_OK;
|
||||
}
|
||||
|
||||
ErrCode CliCommand::TestCommand(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");
|
||||
}
|
||||
}
|
||||
Session *session = SessionManager::getInstance().GetSessionById(sessionId_);
|
||||
TestClient &testClient = session->GetDomainManager().GetTestClient();
|
||||
testClient.DispatcherCmd(cmd);
|
||||
} else {
|
||||
return ErrCode::ERR_FAIL;
|
||||
}
|
||||
|
@ -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<std::string, std::string>;
|
||||
@ -39,8 +40,8 @@ enum class ErrCode : uint8_t {
|
||||
|
||||
class CliCommand {
|
||||
public:
|
||||
CliCommand(std::vector<std::string> cliCmdStr, int cmdId, DomainManager &domainManager, WebsocketClient &cliSocket)
|
||||
: cmd_(cliCmdStr[0]), id_(cmdId), domainManager_(domainManager), cliSocket_(cliSocket)
|
||||
CliCommand(std::vector<std::string> cliCmdStr, uint32_t sessionId)
|
||||
: cmd_(cliCmdStr[0]), sessionId_(sessionId)
|
||||
{
|
||||
for (size_t i = 1u; i < cliCmdStr.size(); i++) {
|
||||
argList_.push_back(cliCmdStr[i]);
|
||||
@ -53,17 +54,17 @@ public:
|
||||
ErrCode ExecCommand();
|
||||
void CreateCommandMap();
|
||||
ErrCode HeapProfilerCommand(const std::string &cmd);
|
||||
ErrCode HandleDebuggerCommand(const std::string &cmd);
|
||||
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 +75,7 @@ private:
|
||||
VecStr argList_ {};
|
||||
std::map<StrPair, std::function<ErrCode()>> commandMap_;
|
||||
std::string resultReceiver_ = "";
|
||||
uint32_t id_ = 0;
|
||||
DomainManager &domainManager_;
|
||||
WebsocketClient &cliSocket_;
|
||||
uint32_t sessionId_;
|
||||
};
|
||||
} // namespace OHOS::ArkCompiler::Toolchain
|
||||
|
||||
|
@ -55,6 +55,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<std::string> Utils::SplitString(const std::string &str, const std::string &delimiter)
|
||||
{
|
||||
std::size_t strIndex = 0;
|
||||
|
@ -24,6 +24,7 @@ class Utils {
|
||||
public:
|
||||
static bool RealPath(const std::string &path, std::string &realPath, bool readOnly = true);
|
||||
static bool GetCurrentTime(char *date, char *tim, size_t size);
|
||||
static bool StrToUInt(const char *content, uint32_t *result);
|
||||
static std::vector<std::string> SplitString(const std::string &str, const std::string &delimiter);
|
||||
};
|
||||
} // OHOS::ArkCompiler::Toolchain
|
||||
|
@ -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<std::string> stateStr = {
|
||||
"uninited",
|
||||
"inited",
|
||||
"connected"
|
||||
};
|
||||
|
||||
return stateStr[socketState_];
|
||||
}
|
||||
} // namespace OHOS::ArkCompiler::Toolchain
|
@ -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};
|
||||
|
@ -28,6 +28,7 @@ config("debug_api_test") {
|
||||
"//arkcompiler/ets_runtime",
|
||||
"../..",
|
||||
"//third_party/cJSON",
|
||||
"//third_party/libuv/include",
|
||||
]
|
||||
}
|
||||
|
||||
|
@ -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<std::string> 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<std::string> 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<std::string> 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";
|
||||
|
@ -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_;
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ public:
|
||||
// break on start
|
||||
{SocketAction::RECV, "Debugger.paused", ActionRule::STRING_CONTAIN},
|
||||
// set breakpoint
|
||||
{SocketAction::SEND, "b " DEBUGGER_JS_DIR "sample.js 21"},
|
||||
{SocketAction::SEND, "b " DEBUGGER_JS_DIR "sample.js 22"},
|
||||
{SocketAction::RECV, "", ActionRule::CUSTOM_RULE, MatchRule::replySuccess},
|
||||
// hit breakpoint after resume first time
|
||||
{SocketAction::SEND, "resume"},
|
||||
|
Loading…
Reference in New Issue
Block a user