From c3521a3678ed48676b46902fe8e95fe58b1a5b67 Mon Sep 17 00:00:00 2001 From: yp9522 Date: Fri, 18 Apr 2025 14:16:22 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E7=BD=AE=E3=80=81=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=96=AD=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: https://gitee.com/openharmony/arkcompiler_toolchain/issues/IC84O1 Signed-off-by: yp9522 Change-Id: I67bc2977204c2136305d762dc2a7af39df5f8088 --- inspector/inspector.cpp | 72 +++++++++++++++++++ inspector/inspector.h | 6 ++ tooling/agent/debugger_impl.cpp | 41 +++++++++++ tooling/agent/debugger_impl.h | 6 ++ tooling/debugger_service.cpp | 57 ++++++++++++++++ tooling/debugger_service.h | 6 ++ tooling/dispatcher.cpp | 89 ++++++++++++++++++++++++ tooling/dispatcher.h | 8 +++ tooling/test/debugger_impl_test.cpp | 95 ++++++++++++++++++++++++++ tooling/test/debugger_service_test.cpp | 50 ++++++++++++++ tooling/test/dispatcher_test.cpp | 86 +++++++++++++++++++++++ 11 files changed, 516 insertions(+) diff --git a/inspector/inspector.cpp b/inspector/inspector.cpp index 0988b350..979436f0 100644 --- a/inspector/inspector.cpp +++ b/inspector/inspector.cpp @@ -50,6 +50,9 @@ using OnMessage = void(*)(void*, std::string&&); using ProcessMessage = void(*)(void*); using GetDispatchStatus = int32_t(*)(void*); using GetCallFrames = char*(*)(void*); +using SaveAllBreakpoints = char*(*)(void*, const char*); +using RemoveBreakpoint = char*(*)(void*, const char*); +using SetBreakpoint = char*(*)(void*, const char*); OnMessage g_onMessage = nullptr; InitializeDebugger g_initializeDebugger = nullptr; @@ -58,6 +61,9 @@ WaitForDebugger g_waitForDebugger = nullptr; ProcessMessage g_processMessage = nullptr; GetDispatchStatus g_getDispatchStatus = nullptr; GetCallFrames g_getCallFrames = nullptr; +SaveAllBreakpoints g_saveAllBreakpoints = nullptr; +RemoveBreakpoint g_removeBreakpoint = nullptr; +SetBreakpoint g_setBreakpoint = nullptr; std::atomic g_hasArkFuncsInited = false; std::unordered_map g_inspectors; @@ -222,6 +228,24 @@ bool InitializeArkFunctionsOthers() ResetServiceLocked(g_vm, true); return false; } + g_saveAllBreakpoints = reinterpret_cast( + GetArkDynFunction("SaveAllBreakpoints")); + if (g_saveAllBreakpoints == nullptr) { + ResetServiceLocked(g_vm, true); + return false; + } + g_removeBreakpoint = reinterpret_cast( + GetArkDynFunction("RemoveBreakpoint")); + if (g_removeBreakpoint == nullptr) { + ResetServiceLocked(g_vm, true); + return false; + } + g_setBreakpoint = reinterpret_cast( + GetArkDynFunction("SetBreakpoint")); + if (g_setBreakpoint == nullptr) { + ResetServiceLocked(g_vm, true); + return false; + } return true; } #else @@ -235,6 +259,9 @@ bool InitializeArkFunctionsIOS() g_getDispatchStatus = reinterpret_cast(&tooling::GetDispatchStatus); g_processMessage = reinterpret_cast(&tooling::ProcessMessage); g_getCallFrames = reinterpret_cast(&tooling::GetCallFrames); + g_saveAllBreakpoints = reinterpret_cast(&tooling::SaveAllBreakpoints); + g_removeBreakpoint = reinterpret_cast(&tooling::RemoveBreakpoint); + g_setBreakpoint = reinterpret_cast(&tooling::SetBreakpoint); return true; } #endif @@ -479,4 +506,49 @@ const char* GetJsBacktrace() return ""; #endif } + +const char* SaveAllJsBreakpoints(const char* message) +{ + (void)message; // Mark the parameter as unused to avoid warnings. +#if defined(OHOS_PLATFORM) + void* vm = GetEcmaVM(Inspector::GetThreadOrTaskId()); + if (g_saveAllBreakpoints == nullptr) { + LOGE("SaveAllBreakpoints symbol resolve failed"); + return ""; + } + return g_saveAllBreakpoints(vm, message); +#else + return ""; +#endif +} + +const char* RemoveJsBreakpoint(const char* message) +{ + (void)message; // Mark the parameter as unused to avoid warnings. +#if defined(OHOS_PLATFORM) + void* vm = GetEcmaVM(Inspector::GetThreadOrTaskId()); + if (g_removeBreakpoint == nullptr) { + LOGE("RemoveBreakpoint symbol resolve failed"); + return ""; + } + return g_removeBreakpoint(vm, message); +#else + return ""; +#endif +} + +const char* SetJsBreakpoint(const char* message) +{ + (void)message; // Mark the parameter as unused to avoid warnings. +#if defined(OHOS_PLATFORM) + void* vm = GetEcmaVM(Inspector::GetThreadOrTaskId()); + if (g_setBreakpoint == nullptr) { + LOGE("SetBreakpoint symbol resolve failed"); + return ""; + } + return g_setBreakpoint(vm, message); +#else + return ""; +#endif +} } // namespace OHOS::ArkCompiler::Toolchain diff --git a/inspector/inspector.h b/inspector/inspector.h index 9b4db968..5402b6a3 100644 --- a/inspector/inspector.h +++ b/inspector/inspector.h @@ -50,6 +50,12 @@ void StoreDebuggerInfo(int tid, void* vm, const DebuggerPostTask& debuggerPostTa // The returned pointer must be released using free() after it is no longer needed. // Failure to release the memory will result in memory leaks. const char* GetJsBacktrace(); + +const char* SaveAllJsBreakpoints(const char* message); + +const char* RemoveJsBreakpoint(const char* message); + +const char* SetJsBreakpoint(const char* message); #if __cplusplus } #endif diff --git a/tooling/agent/debugger_impl.cpp b/tooling/agent/debugger_impl.cpp index a8a80762..83cb5f1d 100755 --- a/tooling/agent/debugger_impl.cpp +++ b/tooling/agent/debugger_impl.cpp @@ -774,6 +774,18 @@ void DebuggerImpl::DispatcherImpl::RemoveBreakpointsByUrl(const DispatchRequest SendResponse(request, response); } +std::string DebuggerImpl::DispatcherImpl::RemoveBreakpointsByUrl( + const int32_t callId, std::unique_ptr params) +{ + if (params == nullptr) { + LOG_DEBUGGER(WARN) << "DebuggerImpl::DispatcherImpl::RemoveBreakpointsByUrl: params is nullptr"; + return ReturnsValueToString(callId, DispatchResponsetToJson(DispatchResponse::Fail("wrong params"))); + } + + DispatchResponse response = debugger_->RemoveBreakpointsByUrl(*params); + return ReturnsValueToString(callId, DispatchResponsetToJson(response)); +} + void DebuggerImpl::DispatcherImpl::Resume(const DispatchRequest &request) { std::unique_ptr params = ResumeParams::Create(request.GetParams()); @@ -833,6 +845,24 @@ void DebuggerImpl::DispatcherImpl::GetPossibleAndSetBreakpointByUrl(const Dispat SendResponse(request, response, result); } +std::string DebuggerImpl::DispatcherImpl::GetPossibleAndSetBreakpointByUrl( + const int32_t callId, std::unique_ptr params) +{ + if (params == nullptr) { + LOG_DEBUGGER(WARN) << "DebuggerImpl::DispatcherImpl::GetPossibleAndSetBreakpointByUrl: params is nullptr"; + return ReturnsValueToString(callId, DispatchResponsetToJson(DispatchResponse::Fail("wrong params"))); + } + std::vector> outLocation; + DispatchResponse response = debugger_->GetPossibleAndSetBreakpointByUrl(*params, outLocation); + if (outLocation.empty() || !response.IsOk()) { + LOG_DEBUGGER(WARN) << "outLocation is empty or response code is not ok"; + return ReturnsValueToString(callId, DispatchResponsetToJson(response)); + } + + GetPossibleAndSetBreakpointByUrlReturns result(std::move(outLocation)); + return ReturnsValueToString(callId, result.ToJson()); +} + void DebuggerImpl::DispatcherImpl::SaveAllPossibleBreakpoints(const DispatchRequest &request) { std::unique_ptr params = @@ -845,6 +875,17 @@ void DebuggerImpl::DispatcherImpl::SaveAllPossibleBreakpoints(const DispatchRequ SendResponse(request, response); } +std::string DebuggerImpl::DispatcherImpl::SaveAllPossibleBreakpoints( + const int32_t callId, std::unique_ptr params) +{ + if (params == nullptr) { + LOG_DEBUGGER(WARN) << "DebuggerImpl::DispatcherImpl::SaveAllPossibleBreakpoints: params is nullptr"; + return ReturnsValueToString(callId, DispatchResponsetToJson(DispatchResponse::Fail("wrong params"))); + } + DispatchResponse response = debugger_->SaveAllPossibleBreakpoints(*params); + return ReturnsValueToString(callId, DispatchResponsetToJson(response)); +} + void DebuggerImpl::DispatcherImpl::SetSymbolicBreakpoints(const DispatchRequest &request) { std::unique_ptr params = diff --git a/tooling/agent/debugger_impl.h b/tooling/agent/debugger_impl.h index 9ee191c5..c67c9fd5 100644 --- a/tooling/agent/debugger_impl.h +++ b/tooling/agent/debugger_impl.h @@ -187,6 +187,12 @@ public: void SaveAllPossibleBreakpoints(const DispatchRequest &request); void SetSymbolicBreakpoints(const DispatchRequest &request); void RemoveSymbolicBreakpoints(const DispatchRequest &request); + std::string SaveAllPossibleBreakpoints(const int32_t callId, + std::unique_ptr params); + std::string RemoveBreakpointsByUrl(const int32_t callId, + std::unique_ptr params); + std::string GetPossibleAndSetBreakpointByUrl(const int32_t callId, + std::unique_ptr params); enum class Method { CONTINUE_TO_LOCATION, diff --git a/tooling/debugger_service.cpp b/tooling/debugger_service.cpp index 86afa0a4..01ae1535 100644 --- a/tooling/debugger_service.cpp +++ b/tooling/debugger_service.cpp @@ -115,4 +115,61 @@ const char* GetCallFrames(const ::panda::ecmascript::EcmaVM *vm) } return ""; } + +const char* SaveAllBreakpoints(const ::panda::ecmascript::EcmaVM *vm, const char* message) +{ + if (vm == nullptr || vm->GetJsDebuggerManager() == nullptr) { + LOG_DEBUGGER(ERROR) << "VM has already been destroyed"; + return ""; + } + ProtocolHandler *handler = vm->GetJsDebuggerManager()->GetDebuggerHandler(); + if (LIKELY(handler != nullptr)) { + auto dispatcher = handler->GetDispatcher(); + if (LIKELY(dispatcher != nullptr)) { + auto info = dispatcher->SaveAllBreakpoints(message); + const char* buffer = strdup(info.c_str()); + return buffer; + } + return ""; + } + return ""; +} + +const char* RemoveBreakpoint(const ::panda::ecmascript::EcmaVM *vm, const char* message) +{ + if (vm == nullptr || vm->GetJsDebuggerManager() == nullptr) { + LOG_DEBUGGER(ERROR) << "VM has already been destroyed"; + return ""; + } + ProtocolHandler *handler = vm->GetJsDebuggerManager()->GetDebuggerHandler(); + if (LIKELY(handler != nullptr)) { + auto dispatcher = handler->GetDispatcher(); + if (LIKELY(dispatcher != nullptr)) { + auto info = dispatcher->RemoveBreakpoint(message); + const char* buffer = strdup(info.c_str()); + return buffer; + } + return ""; + } + return ""; +} + +const char* SetBreakpoint(const ::panda::ecmascript::EcmaVM *vm, const char* message) +{ + if (vm == nullptr || vm->GetJsDebuggerManager() == nullptr) { + LOG_DEBUGGER(ERROR) << "VM has already been destroyed"; + return ""; + } + ProtocolHandler *handler = vm->GetJsDebuggerManager()->GetDebuggerHandler(); + if (LIKELY(handler != nullptr)) { + auto dispatcher = handler->GetDispatcher(); + if (LIKELY(dispatcher != nullptr)) { + auto info = dispatcher->SetBreakpoint(message); + const char* buffer = strdup(info.c_str()); + return buffer; + } + return ""; + } + return ""; +} } // namespace panda::ecmascript::tooling \ No newline at end of file diff --git a/tooling/debugger_service.h b/tooling/debugger_service.h index 95bd86d9..7834a40a 100644 --- a/tooling/debugger_service.h +++ b/tooling/debugger_service.h @@ -47,6 +47,12 @@ TOOLCHAIN_EXPORT int32_t GetDispatchStatus(const ::panda::ecmascript::EcmaVM *vm TOOLCHAIN_EXPORT const char* GetCallFrames(const ::panda::ecmascript::EcmaVM *vm); +TOOLCHAIN_EXPORT const char* SaveAllBreakpoints(const ::panda::ecmascript::EcmaVM *vm, const char* message); + +TOOLCHAIN_EXPORT const char* RemoveBreakpoint(const ::panda::ecmascript::EcmaVM *vm, const char* message); + +TOOLCHAIN_EXPORT const char* SetBreakpoint(const ::panda::ecmascript::EcmaVM *vm, const char* message); + #ifdef __cplusplus #if __cplusplus } diff --git a/tooling/dispatcher.cpp b/tooling/dispatcher.cpp index afbdbc07..791d6b0e 100644 --- a/tooling/dispatcher.cpp +++ b/tooling/dispatcher.cpp @@ -130,6 +130,32 @@ void DispatcherBase::SendResponse(const DispatchRequest &request, const Dispatch } } +std::string DispatcherBase::ReturnsValueToString(const int32_t callId, const std::unique_ptr resultObj) +{ + std::unique_ptr ptJson = PtJson::CreateObject(); + ptJson->Add("id", callId); + ptJson->Add("result", resultObj); + std::string str = ptJson->Stringify(); + if (str.empty()) { + LOG_DEBUGGER(ERROR) << "Dispatcher::ReturnsValueToString: json stringify error"; + return ""; + } + ptJson->ReleaseRoot(); + return str; +} + +std::unique_ptr DispatcherBase::DispatchResponsetToJson(const DispatchResponse &response) const +{ + std::unique_ptr result = PtJson::CreateObject(); + + if (!response.IsOk()) { + result->Add("code", static_cast(response.GetError())); + result->Add("message", response.GetMessage().c_str()); + } + + return result; +} + Dispatcher::Dispatcher(const EcmaVM *vm, ProtocolChannel *channel) { // profiler @@ -214,4 +240,67 @@ std::string Dispatcher::GetJsFrames() const } return ""; } + +std::string Dispatcher::SaveAllBreakpoints(const char* message) const +{ + DispatchRequest request(message); + if (request.GetMethod() == "saveAllPossibleBreakpoints") { + auto dispatcher = dispatchers_.find("Debugger"); + if (dispatcher != dispatchers_.end()) { + return SaveAllBreakpoints(request, dispatcher->second.get()); + } + return ""; + } + return ""; +} + +std::string Dispatcher::SaveAllBreakpoints(const DispatchRequest &request, DispatcherBase *dispatcher) const +{ + auto debuggerImpl = reinterpret_cast(dispatcher); + std::unique_ptr params = + SaveAllPossibleBreakpointsParams::Create(request.GetParams()); + return debuggerImpl->SaveAllPossibleBreakpoints(request.GetCallId(), std::move(params)); +} + +std::string Dispatcher::RemoveBreakpoint(const char* message) const +{ + DispatchRequest request(message); + if (request.GetMethod() == "removeBreakpointsByUrl") { + auto dispatcher = dispatchers_.find("Debugger"); + if (dispatcher != dispatchers_.end()) { + return RemoveBreakpoint(request, dispatcher->second.get()); + } + return ""; + } + return ""; +} + +std::string Dispatcher::RemoveBreakpoint(const DispatchRequest &request, DispatcherBase *dispatcher) const +{ + auto debuggerImpl = reinterpret_cast(dispatcher); + std::unique_ptr params = + RemoveBreakpointsByUrlParams::Create(request.GetParams()); + return debuggerImpl->RemoveBreakpointsByUrl(request.GetCallId(), std::move(params)); +} + +std::string Dispatcher::SetBreakpoint(const char* message) const +{ + DispatchRequest request(message); + if (request.GetMethod() == "getPossibleAndSetBreakpointByUrl") { + auto dispatcher = dispatchers_.find("Debugger"); + if (dispatcher != dispatchers_.end()) { + return SetBreakpoint(request, dispatcher->second.get()); + } + return ""; + } + return ""; +} + +std::string Dispatcher::SetBreakpoint(const DispatchRequest &request, DispatcherBase *dispatcher) const +{ + auto debuggerImpl = reinterpret_cast(dispatcher); + std::unique_ptr params = + GetPossibleAndSetBreakpointParams::Create(request.GetParams()); + return debuggerImpl->GetPossibleAndSetBreakpointByUrl(request.GetCallId(), std::move(params)); +} } // namespace panda::ecmascript::tooling diff --git a/tooling/dispatcher.h b/tooling/dispatcher.h index 7066f86e..8bbad751 100644 --- a/tooling/dispatcher.h +++ b/tooling/dispatcher.h @@ -136,6 +136,8 @@ public: protected: void SendResponse(const DispatchRequest &request, const DispatchResponse &response, const PtBaseReturns &result = PtBaseReturns()); + std::string ReturnsValueToString(const int32_t callId, const std::unique_ptr resultObj); + std::unique_ptr DispatchResponsetToJson(const DispatchResponse &response) const; private: ProtocolChannel *channel_ {nullptr}; @@ -150,8 +152,14 @@ public: ~Dispatcher() = default; void Dispatch(const DispatchRequest &request); std::string GetJsFrames() const; + std::string SaveAllBreakpoints(const char* message) const; + std::string RemoveBreakpoint(const char* message) const; + std::string SetBreakpoint(const char* message) const; private: + std::string SaveAllBreakpoints(const DispatchRequest &request, DispatcherBase *dispatcher) const; + std::string RemoveBreakpoint(const DispatchRequest &request, DispatcherBase *dispatcher) const; + std::string SetBreakpoint(const DispatchRequest &request, DispatcherBase *dispatcher) const; std::unordered_map> dispatchers_ {}; NO_COPY_SEMANTIC(Dispatcher); diff --git a/tooling/test/debugger_impl_test.cpp b/tooling/test/debugger_impl_test.cpp index 7e598763..e14c509c 100644 --- a/tooling/test/debugger_impl_test.cpp +++ b/tooling/test/debugger_impl_test.cpp @@ -648,6 +648,61 @@ HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_RemoveBreakpointsByUrl__002) } } +HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_RemoveBreakpointsByUrl__003) +{ + ProtocolChannel *protocolChannel = new ProtocolHandler(nullptr, ecmaVm); + auto runtimeImpl = std::make_unique(ecmaVm, protocolChannel); + auto debuggerImpl = std::make_unique(ecmaVm, protocolChannel, runtimeImpl.get()); + auto dispatcherImpl = std::make_unique(protocolChannel, std::move(debuggerImpl)); + int32_t callId = 0; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.removeBreakpointsByUrl", + "params": { + "url": "entry|entry|1.0.0|src/main/ets/pages/Index.ts" + } + })"; + std::unique_ptr params = + RemoveBreakpointsByUrlParams::Create(DispatchRequest(msg).GetParams()); + std::string result = dispatcherImpl->RemoveBreakpointsByUrl(callId, std::move(params)); + EXPECT_STREQ(result.c_str(), R"({"id":0,"result":{}})"); + if (protocolChannel) { + delete protocolChannel; + protocolChannel = nullptr; + } +} + +HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_SaveAllPossibleBreakpoints__001) +{ + ProtocolChannel *protocolChannel = new ProtocolHandler(nullptr, ecmaVm); + auto runtimeImpl = std::make_unique(ecmaVm, protocolChannel); + auto debuggerImpl = std::make_unique(ecmaVm, protocolChannel, runtimeImpl.get()); + auto dispatcherImpl = std::make_unique(protocolChannel, std::move(debuggerImpl)); + int32_t callId = 0; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.saveAllPossibleBreakpoints", + "params": { + "locations": { + "entry|entry|1.0.0|src/main/ets/pages/Index.ts": [{ + "lineNumber": 59, + "columnNumber": 16 + }] + } + } + })"; + std::unique_ptr params = + SaveAllPossibleBreakpointsParams::Create(DispatchRequest(msg).GetParams()); + std::string result = dispatcherImpl->SaveAllPossibleBreakpoints(callId, std::move(params)); + EXPECT_STREQ(result.c_str(), R"({"id":0,"result":{}})"); + if (protocolChannel) { + delete protocolChannel; + protocolChannel = nullptr; + } +} + HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_SetSymbolBreakpoints_001) { std::string outStrForCallbackCheck = ""; @@ -1333,6 +1388,46 @@ HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_GetPossibleAndSetBreakpoint__0 } } +HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_GetPossibleAndSetBreakpointByUrl__001) +{ + ProtocolChannel *protocolChannel = new ProtocolHandler(nullptr, ecmaVm); + auto runtimeImpl = std::make_unique(ecmaVm, protocolChannel); + auto debuggerImpl = std::make_unique(ecmaVm, protocolChannel, runtimeImpl.get()); + auto dispatcherImpl = std::make_unique(protocolChannel, std::move(debuggerImpl)); + int32_t callId = 0; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.getPossibleAndSetBreakpointByUrl", + "params": { + "locations": [{ + "url": "entry|entry|1.0.0|src/main/ets/pages/Index.ts", + "lineNumber": 59, + "columnNumber": 16 + }] + } + })"; + std::unique_ptr params = + GetPossibleAndSetBreakpointParams::Create(DispatchRequest(msg).GetParams()); + std::string result = dispatcherImpl->GetPossibleAndSetBreakpointByUrl(callId, std::move(params)); + EXPECT_STREQ(result.c_str(), + R"({ + "id": 0, + "result": { + "locations": [{ + "lineNumber": 59, + "columnNumber": 0, + "id": "id:59:0:entry|entry|1.0.0|src/main/ets/pages/Index.ts", + "scriptId": 1 + }] + } + })"); + if (protocolChannel) { + delete protocolChannel; + protocolChannel = nullptr; + } +} + HWTEST_F_L0(DebuggerImplTest, Dispatcher_Dispatch_DropFrame__001) { std::string outStrForCallbackCheck = ""; diff --git a/tooling/test/debugger_service_test.cpp b/tooling/test/debugger_service_test.cpp index 68b8796f..d28bca1e 100644 --- a/tooling/test/debugger_service_test.cpp +++ b/tooling/test/debugger_service_test.cpp @@ -135,4 +135,54 @@ HWTEST_F_L0(DebuggerServiceTest, GetDispatchStatusTest) int32_t GetDispatchStatusTest = GetDispatchStatus(vm); ASSERT_TRUE(GetDispatchStatusTest == 0); } + +HWTEST_F_L0(DebuggerServiceTest, SaveAllBreakpointsTest) +{ + const char *message = "{\"id\":0,\"method\":\"Debugger.saveAllPossibleBreakpoints\"," + "\"params\":{\"locations\":{\"entry|entry|1.0.0|src/main/ets/pages/Index.ts\":" + "[{\"lineNumber\":59,\"columnNumber\":16}]}}}"; + const char *str0 = SaveAllBreakpoints(nullptr, message); + ASSERT_TRUE(str0 != nullptr && *str0 == '\0'); + + const char *str1 = SaveAllBreakpoints(ecmaVm, message); + ASSERT_TRUE(str1 != nullptr && *str1 == '\0'); + + InitializeDebugger(ecmaVm, nullptr); + const char *str2 = SaveAllBreakpoints(ecmaVm, message); + ASSERT_TRUE(str2 != nullptr && *str2 != '\0'); + UninitializeDebugger(ecmaVm); +} + +HWTEST_F_L0(DebuggerServiceTest, RemoveBreakpointTest) +{ + const char *message = "{\"id\":0,\"method\":\"Debugger.removeBreakpointsByUrl\"," + "\"params\":{\"url\":\"entry|entry|1.0.0|src/main/ets/pages/Index.ts\"}}"; + const char *str0 = RemoveBreakpoint(nullptr, message); + ASSERT_TRUE(str0 != nullptr && *str0 == '\0'); + + const char *str1 = RemoveBreakpoint(ecmaVm, message); + ASSERT_TRUE(str1 != nullptr && *str1 == '\0'); + + InitializeDebugger(ecmaVm, nullptr); + const char *str2 = RemoveBreakpoint(ecmaVm, message); + ASSERT_TRUE(str2 != nullptr && *str2 != '\0'); + UninitializeDebugger(ecmaVm); +} + +HWTEST_F_L0(DebuggerServiceTest, SetBreakpointTest) +{ + const char *message = "{\"id\":0,\"method\":\"Debugger.getPossibleAndSetBreakpointByUrl\"," + "\"params\":{\"locations\":[{\"url\":\"entry|entry|1.0.0|src/main/ets/pages/Index.ts\"," + "\"lineNumber\":59,\"columnNumber\":16}]}}"; + const char *str0 = SetBreakpoint(nullptr, message); + ASSERT_TRUE(str0 != nullptr && *str0 == '\0'); + + const char *str1 = SetBreakpoint(ecmaVm, message); + ASSERT_TRUE(str1 != nullptr && *str1 == '\0'); + + InitializeDebugger(ecmaVm, nullptr); + const char *str2 = SetBreakpoint(ecmaVm, message); + ASSERT_TRUE(str2 != nullptr && *str2 != '\0'); + UninitializeDebugger(ecmaVm); +} } // namespace panda::test \ No newline at end of file diff --git a/tooling/test/dispatcher_test.cpp b/tooling/test/dispatcher_test.cpp index 9624b450..6b962c6a 100644 --- a/tooling/test/dispatcher_test.cpp +++ b/tooling/test/dispatcher_test.cpp @@ -148,4 +148,90 @@ HWTEST_F_L0(DispatcherTest, DispatcherDispatchTest) dispatcher->Dispatch(dispatchRequest2); ASSERT_TRUE(result == ""); } + +HWTEST_F_L0(DispatcherTest, SaveAllBreakpointsTest) +{ + ProtocolChannel *channel = new ProtocolHandler(nullptr, ecmaVm); + auto dispatcher = std::make_unique(ecmaVm, channel); + + std::string result = ""; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.saveAllPossibleBreakpoints", + "params": { + "locations": { + "entry|entry|1.0.0|src/main/ets/pages/Index.ts": [{ + "lineNumber": 59, + "columnNumber": 16 + }] + } + } + })"; + result = dispatcher->SaveAllBreakpoints(msg.c_str()); + EXPECT_STREQ(result.c_str(), R"({"id":0,"result":{}})"); + if (channel) { + delete channel; + channel = nullptr; + } +} + +HWTEST_F_L0(DispatcherTest, RemoveBreakpointTest) +{ + ProtocolChannel *channel = new ProtocolHandler(nullptr, ecmaVm); + auto dispatcher = std::make_unique(ecmaVm, channel); + + std::string result = ""; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.removeBreakpointsByUrl", + "params": { + "url": "entry|entry|1.0.0|src/main/ets/pages/Index.ts" + } + })"; + result = dispatcher->RemoveBreakpoint(msg.c_str()); + EXPECT_STREQ(result.c_str(), R"({"id":0,"result":{}})"); + if (channel) { + delete channel; + channel = nullptr; + } +} + +HWTEST_F_L0(DispatcherTest, SetBreakpointTest) +{ + ProtocolChannel *channel = new ProtocolHandler(nullptr, ecmaVm); + auto dispatcher = std::make_unique(ecmaVm, channel); + + std::string result = ""; + std::string msg = std::string() + + R"({ + "id": 0, + "method": "Debugger.getPossibleAndSetBreakpointByUrl", + "params": { + "locations": [{ + "url": "entry|entry|1.0.0|src/main/ets/pages/Index.ts", + "lineNumber": 59, + "columnNumber": 16 + }] + } + })"; + result = dispatcher->SetBreakpoint(msg.c_str()); + EXPECT_STREQ(result.c_str(), + R"({ + "id": 0, + "result": { + "locations": [{ + "lineNumber": 59, + "columnNumber": 0, + "id": "id:59:0:entry|entry|1.0.0|src/main/ets/pages/Index.ts", + "scriptId": 1 + }] + } + })"); + if (channel) { + delete channel; + channel = nullptr; + } +} } // namespace panda::test \ No newline at end of file -- Gitee