diff --git a/bundle.json b/bundle.json index 37658a35033c4dffb419492821cb74b23b76e65e..1373083473503be67b5a607b090bb9ab895fd61e 100644 --- a/bundle.json +++ b/bundle.json @@ -11,7 +11,7 @@ "destPath": "arkcompiler/toolchain" }, "component": { - "name": "arkcompiler_toolchain", + "name": "toolchain", "subsystem": "ark", "syscap": [], "features": [], @@ -25,7 +25,9 @@ "third_party": [] }, "build": { - "sub_component": [], + "sub_component": [ + "//arkcompiler/toolchain/inspector:ark_debugger" + ], "inner_kits": [], "test": [] } diff --git a/inspector/BUILD.gn b/inspector/BUILD.gn index e07c092aed02cd6a42d2d603590fcab403514bf5..911b8942bcd29971bd0f377fdbbfd9e833f9b34a 100644 --- a/inspector/BUILD.gn +++ b/inspector/BUILD.gn @@ -34,23 +34,44 @@ ohos_shared_library("ark_debugger") { defines += [ "ACE_LOG_TAG=\"ArkDebugger\"" ] - external_deps = hilog_deps + if (is_mingw || is_mac) { + cflags = [ "-std=c++17" ] + if (is_mingw) { + platform = "windows" + defines += [ "WINDOWS_PLATFORM" ] + ldflags = [ + "-lwsock32", + "-lws2_32", + ] + } else { + platform = "mac" + defines += [ + "MAC_PLATFORM", + "UNIX_PLATFORM", + ] + } + deps = [ + "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog_$platform", + ] + } else { + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + defines += [ "UNIX_PLATFORM" ] + } include_dirs = [ - "$toolchain_root", - "$ace_root/frameworks", + ".", "//third_party/boost", "//third_party/boost/boost", ] sources = [ - "$ace_root/adapter/ohos/osal/log_wrapper.cpp", "inspector.cpp", + "library_loader.cpp", "ws_server.cpp", ] configs = [ ":ark_debugger_config" ] - subsystem_name = "arkcompiler" + subsystem_name = "ark" part_name = "toolchain" } diff --git a/inspector/hilog_wrapper.h b/inspector/hilog_wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..910784bff3878bf0d0289282fce092e0d2715643 --- /dev/null +++ b/inspector/hilog_wrapper.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 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 ARKCOMPILER_TOOLCHAIN_INSPECTOR_HILOG_WRAPPER_H +#define ARKCOMPILER_TOOLCHAIN_INSPECTOR_HILOG_WRAPPER_H + +#include "hilog/log.h" + +namespace OHOS::ArkCompiler::Toolchain { +#ifdef LOGF +#undef LOGF +#endif +#ifdef LOGE +#undef LOGE +#endif +#ifdef LOGW +#undef LOGW +#endif +#ifdef LOGI +#undef LOGI +#endif +#ifdef LOGD +#undef LOGD +#endif + +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, + 0xD003F00, + "ArkCompiler" +}; + +#define LOGF(fmt, ...) OHOS::HiviewDFX::HiLog::Fatal(LABEL, fmt, ##__VA_ARGS__) +#define LOGE(fmt, ...) OHOS::HiviewDFX::HiLog::Error(LABEL, fmt, ##__VA_ARGS__) +#define LOGW(fmt, ...) OHOS::HiviewDFX::HiLog::Warn(LABEL, fmt, ##__VA_ARGS__) +#define LOGI(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, fmt, ##__VA_ARGS__) +#define LOGD(fmt, ...) OHOS::HiviewDFX::HiLog::Debug(LABEL, fmt, ##__VA_ARGS__) +} // namespace OHOS::ArkCompiler::Toolchain +#endif // ARKCOMPILER_TOOLCHAIN_INSPECTOR_HILOG_WRAPPER_H diff --git a/inspector/inspector.cpp b/inspector/inspector.cpp index 28fc64396176afc51a88fba4f4854245e428c26b..45ee4023f098ff910728661fcd6b490a1a204991 100644 --- a/inspector/inspector.cpp +++ b/inspector/inspector.cpp @@ -13,15 +13,15 @@ * limitations under the License. */ -#include "inspector/inspector.h" +#include "inspector.h" -#include +#include #include -#include +#include #include -#include "base/log/log.h" -#include "inspector/ws_server.h" +#include "hilog_wrapper.h" +#include "library_loader.h" namespace OHOS::ArkCompiler::Toolchain { namespace { @@ -34,11 +34,11 @@ enum DispatchStatus : int32_t { using InitializeDebugger = void(*)(void*, const std::function&); using UninitializeDebugger = void(*)(void*); using WaitForDebugger = void(*)(void*); -using DispatchMessage = void(*)(void*, std::string&&); +using OnMessage = void(*)(void*, std::string&&); using ProcessMessage = void(*)(void*); using GetDispatchStatus = int32_t(*)(void*); -DispatchMessage g_dispatchMessage = nullptr; +OnMessage g_onMessage = nullptr; InitializeDebugger g_initializeDebugger = nullptr; UninitializeDebugger g_uninitializeDebugger = nullptr; WaitForDebugger g_waitForDebugger = nullptr; @@ -52,7 +52,13 @@ std::shared_mutex g_mutex; thread_local void* g_handle = nullptr; thread_local void* g_vm = nullptr; +#if defined(WINDOWS_PLATFORM) +constexpr char ARK_DEBUGGER_SHARED_LIB[] = "libark_ecma_debugger.dll"; +#elif defined(MAC_PLATFORM) +constexpr char ARK_DEBUGGER_SHARED_LIB[] = "libark_ecma_debugger.dylib"; +#else constexpr char ARK_DEBUGGER_SHARED_LIB[] = "libark_ecma_debugger.so"; +#endif void* HandleClient(void* const server) { @@ -71,9 +77,8 @@ bool LoadArkDebuggerLibrary() LOGE("Already opened"); return false; } - g_handle = dlopen(ARK_DEBUGGER_SHARED_LIB, RTLD_LAZY); + g_handle = Load(ARK_DEBUGGER_SHARED_LIB); if (g_handle == nullptr) { - LOGE("Failed to open %{public}s, reason: %{public}sn", ARK_DEBUGGER_SHARED_LIB, dlerror()); return false; } return true; @@ -81,11 +86,7 @@ bool LoadArkDebuggerLibrary() void* GetArkDynFunction(const char* symbol) { - auto function = dlsym(g_handle, symbol); - if (function == nullptr) { - LOGE("Failed to get symbol %{public}s in %{public}s", symbol, ARK_DEBUGGER_SHARED_LIB); - } - return function; + return ResolveSymbol(g_handle, symbol); } void SendReply(const void* vm, const std::string& message) @@ -109,7 +110,7 @@ void ResetServiceLocked() g_inspectors.erase(iter); } if (g_handle != nullptr) { - dlclose(g_handle); + CloseHandle(g_handle); g_handle = nullptr; } } @@ -175,9 +176,9 @@ bool InitializeArkFunctions() ResetServiceLocked(); return false; } - g_dispatchMessage = reinterpret_cast( - GetArkDynFunction("DispatchMessage")); - if (g_dispatchMessage == nullptr) { + g_onMessage = reinterpret_cast( + GetArkDynFunction("OnMessage")); + if (g_onMessage == nullptr) { ResetServiceLocked(); return false; } @@ -201,13 +202,13 @@ bool InitializeArkFunctions() void Inspector::OnMessage(std::string&& msg) { - g_dispatchMessage(vm_, std::move(msg)); + g_onMessage(vm_, std::move(msg)); // message will be processed soon if the debugger thread is in running or waiting status if (g_getDispatchStatus(vm_) != DispatchStatus::UNKNOWN) { return; } - usleep(DELAY_CHECK_DISPATCH_STATUS); + std::this_thread::sleep_for(std::chrono::microseconds(DELAY_CHECK_DISPATCH_STATUS)); if (g_getDispatchStatus(vm_) != DispatchStatus::UNKNOWN) { return; } @@ -229,7 +230,6 @@ void Inspector::OnMessage(std::string&& msg) bool StartDebug(const std::string& componentName, void* vm, bool isDebugMode, int32_t instanceId, const DebuggerPostTask& debuggerPostTask) { - LOGI("StartDebug: %{private}s", componentName.c_str()); g_vm = vm; if (!LoadArkDebuggerLibrary()) { return false; @@ -249,7 +249,6 @@ bool StartDebug(const std::string& componentName, void* vm, bool isDebugMode, in if (isDebugMode) { g_waitForDebugger(vm); } - LOGI("StartDebug Continue"); return true; } diff --git a/inspector/inspector.h b/inspector/inspector.h index 5bf32192c35cc544a86e431442334df67e90155b..387f48722f272231ecda2f08e72216d6a6aaf498 100644 --- a/inspector/inspector.h +++ b/inspector/inspector.h @@ -20,6 +20,8 @@ #include +#include + namespace panda::ecmascript { class EcmaVM; } // namespace panda::ecmascript @@ -28,22 +30,18 @@ namespace OHOS::ArkCompiler::Toolchain { using EcmaVM = panda::ecmascript::EcmaVM; using DebuggerPostTask = std::function&&)>; -#ifdef __cplusplus #if __cplusplus extern "C" { #endif -#endif bool StartDebug(const std::string& componentName, void* vm, bool isDebugMode, int32_t instanceId, const DebuggerPostTask& debuggerPostTask); void StopDebug(const std::string& componentName); -#ifdef __cplusplus #if __cplusplus } #endif -#endif class Inspector { public: diff --git a/inspector/library_loader.cpp b/inspector/library_loader.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4b8e0cac913efe25447a280689cacf575e370e69 --- /dev/null +++ b/inspector/library_loader.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022 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 "library_loader.h" + +#include "hilog_wrapper.h" + +#if defined(UNIX_PLATFORM) +#include +#elif defined(WINDOWS_PLATFORM) +#include +#else +#error "Unsupported platform" +#endif + +#include + +namespace OHOS::ArkCompiler::Toolchain { +#ifdef WINDOWS_PLATFORM +void* Load(std::string_view libraryName) +{ + HMODULE module = LoadLibrary(libraryName.data()); + void* handle = reinterpret_cast(module); + if (handle != nullptr) { + return handle; + } + + LOGE("Failed to open %{public}s, reason:%{public}sn", libraryName.data(), + std::to_string(GetLastError()).c_str()); + return nullptr; +} + +void* ResolveSymbol(void* handle, std::string_view symbol) +{ + HMODULE module = reinterpret_cast(handle); + void* addr = reinterpret_cast(GetProcAddress(module, symbol.data())); + if (addr != nullptr) { + return addr; + } + LOGE("Failed to get symbol:%{public}s, reason:%{public}s", symbol.data(), + std::to_string(GetLastError()).c_str()); + return nullptr; +} + +void CloseHandle(void* handle) +{ + if (handle != nullptr) { + FreeLibrary(reinterpret_cast(handle)); + } +} +#else // UNIX_PLATFORM +void* Load(std::string_view libraryName) +{ + void* handle = dlopen(libraryName.data(), RTLD_LAZY); + if (handle != nullptr) { + return handle; + } + LOGE("Failed to open %{public}s, reason:%{public}sn", libraryName.data(), dlerror()); + return nullptr; +} + +void* ResolveSymbol(void* handle, std::string_view symbol) +{ + void* addr = dlsym(handle, symbol.data()); + if (addr != nullptr) { + return addr; + } + LOGE("Failed to get symbol:%{public}s, reason:%{public}sn", symbol.data(), dlerror()); + return nullptr; +} + +void CloseHandle(void* handle) +{ + if (handle != nullptr) { + dlclose(handle); + } +} +#endif +} \ No newline at end of file diff --git a/inspector/library_loader.h b/inspector/library_loader.h new file mode 100644 index 0000000000000000000000000000000000000000..389a6e4f973165e6e91fba49ff38dcfacb65afc7 --- /dev/null +++ b/inspector/library_loader.h @@ -0,0 +1,28 @@ + +/** + * Copyright (c) 2022 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 ARKCOMPILER_TOOLCHAIN_INSPECTOR_LIBRARY_LOADER_H +#define ARKCOMPILER_TOOLCHAIN_INSPECTOR_LIBRARY_LOADER_H + +#include + +namespace OHOS::ArkCompiler::Toolchain { +void* Load(std::string_view filename); +void* ResolveSymbol(void* handle, std::string_view name); +void CloseHandle(void* handle); +} // namespace OHOS::ArkCompiler::Toolchain + +#endif // ARKCOMPILER_TOOLCHAIN_INSPECTOR_LIBRARY_LOADER_H diff --git a/inspector/ws_server.cpp b/inspector/ws_server.cpp index 200dd832d1d0f89631661d93ab01128ddf56d2e8..f1d7b1ce82672f4eb4279cde6a147b658c9a860a 100644 --- a/inspector/ws_server.cpp +++ b/inspector/ws_server.cpp @@ -13,25 +13,27 @@ * limitations under the License. */ -#include "inspector/ws_server.h" +#include "ws_server.h" #include #include #include -#include "base/log/log.h" +#include "hilog_wrapper.h" namespace OHOS::ArkCompiler::Toolchain { void WsServer::RunServer() { terminateExecution_ = false; try { - ioContext_ = std::make_unique(); - int appPid = getpid(); tid_ = pthread_self(); +#if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM) + constexpr int32_t DEFAULT_INSEPTOR_PORT = 9230; + CommProtocol::endpoint endPoint(CommProtocol::v4(), DEFAULT_INSEPTOR_PORT); +#else + int appPid = getpid(); std::string pidStr = std::to_string(appPid); std::string instanceIdStr(""); - auto& connectFlag = connectState_; /** * The old version of IDE is not compatible with the new images due to the connect server. * The First instance will use "pid" instead of "pid + instanceId" to avoid this. @@ -42,9 +44,12 @@ void WsServer::RunServer() } std::string sockName = '\0' + pidStr + instanceIdStr + componentName_; LOGI("WsServer RunServer: %{public}d%{public}d%{public}s", appPid, instanceId_, componentName_.c_str()); - localSocket::endpoint endPoint(sockName); - localSocket::socket socket(*ioContext_); - localSocket::acceptor acceptor(*ioContext_, endPoint); + CommProtocol::endpoint endPoint(sockName); +#endif + ioContext_ = std::make_unique(); + CommProtocol::socket socket(*ioContext_); + CommProtocol::acceptor acceptor(*ioContext_, endPoint); + auto& connectFlag = connectState_; acceptor.async_accept(socket, [&connectFlag](const boost::system::error_code& error) { if (!error) { connectFlag = true; @@ -54,8 +59,8 @@ void WsServer::RunServer() if (terminateExecution_ || !connectState_) { return; } - webSocket_ = std::unique_ptr>( - std::make_unique>(std::move(socket))); + webSocket_ = std::unique_ptr>( + std::make_unique>(std::move(socket))); webSocket_->accept(); while (!terminateExecution_) { beast::flat_buffer buffer; @@ -72,7 +77,7 @@ void WsServer::RunServer() } catch (const beast::system_error& se) { if (se.code() != websocket::error::closed) { webSocket_.reset(); - LOGE("Error system_error"); + LOGE("Error system_error, %{public}s", se.what()); } } catch (const std::exception& e) { LOGE("Error exception, %{public}s", e.what()); @@ -85,15 +90,19 @@ void WsServer::StopServer() terminateExecution_ = true; if (!connectState_) { ioContext_->stop(); - } else { + } else if (webSocket_ != nullptr) { boost::system::error_code error; webSocket_->close(websocket::close_code::normal, error); } - pthread_join(tid_, NULL); + pthread_join(tid_, nullptr); } void WsServer::SendReply(const std::string& message) const { + if (webSocket_ == nullptr) { + LOGE("WsServer SendReply websocket has been closed unexpectedly"); + return; + } LOGI("WsServer SendReply: %{public}s", message.c_str()); try { boost::beast::multi_buffer buffer; diff --git a/inspector/ws_server.h b/inspector/ws_server.h index 304f8883b714cf95451ef88b53c5acda79bf8901..f6bc44dac463cf124278ca4462219d31257974ce 100644 --- a/inspector/ws_server.h +++ b/inspector/ws_server.h @@ -16,19 +16,28 @@ #ifndef ARKCOMPILER_TOOLCHAIN_INSPECTOR_WS_SERVER_H #define ARKCOMPILER_TOOLCHAIN_INSPECTOR_WS_SERVER_H -#include -#include -#include - #include +#if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM) +#include +#else #include +#endif #include #include +#include +#include +#include + +#include namespace OHOS::ArkCompiler::Toolchain { namespace beast = boost::beast; namespace websocket = beast::websocket; -using localSocket = boost::asio::local::stream_protocol; +#if defined(WINDOWS_PLATFORM) || defined(MAC_PLATFORM) +using CommProtocol = boost::asio::ip::tcp; +#else +using CommProtocol = boost::asio::local::stream_protocol; +#endif class WsServer { public: @@ -43,11 +52,11 @@ public: private: std::atomic connectState_ {false}; std::atomic terminateExecution_ { false }; - int32_t instanceId_ {0}; + [[maybe_unused]] int32_t instanceId_ {0}; pthread_t tid_ {0}; std::string componentName_ {}; std::function wsOnMessage_ {}; - std::unique_ptr> webSocket_ { nullptr }; + std::unique_ptr> webSocket_ { nullptr }; std::unique_ptr ioContext_ { nullptr }; }; } // namespace OHOS::ArkCompiler::Toolchain