From 641623e506f47bc203484b36a20c663449d7ec5d Mon Sep 17 00:00:00 2001 From: wengchangcheng Date: Wed, 19 Apr 2023 15:41:24 +0800 Subject: [PATCH 1/5] Add base file for toolchain client 1. Add domain client 2. Add function manager 3. Add toolchain command line tool Issue: https://gitee.com/openharmony/arkcompiler_toolchain/issues/I6X1B1 Signed-off-by: wengchangcheng Change-Id: Ifdbad4f271b639e709f0df2c19676a6a399c8b06 --- tooling/client/BUILD.gn | 12 ++++++++++++ tooling/client/domain/debugger_client.cpp | 14 ++++++++++++++ tooling/client/domain/debugger_client.h | 14 ++++++++++++++ tooling/client/domain/heapprofiler_client.cpp | 14 ++++++++++++++ tooling/client/domain/heapprofiler_client.h | 14 ++++++++++++++ tooling/client/domain/profiler_client copy.h | 14 ++++++++++++++ tooling/client/domain/profiler_client.cpp | 14 ++++++++++++++ tooling/client/domain/profiler_client.h | 14 ++++++++++++++ tooling/client/domain/runtime_client.cpp | 14 ++++++++++++++ tooling/client/domain/runtime_client.h | 14 ++++++++++++++ tooling/client/manager/breakpoint_manager.cpp | 14 ++++++++++++++ tooling/client/manager/breakpoint_manager.h | 14 ++++++++++++++ tooling/client/manager/stack_manager.cpp | 14 ++++++++++++++ tooling/client/manager/stack_manager.h | 14 ++++++++++++++ tooling/client/manager/step_manager.cpp | 14 ++++++++++++++ tooling/client/manager/step_manager.h | 14 ++++++++++++++ tooling/client/manager/variable_manager.cpp | 14 ++++++++++++++ tooling/client/manager/variable_manager.h | 14 ++++++++++++++ tooling/client/toolchain_cli/BUILD.gn | 12 ++++++++++++ tooling/client/toolchain_cli/main.cpp | 14 ++++++++++++++ tooling/client/websocket/websocket_client.cpp | 14 ++++++++++++++ tooling/client/websocket/websocket_client.h | 14 ++++++++++++++ 22 files changed, 304 insertions(+) create mode 100644 tooling/client/BUILD.gn create mode 100644 tooling/client/domain/debugger_client.cpp create mode 100644 tooling/client/domain/debugger_client.h create mode 100644 tooling/client/domain/heapprofiler_client.cpp create mode 100644 tooling/client/domain/heapprofiler_client.h create mode 100644 tooling/client/domain/profiler_client copy.h create mode 100644 tooling/client/domain/profiler_client.cpp create mode 100644 tooling/client/domain/profiler_client.h create mode 100644 tooling/client/domain/runtime_client.cpp create mode 100644 tooling/client/domain/runtime_client.h create mode 100644 tooling/client/manager/breakpoint_manager.cpp create mode 100644 tooling/client/manager/breakpoint_manager.h create mode 100644 tooling/client/manager/stack_manager.cpp create mode 100644 tooling/client/manager/stack_manager.h create mode 100644 tooling/client/manager/step_manager.cpp create mode 100644 tooling/client/manager/step_manager.h create mode 100644 tooling/client/manager/variable_manager.cpp create mode 100644 tooling/client/manager/variable_manager.h create mode 100644 tooling/client/toolchain_cli/BUILD.gn create mode 100644 tooling/client/toolchain_cli/main.cpp create mode 100644 tooling/client/websocket/websocket_client.cpp create mode 100644 tooling/client/websocket/websocket_client.h diff --git a/tooling/client/BUILD.gn b/tooling/client/BUILD.gn new file mode 100644 index 00000000..242ddef1 --- /dev/null +++ b/tooling/client/BUILD.gn @@ -0,0 +1,12 @@ +# Copyright (c) 2021-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. diff --git a/tooling/client/domain/debugger_client.cpp b/tooling/client/domain/debugger_client.cpp new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/domain/debugger_client.cpp @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/domain/debugger_client.h b/tooling/client/domain/debugger_client.h new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/domain/debugger_client.h @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/domain/heapprofiler_client.cpp b/tooling/client/domain/heapprofiler_client.cpp new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/domain/heapprofiler_client.cpp @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/domain/heapprofiler_client.h b/tooling/client/domain/heapprofiler_client.h new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/domain/heapprofiler_client.h @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/domain/profiler_client copy.h b/tooling/client/domain/profiler_client copy.h new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/domain/profiler_client copy.h @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/domain/profiler_client.cpp b/tooling/client/domain/profiler_client.cpp new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/domain/profiler_client.cpp @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/domain/profiler_client.h b/tooling/client/domain/profiler_client.h new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/domain/profiler_client.h @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/domain/runtime_client.cpp b/tooling/client/domain/runtime_client.cpp new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/domain/runtime_client.cpp @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/domain/runtime_client.h b/tooling/client/domain/runtime_client.h new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/domain/runtime_client.h @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/manager/breakpoint_manager.cpp b/tooling/client/manager/breakpoint_manager.cpp new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/manager/breakpoint_manager.cpp @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/manager/breakpoint_manager.h b/tooling/client/manager/breakpoint_manager.h new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/manager/breakpoint_manager.h @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/manager/stack_manager.cpp b/tooling/client/manager/stack_manager.cpp new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/manager/stack_manager.cpp @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/manager/stack_manager.h b/tooling/client/manager/stack_manager.h new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/manager/stack_manager.h @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/manager/step_manager.cpp b/tooling/client/manager/step_manager.cpp new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/manager/step_manager.cpp @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/manager/step_manager.h b/tooling/client/manager/step_manager.h new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/manager/step_manager.h @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/manager/variable_manager.cpp b/tooling/client/manager/variable_manager.cpp new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/manager/variable_manager.cpp @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/manager/variable_manager.h b/tooling/client/manager/variable_manager.h new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/manager/variable_manager.h @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/toolchain_cli/BUILD.gn b/tooling/client/toolchain_cli/BUILD.gn new file mode 100644 index 00000000..242ddef1 --- /dev/null +++ b/tooling/client/toolchain_cli/BUILD.gn @@ -0,0 +1,12 @@ +# Copyright (c) 2021-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. diff --git a/tooling/client/toolchain_cli/main.cpp b/tooling/client/toolchain_cli/main.cpp new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/toolchain_cli/main.cpp @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/websocket/websocket_client.cpp b/tooling/client/websocket/websocket_client.cpp new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/websocket/websocket_client.cpp @@ -0,0 +1,14 @@ +/* + * 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. + */ diff --git a/tooling/client/websocket/websocket_client.h b/tooling/client/websocket/websocket_client.h new file mode 100644 index 00000000..9703852d --- /dev/null +++ b/tooling/client/websocket/websocket_client.h @@ -0,0 +1,14 @@ +/* + * 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. + */ -- Gitee From 120bf8814a196a6c9ae3178225d2c7ebd451df45 Mon Sep 17 00:00:00 2001 From: caolili123 Date: Fri, 30 Jun 2023 11:07:34 +0800 Subject: [PATCH 2/5] issue:https://gitee.com/openharmony/arkcompiler_toolchain/issues/I7HB8J Signed-off-by: caolili123 --- BUILD.gn | 1 + tooling/client/BUILD.gn | 57 ++- tooling/client/toolchain_cli/BUILD.gn | 49 ++- tooling/client/toolchain_cli/cli_command.cpp | 295 +++++++++++++ tooling/client/toolchain_cli/cli_command.h | 90 ++++ tooling/client/toolchain_cli/main.cpp | 96 ++++ tooling/client/websocket/websocket_client.cpp | 414 ++++++++++++++++++ tooling/client/websocket/websocket_client.h | 66 +++ 8 files changed, 1066 insertions(+), 2 deletions(-) create mode 100644 tooling/client/toolchain_cli/cli_command.cpp create mode 100644 tooling/client/toolchain_cli/cli_command.h diff --git a/BUILD.gn b/BUILD.gn index bfa153b7..10421139 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -133,6 +133,7 @@ group("ark_toolchain_packages") { "$toolchain_root/inspector:ark_debugger", "$toolchain_root/inspector:connectserver_debugger", "$toolchain_root/tooling:libark_ecma_debugger", + "$toolchain_root/tooling/client/toolchain_cli:toolchain_cli" ] } } diff --git a/tooling/client/BUILD.gn b/tooling/client/BUILD.gn index 242ddef1..0a396b3f 100644 --- a/tooling/client/BUILD.gn +++ b/tooling/client/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2022 Huawei Device Co., Ltd. +# 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 @@ -10,3 +10,58 @@ # 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. + +import("//arkcompiler/toolchain/toolchain.gni") + +config("hiviewdfx_config") { + defines = [] + if (enable_dump_in_faultlog) { + defines += [ "ENABLE_DUMP_IN_FAULTLOG" ] + } + if (enable_bytrace) { + defines += [ "ENABLE_BYTRACE" ] + cflags_cc = [ "-Wno-gnu-zero-variadic-macro-arguments" ] + } + if (enable_hitrace) { + defines += [ "ENABLE_HITRACE" ] + } + if (enable_hilog) { + defines += [ "ENABLE_HILOG" ] + } + + include_dirs = [ "$hilog_root/include" ] +} + +ohos_source_set("websocket_client") { + stack_protector_ret = false + defines = [] + deps = [] + configs = [] + + # hiviewdfx libraries + external_deps = hiviewdfx_ext_deps + deps += hiviewdfx_deps + + include_dirs = [ + "$toolchain_root", + "$toolchain_root/inspector", + "$toolchain_root/websocket", + "$toolchain_root/tooling/client", + ] + + sources = [ "websocket/websocket_client.cpp" ] + + deps += [ + "$toolchain_root/websocket:websocket", + "$ark_third_party_root/openssl:libcrypto_shared", + sdk_libc_secshared_dep, + ] + + configs += [ + ":hiviewdfx_config", + ] + + subsystem_name = "arkcompiler" + part_name = "toolchain" +} + diff --git a/tooling/client/toolchain_cli/BUILD.gn b/tooling/client/toolchain_cli/BUILD.gn index 242ddef1..015a9095 100644 --- a/tooling/client/toolchain_cli/BUILD.gn +++ b/tooling/client/toolchain_cli/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2021-2022 Huawei Device Co., Ltd. +# 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 @@ -10,3 +10,50 @@ # 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. + +import("//arkcompiler/toolchain/toolchain.gni") + +config("hiviewdfx_config") { + defines = [] + if (enable_dump_in_faultlog) { + defines += [ "ENABLE_DUMP_IN_FAULTLOG" ] + } + if (enable_bytrace) { + defines += [ "ENABLE_BYTRACE" ] + cflags_cc = [ "-Wno-gnu-zero-variadic-macro-arguments" ] + } + if (enable_hitrace) { + defines += [ "ENABLE_HITRACE" ] + } + if (enable_hilog) { + defines += [ "ENABLE_HILOG" ] + } + + include_dirs = [ "$hilog_root/include" ] +} + +ohos_executable("toolchain_cli") { + sources = [ + "main.cpp", + "cli_command.cpp", + ] + + include_dirs = [ + "$toolchain_root", + "$toolchain_root/tooling", + "$toolchain_root/inspector", + "$toolchain_root/websocket", + "$toolchain_root/tooling/client/toolchain_cli", + ] + + deps = [ + "$toolchain_root/tooling/client:websocket_client", + ] + + configs = [ ":hiviewdfx_config" ] + + install_enable = false + + part_name = "toolchain" + subsystem_name = "arkcompiler" +} diff --git a/tooling/client/toolchain_cli/cli_command.cpp b/tooling/client/toolchain_cli/cli_command.cpp new file mode 100644 index 00000000..b00b45b7 --- /dev/null +++ b/tooling/client/toolchain_cli/cli_command.cpp @@ -0,0 +1,295 @@ +/* + * 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 +#include +#include +#include +#include "cli_command.h" +#include "log_wrapper.h" + +namespace OHOS::ArkCompiler::Toolchain{ +const std::string HELP_MSG = "usage: \n" + " These are common commands list:\n" + " allocationtrack(at) allocation-track-start with options\n" + " break(b) break with options\n" + " backtrack(bt) backtrace\n" + " continue(c) continue\n" + " cpuprofile(cp) cpu-profile-start with options\n" + " delete(d) delete with options\n" + " disable disable\n" + " display display\n" + " enable enable\n" + " finish(fin) finish\n" + " frame(f) frame\n" + " heapdump(hd) heapdump with options\n" + " help(h) list available commands\n" + " ignore(ig) ignore\n" + " infobreakpoints(infob) info-breakpoints\n" + " infosource(infos) info-source\n" + " jump(j) jump\n" + " list(l) list\n" + " next(n) next\n" + " print(p) print with options\n" + " ptype ptype\n" + " quit(q) quit\n" + " run(r) run\n" + " setvar(sv) set value with options\n" + " step(s) step\n" + " undisplay undisplay\n" + " watch watch\n"; + +const std::vector cmdList = { + "allocationtrack", + "break", + "backtrack", + "continue", + "cpuprofile", + "delete", + "disable", + "display", + "enable", + "finish", + "frame", + "heapdump", + "help", + "ignore", + "infobreakpoints", + "infosource", + "jump", + "list", + "next", + "print", + "ptype", + "run", + "setvar", + "step", + "undisplay", + "watch" +}; +std::string CliCommand::ExecCommand() +{ + + int result = CreateCommandMap(); + if (result != ERR_OK) { + LOGE("failed to create command map."); + } + + result = OnCommand(); + if (result != ERR_OK) { + LOGE("failed to execute your command."); + resultReceiver_ = "error: failed to execute your command.\n"; + } + return resultReceiver_; +} + +ErrCode CliCommand::CreateCommandMap() +{ + commandMap_ = { + {std::make_pair("allocationtrack","at"), std::bind(&CliCommand::ExecAllocationTrackCommand, this)}, + {std::make_pair("break","b"), std::bind(&CliCommand::ExecBreakCommand, this)}, + {std::make_pair("backtrack","bt"), std::bind(&CliCommand::ExecBackTrackCommand, this)}, + {std::make_pair("continue","c"), std::bind(&CliCommand::ExecContinueCommand, this)}, + {std::make_pair("cpuprofile","cp"), std::bind(&CliCommand::ExecCpuProfileCommand, this)}, + {std::make_pair("delete","d"), std::bind(&CliCommand::ExecDeleteCommand, this)}, + {std::make_pair("disable","disable"), std::bind(&CliCommand::ExecDisableCommand, this)}, + {std::make_pair("display","display"), std::bind(&CliCommand::ExecDisplayCommand, this)}, + {std::make_pair("enable","enable"), std::bind(&CliCommand::ExecEnableCommand, this)}, + {std::make_pair("finish","fin"), std::bind(&CliCommand::ExecFinishCommand, this)}, + {std::make_pair("frame","f"), std::bind(&CliCommand::ExecFrameCommand, this)}, + {std::make_pair("heapdump","hd"), std::bind(&CliCommand::ExecHeapDumpCommand, this)}, + {std::make_pair("help","h"), std::bind(&CliCommand::ExecHelpCommand, this)}, + {std::make_pair("ignore","ig"), std::bind(&CliCommand::ExecIgnoreCommand, this)}, + {std::make_pair("infobreakpoints","infob"), std::bind(&CliCommand::ExecInfoBCommand, this)}, + {std::make_pair("infosource","infos"), std::bind(&CliCommand::ExecInfoSCommand, this)}, + {std::make_pair("jump","j"), std::bind(&CliCommand::ExecJumpCommand, this)}, + {std::make_pair("list","l"), std::bind(&CliCommand::ExecListCommand, this)}, + {std::make_pair("next","n"), std::bind(&CliCommand::ExecNextCommand, this)}, + {std::make_pair("print","p"), std::bind(&CliCommand::ExecPrintCommand, this)}, + {std::make_pair("ptype","ptype"), std::bind(&CliCommand::ExecPtypeCommand, this)}, + {std::make_pair("run","r"), std::bind(&CliCommand::ExecRunCommand, this)}, + {std::make_pair("setvar","sv"), std::bind(&CliCommand::ExecSetValueCommand, this)}, + {std::make_pair("step","s"), std::bind(&CliCommand::ExecStepCommand, this)}, + {std::make_pair("undisplay","undisplay"), std::bind(&CliCommand::ExecUndisplayCommand, this)}, + {std::make_pair("watch","wa"), std::bind(&CliCommand::ExecWatchCommand, this)}, + }; + + return ERR_OK; +} + +ErrCode CliCommand::ExecAllocationTrackCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecBreakCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecBackTrackCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecContinueCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecCpuProfileCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecDeleteCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecDisableCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecDisplayCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecEnableCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecFinishCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecFrameCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecHeapDumpCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecHelpCommand() +{ + std::cout << HELP_MSG; + return ERR_OK; +} + +ErrCode CliCommand::ExecIgnoreCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecInfoBCommand() +{ + return ERR_OK; +} +ErrCode CliCommand::ExecInfoSCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecJumpCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecListCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecNextCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecPrintCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecPtypeCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecRunCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecSetValueCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecStepCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecUndisplayCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::ExecWatchCommand() +{ + return ERR_OK; +} + +ErrCode CliCommand::OnCommand() +{ + std::map>::iterator it; + StrPair cmdPair; + bool haveCmdFlag = false; + + for (it = commandMap_.begin(); it != commandMap_.end(); it++) { + cmdPair = it->first; + if (!strcmp(cmdPair.first.c_str(), cmd_.c_str()) + ||!strcmp(cmdPair.second.c_str(), cmd_.c_str())) { + auto respond = it->second; + respond(); + std::cout << "exe success, cmd is " << cmd_ << std::endl; + return ERR_OK; + } + } + + for(unsigned int i = 0; i < cmdList.size(); i++) { + if (!strncmp(cmdList[i].c_str(), cmd_.c_str(), std::strlen(cmd_.c_str()))) { + haveCmdFlag = true; + std::cout << cmdList[i] << " "; + } + } + + if (haveCmdFlag) { + std::cout << std::endl; + } else { + ExecHelpCommand(); + } + + return ERR_OK; +} + +} // namespace OHOS::ArkCompiler::Toolchain diff --git a/tooling/client/toolchain_cli/cli_command.h b/tooling/client/toolchain_cli/cli_command.h new file mode 100644 index 00000000..a3896038 --- /dev/null +++ b/tooling/client/toolchain_cli/cli_command.h @@ -0,0 +1,90 @@ +/* + * 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_TOOLCHAIN_CLI_COMMAND_H +#define ECMASCRIPT_TOOLING_CLIENT_TOOLCHAIN_CLI_COMMAND_H + +#include +#include +#include +#include +#include "../websocket/websocket_client.h" +#include "log_wrapper.h" + +namespace OHOS::ArkCompiler::Toolchain{ +using ErrCode = int; +using StrPair = std::pair; +using VecStr = std::vector; +enum { + ERR_OK = 0, + ERR_FAIL = 1 +}; + +class CliCommand { +public: + CliCommand(ToolchainWebsocket* cliSocket, std::vector cliCmdStr) + { + cliSocket_ = std::move(cliSocket); + cmd_ = cliCmdStr[0]; + for (unsigned int i = 1; i < cliCmdStr.size(); i++) { + argList_.push_back(cliCmdStr[i]); + } + } + + ~CliCommand() + { + } + + ErrCode OnCommand(); + std::string ExecCommand(); + std::string GetCommand(const std::string &str); + ErrCode CreateCommandMap(); + ErrCode ExecAllocationTrackCommand(); + ErrCode ExecBreakCommand(); + ErrCode ExecBackTrackCommand(); + ErrCode ExecContinueCommand(); + ErrCode ExecCpuProfileCommand(); + ErrCode ExecDeleteCommand(); + ErrCode ExecDisableCommand(); + ErrCode ExecDisplayCommand(); + ErrCode ExecEnableCommand(); + ErrCode ExecFinishCommand(); + ErrCode ExecFrameCommand(); + ErrCode ExecHeapDumpCommand(); + ErrCode ExecHelpCommand(); + ErrCode ExecIgnoreCommand(); + ErrCode ExecInfoBCommand(); + ErrCode ExecInfoSCommand(); + ErrCode ExecJumpCommand(); + ErrCode ExecListCommand(); + ErrCode ExecNextCommand(); + ErrCode ExecPrintCommand(); + ErrCode ExecPtypeCommand(); + ErrCode ExecRunCommand(); + ErrCode ExecSetValueCommand(); + ErrCode ExecStepCommand(); + ErrCode ExecUndisplayCommand(); + ErrCode ExecWatchCommand(); + +private: + std::string cmd_; + VecStr argList_; + std::map> commandMap_; + std::string resultReceiver_ = ""; + ToolchainWebsocket* cliSocket_ {nullptr}; +}; +} // namespace OHOS::ArkCompiler::Toolchain + +#endif //ECMASCRIPT_TOOLING_CLIENT_TOOLCHAIN_CLI_COMMAND_H \ No newline at end of file diff --git a/tooling/client/toolchain_cli/main.cpp b/tooling/client/toolchain_cli/main.cpp index 9703852d..af7eba39 100644 --- a/tooling/client/toolchain_cli/main.cpp +++ b/tooling/client/toolchain_cli/main.cpp @@ -12,3 +12,99 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include +#include +#include + +#include "cli_command.h" + +namespace OHOS::ArkCompiler::Toolchain{ +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; +} + +std::vector SplitString(const std::string &str, const std::string &delimiter) +{ + std::size_t strIndex = 0; + std::vector value; + std::size_t pos = str.find_first_of(delimiter, strIndex); + while ((pos < str.size()) && (pos > strIndex)) { + std::string subStr = str.substr(strIndex, pos - strIndex); + value.push_back(std::move(subStr)); + strIndex = pos; + strIndex = str.find_first_not_of(delimiter, strIndex); + pos = str.find_first_of(delimiter, strIndex); + } + if (pos > strIndex) { + std::string subStr = str.substr(strIndex, pos - strIndex); + if (!subStr.empty()) { + value.push_back(std::move(subStr)); + } + } + return value; +} + +int Main(const int argc, const char** argv) +{ + uint32_t port = 0; + OHOS::ArkCompiler::Toolchain::ToolchainWebsocket cliSocket; + if(argc < 2) { + LOGE("toolchain_cli is missing a parameter"); + return -1; + } + if(strstr(argv[0], "toolchain_cli") != nullptr) { + if(StrToUInt(argv[1], &port)) { + if((port <= 0) || (port >= 65535)) { + LOGE("toolchain_cli:InitToolchainWebSocketForPort the port = %{public}d is wrong.", port); + return -1; + } + if(!cliSocket.InitToolchainWebSocketForPort(port, 5)) { + LOGE("toolchain_cli:InitToolchainWebSocketForPort failed"); + return -1; + } + } else { + if(!cliSocket.InitToolchainWebSocketForSockName(argv[1])) { + LOGE("toolchain_cli:InitToolchainWebSocketForSockName failed"); + return -1; + } + } + + if (!cliSocket.ClientSendWSUpgradeReq()) { + LOGE("toolchain_cli:ClientSendWSUpgradeReq failed"); + return -1; + } + if (!cliSocket.ClientRecvWSUpgradeRsp()) { + LOGE("toolchain_cli:ClientRecvWSUpgradeRsp failed"); + return -1; + } + + std::cout << ">>> "; + std::string inputStr; + while(getline(std::cin, inputStr)) { + if((!strcmp(inputStr.c_str(), "quit"))||(!strcmp(inputStr.c_str(), "q"))) { + LOGE("toolchain_cli: quit"); + cliSocket.Close(); + break; + } + std::vector cliCmdStr = SplitString(inputStr, " "); + OHOS::ArkCompiler::Toolchain::CliCommand cmd(&cliSocket, cliCmdStr); + std::cout << cmd.ExecCommand(); + std::cout << ">>> "; + } + } + return 0; +} +} //OHOS::ArkCompiler::Toolchain + +int main(int argc, const char **argv) +{ + return OHOS::ArkCompiler::Toolchain::Main(argc, argv); +} diff --git a/tooling/client/websocket/websocket_client.cpp b/tooling/client/websocket/websocket_client.cpp index 9703852d..cfc3c564 100644 --- a/tooling/client/websocket/websocket_client.cpp +++ b/tooling/client/websocket/websocket_client.cpp @@ -12,3 +12,417 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include +#include +#include +#include +#include +#include + +#include "log_wrapper.h" +#include "websocket_client.h" + + +namespace OHOS::ArkCompiler::Toolchain { +bool ToolchainWebsocket::InitToolchainWebSocketForPort (int port, uint32_t timeoutLimit) +{ + if (socketState_ != ToolchainSocketState::UNINITED) { + LOGE("InitToolchainWebSocketForPort::client has inited."); + return true; + } + + client_ = socket(AF_INET, SOCK_STREAM, 0); + if (client_ < SOCKET_SUCCESS) { + LOGE("InitToolchainWebSocketForPort::client socket failed, error = %{public}d , desc = %{public}s", + errno, strerror(errno)); + return false; + } + + // set send and recv timeout limit + if (!SetWebSocketTimeOut(client_, timeoutLimit)) { + LOGE("InitToolchainWebSocketForPort::client SetWebSocketTimeOut failed, error = %{public}d , desc = %{public}s", + errno, strerror(errno)); + close(client_); + client_ = -1; + return false; + } + + sockaddr_in clientAddr; + if (memset_s(&clientAddr, sizeof(clientAddr), 0, sizeof(clientAddr)) != EOK) { + LOGE("InitToolchainWebSocketForPort::client memset_s clientAddr failed, error = %{public}d, desc = %{public}s", + errno, strerror(errno)); + close(client_); + client_ = -1; + return false; + } + clientAddr.sin_family = AF_INET; + clientAddr.sin_port = htons(port); + if (int ret = inet_pton(AF_INET, "127.0.0.1", &clientAddr.sin_addr) < NET_SUCCESS) { + LOGE("InitToolchainWebSocketForPort::client inet_pton failed, error = %{public}d, desc = %{public}s", + errno, strerror(errno)); + close(client_); + client_ = -1; + return false; + } + + int ret = connect(client_, reinterpret_cast(&clientAddr), sizeof(clientAddr)); + if (ret != SOCKET_SUCCESS) { + LOGE("InitToolchainWebSocketForPort::client connect failed, error = %{public}d, desc = %{public}s", + errno, strerror(errno)); + close(client_); + client_ = -1; + return false; + } + socketState_ = ToolchainSocketState::INITED; + LOGE("InitToolchainWebSocketForPort::client connect success."); + return true; +} + +bool ToolchainWebsocket::InitToolchainWebSocketForSockName(const std::string &sockName, uint32_t timeoutLimit) +{ + if (socketState_ != ToolchainSocketState::UNINITED) { + LOGE("InitToolchainWebSocketForSockName::client has inited."); + return true; + } + + client_ = socket(AF_UNIX, SOCK_STREAM, 0); + if (client_ < SOCKET_SUCCESS) { + LOGE("InitToolchainWebSocketForSockName::client socket failed, error = %{public}d , desc = %{public}s", + errno, strerror(errno)); + return false; + } + + // set send and recv timeout limit + if (!SetWebSocketTimeOut(client_, timeoutLimit)) { + LOGE("InitToolchainWebSocketForSockName::client SetWebSocketTimeOut failed, error = %{public}d ,\ + desc = %{public}s", errno, strerror(errno)); + close(client_); + client_ = -1; + return false; + } + + struct sockaddr_un serverAddr; + if (memset_s(&serverAddr, sizeof(serverAddr), 0, sizeof(serverAddr)) != EOK) { + LOGE("InitToolchainWebSocketForSockName::client memset_s clientAddr failed, error = %{public}d,\ + desc = %{public}s", errno, strerror(errno)); + close(client_); + client_ = -1; + return false; + } + serverAddr.sun_family = AF_UNIX; + if (strcpy_s(serverAddr.sun_path + 1, sizeof(serverAddr.sun_path) - 1, sockName.c_str()) != EOK) { + LOGE("InitToolchainWebSocketForSockName::client strcpy_s serverAddr.sun_path failed, error = %{public}d,\ + desc = %{public}s", errno, strerror(errno)); + close(client_); + client_ = -1; + return false; + } + serverAddr.sun_path[0] = '\0'; + + uint32_t len = offsetof(struct sockaddr_un, sun_path) + strlen(sockName.c_str()) + 1; + int ret = connect(client_, reinterpret_cast(&serverAddr), static_cast(len)); + if (ret != SOCKET_SUCCESS) { + LOGE("InitToolchainWebSocketForSockName::client connect failed, error = %{public}d, desc = %{public}s", + errno, strerror(errno)); + close(client_); + client_ = -1; + return false; + } + socketState_ = ToolchainSocketState::INITED; + LOGE("InitToolchainWebSocketForSockName::client connect success."); + return true; +} + +bool ToolchainWebsocket::ClientSendWSUpgradeReq() +{ + if (socketState_ == ToolchainSocketState::UNINITED) { + LOGE("ClientSendWSUpgradeReq::client has not inited."); + return false; + } + if (socketState_ == ToolchainSocketState::CONNECTED) { + LOGE("ClientSendWSUpgradeReq::client has connected."); + return true; + } + + int msgLen = strlen(CLIENT_WEBSOCKET_UPGRADE_REQ); + int32_t sendLen = send(client_, CLIENT_WEBSOCKET_UPGRADE_REQ, msgLen, 0); + if (sendLen != msgLen) { + LOGE("ClientSendWSUpgradeReq::client send wsupgrade req failed, error = %{public}d, desc = %{public}sn", + errno, strerror(errno)); + socketState_ = ToolchainSocketState::UNINITED; + close(client_); + client_ = -1; + return false; + } + LOGE("ClientSendWSUpgradeReq::client send wsupgrade req success."); + return true; +} + +bool ToolchainWebsocket::ClientRecvWSUpgradeRsp() +{ + if (socketState_ == ToolchainSocketState::UNINITED) { + LOGE("ClientRecvWSUpgradeRsp::client has not inited."); + return false; + } + if (socketState_ == ToolchainSocketState::CONNECTED) { + LOGE("ClientRecvWSUpgradeRsp::client has connected."); + return true; + } + + char recvBuf[CLIENT_WEBSOCKET_UPGRADE_RSP_LEN + 1] = {0}; + int32_t bufLen = recv(client_, recvBuf, CLIENT_WEBSOCKET_UPGRADE_RSP_LEN, 0); + if (bufLen != CLIENT_WEBSOCKET_UPGRADE_RSP_LEN) { + LOGE("ClientRecvWSUpgradeRsp::client recv wsupgrade rsp failed, error = %{public}d, desc = %{public}sn", + errno, strerror(errno)); + socketState_ = ToolchainSocketState::UNINITED; + close(client_); + client_ = -1; + return false; + } + socketState_ = ToolchainSocketState::CONNECTED; + LOGE("ClientRecvWSUpgradeRsp::client recv wsupgrade rsp success."); + return true; +} + +bool ToolchainWebsocket::ClientSendReq(const std::string &message) +{ + if (socketState_ != ToolchainSocketState::CONNECTED) { + LOGE("ClientSendReq::client has not connected."); + return false; + } + + uint32_t msgLen = message.length(); + std::unique_ptr msgBuf = std::make_unique(msgLen + 15); // 15: the maximum expand length + char *sendBuf = msgBuf.get(); + uint32_t sendMsgLen = 0; + sendBuf[0] = 0x81; // 0x81: the text message sent by the server should start with '0x81'. + uint32_t mask = 1; + // Depending on the length of the messages, client will use shift operation to get the res + // and store them in the buffer. + if (msgLen <= 125) { // 125: situation 1 when message's length <= 125 + sendBuf[1] = msgLen | (mask << 7); // 7: mask need shift left by 7 bits + sendMsgLen = 2; // 2: the length of header frame is 2; + } else if (msgLen < 65536) { // 65536: message's length + sendBuf[1] = 126 | (mask << 7); // 126: payloadLen according to the spec; 7: mask shift left by 7 bits + sendBuf[2] = ((msgLen >> 8) & 0xff); // 8: shift right by 8 bits => res * (256^1) + sendBuf[3] = (msgLen & 0xff); // 3: store len's data => res * (256^0) + sendMsgLen = 4; // 4: the length of header frame is 4 + } else { + sendBuf[1] = 127 | (mask << 7); // 127: payloadLen according to the spec; 7: mask shift left by 7 bits + for (int32_t i = 2; i <= 5; i++) { // 2 ~ 5: unused bits + sendBuf[i] = 0; + } + sendBuf[6] = ((msgLen & 0xff000000) >> 24); // 6: shift 24 bits => res * (256^3) + sendBuf[7] = ((msgLen & 0x00ff0000) >> 16); // 7: shift 16 bits => res * (256^2) + sendBuf[8] = ((msgLen & 0x0000ff00) >> 8); // 8: shift 8 bits => res * (256^1) + sendBuf[9] = (msgLen & 0x000000ff); // 9: res * (256^0) + sendMsgLen = 10; // 10: the length of header frame is 10 + } + + if (memcpy_s(sendBuf + sendMsgLen, SOCKET_MASK_LEN, MASK_KEY, SOCKET_MASK_LEN) != EOK) { + LOGE("ClientSendReq::client memcpy_s MASK_KEY failed, error = %{public}d, desc = %{public}s", + errno, strerror(errno)); + return false; + } + sendMsgLen += SOCKET_MASK_LEN; + + std::string maskMessage; + for (uint64_t i = 0; i < msgLen; i++) { + uint64_t j = i % SOCKET_MASK_LEN; + maskMessage.push_back(message[i] ^ MASK_KEY[j]); + } + if (memcpy_s(sendBuf + sendMsgLen, msgLen, maskMessage.c_str(), msgLen) != EOK) { + LOGE("ClientSendReq::client memcpy_s maskMessage failed, error = %{public}d, desc = %{public}s", + errno, strerror(errno)); + return false; + } + msgBuf[sendMsgLen + msgLen] = '\0'; + + if (send(client_, sendBuf, sendMsgLen + msgLen, 0) != static_cast(sendMsgLen + msgLen)) { + LOGE("ClientSendReq::client send msg req failed, error = %{public}d, desc = %{public}s", + errno, strerror(errno)); + return false; + } + LOGE("ClientRecvWSUpgradeRsp::client send msg req success."); + return true; +} + +std::string ToolchainWebsocket::Decode() +{ + if (socketState_ != ToolchainSocketState::CONNECTED) { + LOGE("ToolchainWebsocket:Decode failed, websocket not connected!"); + return ""; + } + char recvbuf[SOCKET_HEADER_LEN + 1]; + if (!Recv(client_, recvbuf, SOCKET_HEADER_LEN, 0)) { + LOGE("ToolchainWebsocket:Decode failed, client websocket disconnect"); + socketState_ = ToolchainSocketState::INITED; + close(client_); + client_ = -1; + return ""; + } + ToolchainWebSocketFrame wsFrame; + int32_t index = 0; + wsFrame.fin = static_cast(recvbuf[index] >> 7); // 7: shift right by 7 bits to get the fin + wsFrame.opcode = static_cast(recvbuf[index] & 0xf); + if (wsFrame.opcode == 0x1) { // 0x1: 0x1 means a text frame + index++; + wsFrame.mask = static_cast((recvbuf[index] >> 7) & 0x1); // 7: to get the mask + wsFrame.payloadLen = recvbuf[index] & 0x7f; + if (HandleFrame(wsFrame)) { + return wsFrame.payload.get(); + } + return ""; + } else if (wsFrame.opcode == 0x9) { // 0x9: 0x9 means a ping frame + // send pong frame + char pongFrame[SOCKET_HEADER_LEN] = {0}; + pongFrame[0] = 0x8a; // 0x8a: 0x8a means a pong frame + pongFrame[1] = 0x0; + if (!Send(client_, pongFrame, SOCKET_HEADER_LEN, 0)) { + LOGE("ToolchainWebsocket Decode: Send pong frame failed"); + return ""; + } + } + return ""; +} + +bool ToolchainWebsocket::HandleFrame(ToolchainWebSocketFrame& wsFrame) +{ + if (wsFrame.payloadLen == 126) { // 126: the payloadLen read from frame + char recvbuf[PAYLOAD_LEN + 1] = {0}; + if (!Recv(client_, recvbuf, PAYLOAD_LEN, 0)) { + LOGE("ToolchainWebsocket HandleFrame: Recv payloadLen == 126 failed"); + return false; + } + + uint16_t msgLen = 0; + if (memcpy_s(&msgLen, sizeof(recvbuf), recvbuf, sizeof(recvbuf) - 1) != EOK) { + LOGE("ToolchainWebsocket HandleFrame: memcpy_s failed"); + return false; + } + wsFrame.payloadLen = ntohs(msgLen); + } else if (wsFrame.payloadLen > 126) { // 126: the payloadLen read from frame + char recvbuf[EXTEND_PAYLOAD_LEN + 1] = {0}; + if (!Recv(client_, recvbuf, EXTEND_PAYLOAD_LEN, 0)) { + LOGE("ToolchainWebsocket HandleFrame: Recv payloadLen > 127 failed"); + return false; + } + wsFrame.payloadLen = NetToHostLongLong(recvbuf, EXTEND_PAYLOAD_LEN); + } + return DecodeMessage(wsFrame); +} + +bool ToolchainWebsocket::DecodeMessage(ToolchainWebSocketFrame& wsFrame) +{ + if (wsFrame.payloadLen == 0 || wsFrame.payloadLen > UINT64_MAX) { + LOGE("ToolchainWebsocket:ReadMsg length error, expected greater than zero and less than UINT64_MAX"); + return false; + } + uint64_t msgLen = wsFrame.payloadLen; + wsFrame.payload = std::make_unique(msgLen + 1); + if (wsFrame.mask == 1) { + char buf[msgLen + 1]; + if (!Recv(client_, wsFrame.maskingkey, SOCKET_MASK_LEN, 0)) { + LOGE("ToolchainWebsocket DecodeMessage: Recv maskingkey failed"); + return false; + } + + if (!Recv(client_, buf, msgLen, 0)) { + LOGE("ToolchainWebsocket DecodeMessage: Recv message with mask failed"); + return false; + } + + for (uint64_t i = 0; i < msgLen; i++) { + uint64_t j = i % SOCKET_MASK_LEN; + wsFrame.payload.get()[i] = buf[i] ^ wsFrame.maskingkey[j]; + } + } else { + char buf[msgLen + 1]; + if (!Recv(client_, buf, msgLen, 0)) { + LOGE("ToolchainWebsocket DecodeMessage: Recv message without mask failed"); + return false; + } + + if (memcpy_s(wsFrame.payload.get(), msgLen, buf, msgLen) != EOK) { + LOGE("ToolchainWebsocket DecodeMessage: memcpy_s failed"); + return false; + } + } + wsFrame.payload.get()[msgLen] = '\0'; + return true; +} + +uint64_t ToolchainWebsocket::NetToHostLongLong(char* buf, uint32_t len) +{ + uint64_t result = 0; + for (uint32_t i = 0; i < len; i++) { + result |= static_cast(buf[i]); + if ((i + 1) < len) { + result <<= 8; // 8: result need shift left 8 bits in order to big endian convert to int + } + } + return result; +} + +bool ToolchainWebsocket::Send(int32_t fd, const char* buf, size_t totalLen, int32_t flags) const +{ + size_t sendLen = 0; + while (sendLen < totalLen) { + ssize_t len = send(fd, buf + sendLen, totalLen - sendLen, flags); + if (len <= 0) { + LOGE("ToolchainWebsocket Send Message in while failed, ToolchainWebsocket disconnect"); + return false; + } + sendLen += static_cast(len); + } + return true; +} + +bool ToolchainWebsocket::Recv(int32_t fd, char* buf, size_t totalLen, int32_t flags) const +{ + size_t recvLen = 0; + while (recvLen < totalLen) { + ssize_t len = recv(fd, buf + recvLen, totalLen - recvLen, flags); + if (len <= 0) { + LOGE("ToolchainWebsocket Recv payload in while failed, ToolchainWebsocket disconnect"); + return false; + } + recvLen += static_cast(len); + } + buf[totalLen] = '\0'; + return true; +} + +void ToolchainWebsocket::Close() +{ + if (socketState_ == ToolchainSocketState::UNINITED) { + return; + } + socketState_ = ToolchainSocketState::UNINITED; + close(client_); + client_ = -1; +} + +bool ToolchainWebsocket::SetWebSocketTimeOut(int32_t fd, uint32_t timeoutLimit) +{ + if (timeoutLimit > 0) { + struct timeval timeout = {timeoutLimit, 0}; + if (setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, + reinterpret_cast(&timeout), sizeof(timeout)) != SOCKET_SUCCESS) { + LOGE("ToolchainWebsocket:SetWebSocketTimeOut setsockopt SO_SNDTIMEO failed"); + return false; + } + if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, + reinterpret_cast(&timeout), sizeof(timeout)) != SOCKET_SUCCESS) { + LOGE("ToolchainWebsocket:SetWebSocketTimeOut setsockopt SO_RCVTIMEO failed"); + return false; + } + } + return true; +} + +bool ToolchainWebsocket::IsConnected() +{ + return socketState_ == ToolchainSocketState::CONNECTED; +} +} // namespace OHOS::ArkCompiler::Toolchain \ No newline at end of file diff --git a/tooling/client/websocket/websocket_client.h b/tooling/client/websocket/websocket_client.h index 9703852d..5c884009 100644 --- a/tooling/client/websocket/websocket_client.h +++ b/tooling/client/websocket/websocket_client.h @@ -12,3 +12,69 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#ifndef ECMASCRIPT_TOOLING_CLIENT_WEBSOCKET_CLIENT_H +#define ECMASCRIPT_TOOLING_CLIENT_WEBSOCKET_CLIENT_H + +#include +#include +#include + +#include "websocket.h" + +namespace OHOS::ArkCompiler::Toolchain { +struct ToolchainWebSocketFrame { + uint8_t fin = 0; + uint8_t opcode = 0; + uint8_t mask = 0; + uint64_t payloadLen = 0; + char maskingkey[5] = {0}; + std::unique_ptr payload = nullptr; +}; +class ToolchainWebsocket : public WebSocket { +public: + enum ToolchainSocketState : uint8_t { + UNINITED, + INITED, + CONNECTED, + }; + ToolchainWebsocket() = default; + ~ToolchainWebsocket() = default; + bool InitToolchainWebSocketForPort(int port, uint32_t timeoutLimit = 5); + bool InitToolchainWebSocketForSockName(const std::string &sockName, uint32_t timeoutLimit = 0); + bool ClientSendWSUpgradeReq(); + bool ClientRecvWSUpgradeRsp(); + bool ClientSendReq(const std::string &message); + std::string Decode(); + bool HandleFrame(ToolchainWebSocketFrame& wsFrame); + bool DecodeMessage(ToolchainWebSocketFrame& wsFrame); + uint64_t NetToHostLongLong(char* buf, uint32_t len); + bool Recv(int32_t fd, char* buf, size_t totalLen, int32_t flags) const; + bool Send(int32_t fd, const char* buf, size_t totalLen, int32_t flags) const; + void Close(); + bool SetWebSocketTimeOut(int32_t fd, uint32_t timeoutLimit); + bool IsConnected(); +private: + int32_t client_ {-1}; + std::atomic socketState_ {ToolchainSocketState::UNINITED}; + static constexpr int32_t CLIENT_WEBSOCKET_UPGRADE_RSP_LEN = 129; + static constexpr char CLIENT_WEBSOCKET_UPGRADE_REQ[] = "GET / HTTP/1.1\r\n" + "Connection: Upgrade\r\n" + "Pragma: no-cache\r\n" + "Cache-Control: no-cache\r\n" + "Upgrade: websocket\r\n" + "Sec-WebSocket-Version: 13\r\n" + "Accept-Encoding: gzip, deflate, br\r\n" + "Sec-WebSocket-Key: 64b4B+s5JDlgkdg7NekJ+g==\r\n" + "Sec-WebSocket-Extensions: permessage-deflate\r\n"; + static constexpr int32_t SOCKET_SUCCESS = 0; + static constexpr int NET_SUCCESS = 1; + static constexpr int32_t SOCKET_MASK_LEN = 4; + static constexpr int32_t SOCKET_HEADER_LEN = 2; + static constexpr int32_t PAYLOAD_LEN = 2; + static constexpr int32_t EXTEND_PAYLOAD_LEN = 8; + static constexpr char MASK_KEY[SOCKET_MASK_LEN + 1] = "abcd"; +}; +} // namespace OHOS::ArkCompiler::Toolchain + +#endif \ No newline at end of file -- Gitee From a5581fdc33960bff4b4897d7b7a8072c75b5f012 Mon Sep 17 00:00:00 2001 From: caolili123 Date: Wed, 12 Jul 2023 10:58:41 +0800 Subject: [PATCH 3/5] issue:https://gitee.com/openharmony/arkcompiler_toolchain/issues/I7KIQG Signed-off-by: caolili123 --- BUILD.gn | 1 + tooling/client/BUILD.gn | 39 ++- tooling/client/domain/heapprofiler_client.cpp | 112 +++++++ tooling/client/domain/heapprofiler_client.h | 26 ++ tooling/client/domain/profiler_client copy.h | 14 - tooling/client/toolchain_cli/BUILD.gn | 7 +- tooling/client/toolchain_cli/cli_command.cpp | 305 +++++++----------- tooling/client/toolchain_cli/cli_command.h | 47 +-- tooling/client/toolchain_cli/main.cpp | 8 +- 9 files changed, 322 insertions(+), 237 deletions(-) delete mode 100644 tooling/client/domain/profiler_client copy.h diff --git a/BUILD.gn b/BUILD.gn index 10421139..89bdfb0a 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -133,6 +133,7 @@ group("ark_toolchain_packages") { "$toolchain_root/inspector:ark_debugger", "$toolchain_root/inspector:connectserver_debugger", "$toolchain_root/tooling:libark_ecma_debugger", + "$toolchain_root/tooling/client:libark_toolchain_client", "$toolchain_root/tooling/client/toolchain_cli:toolchain_cli" ] } diff --git a/tooling/client/BUILD.gn b/tooling/client/BUILD.gn index 0a396b3f..bf9360f7 100644 --- a/tooling/client/BUILD.gn +++ b/tooling/client/BUILD.gn @@ -32,11 +32,13 @@ config("hiviewdfx_config") { include_dirs = [ "$hilog_root/include" ] } -ohos_source_set("websocket_client") { +ohos_source_set("libark_toolchain_client_set") { stack_protector_ret = false defines = [] deps = [] - configs = [] + configs = [ + sdk_libc_secshared_config, + ] # hiviewdfx libraries external_deps = hiviewdfx_ext_deps @@ -46,21 +48,48 @@ ohos_source_set("websocket_client") { "$toolchain_root", "$toolchain_root/inspector", "$toolchain_root/websocket", + "$toolchain_root/tooling/base", "$toolchain_root/tooling/client", + "//third_party/cJSON", ] - sources = [ "websocket/websocket_client.cpp" ] + sources = [ + "websocket/websocket_client.cpp", + "domain/heapprofiler_client.cpp", + ] deps += [ "$toolchain_root/websocket:websocket", + "$toolchain_root/tooling:libark_ecma_debugger_set", "$ark_third_party_root/openssl:libcrypto_shared", sdk_libc_secshared_dep, ] - configs += [ - ":hiviewdfx_config", + external_deps += [ + "ets_runtime:libark_jsruntime", + "libuv:uv", + ] + + configs += [ + ":hiviewdfx_config", ] + cflags_cc = [ + "-Wno-error=vla-extension", + ] + + subsystem_name = "arkcompiler" + part_name = "toolchain" +} + +ohos_shared_library("libark_toolchain_client") { + stack_protector_ret = false + deps = [ ":libark_toolchain_client_set" ] + + if (!is_mingw && !is_mac) { + output_extension = "so" + } + subsystem_name = "arkcompiler" part_name = "toolchain" } diff --git a/tooling/client/domain/heapprofiler_client.cpp b/tooling/client/domain/heapprofiler_client.cpp index 9703852d..93448e3b 100644 --- a/tooling/client/domain/heapprofiler_client.cpp +++ b/tooling/client/domain/heapprofiler_client.cpp @@ -12,3 +12,115 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include "domain/heapprofiler_client.h" +#include "pt_json.h" +#include "log_wrapper.h" + +#include +#include +#include + +using PtJson = panda::ecmascript::tooling::PtJson; +namespace OHOS::ArkCompiler::Toolchain { +bool HeapProfilerClient::DispatcherCmd(int id, const std::string cmd, std::string* reqStr) +{ + std::map> dispatcherTable { + { "allocationtrack", std::bind(&HeapProfilerClient::AllocationTrackCommand, this, id)}, + { "allocationtrack-stop", std::bind(&HeapProfilerClient::AllocationTrackStopCommand, this, id)}, + { "heapdump", std::bind(&HeapProfilerClient::HeapDumpCommand, this, id)}, + { "heapprofiler-enable", std::bind(&HeapProfilerClient::Enable, this, id)}, + { "heapprofiler-disable", std::bind(&HeapProfilerClient::Disable, this, id)}, + { "sampling", std::bind(&HeapProfilerClient::Samping, this, id)}, + { "sampling-stop", std::bind(&HeapProfilerClient::SampingStop, this, id)}, + { "collectgarbage", std::bind(&HeapProfilerClient::CollectGarbage, this, id)} + }; + + auto entry = dispatcherTable.find(cmd); + + if (entry != dispatcherTable.end() && entry->second != nullptr) { + *reqStr = entry->second(); + LOGE("DispatcherCmd reqStr1: %{public}s", reqStr->c_str()); + return true; + } else { + *reqStr = "Unknown commond: " + cmd; + LOGE("DispatcherCmd reqStr2: %{public}s", reqStr->c_str()); + return false; + } +} + +std::string HeapProfilerClient::HeapDumpCommand(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "HeapProfiler.takeHeapSnapshot"); + + std::unique_ptr params = PtJson::CreateObject(); + params->Add("reportProgress", true); + params->Add("captureNumericValue", true); + params->Add("exposeInternals", false); + request->Add("params", params); + return request->Stringify(); +} + +std::string HeapProfilerClient::AllocationTrackCommand(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "HeapProfiler.startTrackingHeapObjects"); + + std::unique_ptr params = PtJson::CreateObject(); + params->Add("trackAllocations", true); + request->Add("params", params); + return request->Stringify(); +} + +std::string HeapProfilerClient::AllocationTrackStopCommand(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "HeapProfiler.stopTrackingHeapObjects"); + + std::unique_ptr params = PtJson::CreateObject(); + params->Add("reportProgress", true); + request->Add("params", params); + return request->Stringify(); +} + +std::string HeapProfilerClient::Enable(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "HeapProfiler.enable"); + + std::unique_ptr params = PtJson::CreateObject(); + request->Add("params", params); + return request->Stringify(); +} + +std::string HeapProfilerClient::Disable(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "HeapProfiler.disable"); + + std::unique_ptr params = PtJson::CreateObject(); + request->Add("params", params); + return request->Stringify(); +} + +std::string HeapProfilerClient::Samping([[maybe_unused]] int id) +{ + return "Samping"; +} + +std::string HeapProfilerClient::SampingStop([[maybe_unused]] int id) +{ + return "SampingStop"; +} + +std::string HeapProfilerClient::CollectGarbage([[maybe_unused]] int id) +{ + return "CollectGarbage"; +} +} //OHOS::ArkCompiler::Toolchain \ No newline at end of file diff --git a/tooling/client/domain/heapprofiler_client.h b/tooling/client/domain/heapprofiler_client.h index 9703852d..496cd237 100644 --- a/tooling/client/domain/heapprofiler_client.h +++ b/tooling/client/domain/heapprofiler_client.h @@ -12,3 +12,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#ifndef ECMASCRIPT_TOOLING_CLIENT_DOMAIN_HEAPPROFILER_CLIENT_H +#define ECMASCRIPT_TOOLING_CLIENT_DOMAIN_HEAPPROFILER_CLIENT_H + +#include + +namespace OHOS::ArkCompiler::Toolchain { +class HeapProfilerClient final { +public: + HeapProfilerClient() = default; + ~HeapProfilerClient() = default; + + bool DispatcherCmd(int id, const std::string cmd, 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); +private: + +}; +} //OHOS::ArkCompiler::Toolchain +#endif \ No newline at end of file diff --git a/tooling/client/domain/profiler_client copy.h b/tooling/client/domain/profiler_client copy.h deleted file mode 100644 index 9703852d..00000000 --- a/tooling/client/domain/profiler_client copy.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * 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. - */ diff --git a/tooling/client/toolchain_cli/BUILD.gn b/tooling/client/toolchain_cli/BUILD.gn index 015a9095..6340ce32 100644 --- a/tooling/client/toolchain_cli/BUILD.gn +++ b/tooling/client/toolchain_cli/BUILD.gn @@ -33,8 +33,8 @@ config("hiviewdfx_config") { } ohos_executable("toolchain_cli") { - sources = [ - "main.cpp", + sources = [ + "main.cpp", "cli_command.cpp", ] @@ -43,11 +43,12 @@ ohos_executable("toolchain_cli") { "$toolchain_root/tooling", "$toolchain_root/inspector", "$toolchain_root/websocket", + "$toolchain_root/tooling/client", "$toolchain_root/tooling/client/toolchain_cli", ] deps = [ - "$toolchain_root/tooling/client:websocket_client", + "$toolchain_root/tooling/client:libark_toolchain_client_set", ] configs = [ ":hiviewdfx_config" ] diff --git a/tooling/client/toolchain_cli/cli_command.cpp b/tooling/client/toolchain_cli/cli_command.cpp index b00b45b7..060e58cc 100644 --- a/tooling/client/toolchain_cli/cli_command.cpp +++ b/tooling/client/toolchain_cli/cli_command.cpp @@ -23,47 +23,69 @@ namespace OHOS::ArkCompiler::Toolchain{ const std::string HELP_MSG = "usage: \n" " These are common commands list:\n" - " allocationtrack(at) allocation-track-start with options\n" - " break(b) break with options\n" - " backtrack(bt) backtrace\n" - " continue(c) continue\n" - " cpuprofile(cp) cpu-profile-start with options\n" - " delete(d) delete with options\n" - " disable disable\n" - " display display\n" - " enable enable\n" - " finish(fin) finish\n" - " frame(f) frame\n" - " heapdump(hd) heapdump with options\n" - " help(h) list available commands\n" - " ignore(ig) ignore\n" - " infobreakpoints(infob) info-breakpoints\n" - " infosource(infos) info-source\n" - " jump(j) jump\n" - " list(l) list\n" - " next(n) next\n" - " print(p) print with options\n" - " ptype ptype\n" - " quit(q) quit\n" - " run(r) run\n" - " setvar(sv) set value with options\n" - " step(s) step\n" - " undisplay undisplay\n" - " watch watch\n"; + " allocationtrack(at) allocation-track-start with options\n" + " allocationtrack-stop(at-stop) allocation-track-stop\n" + " heapdump(hd) heapdump with options\n" + " heapprofiler-enable(hp-enable) heapdump enable\n" + " heapprofiler-disable(hp-disable) heapdump disable\n" + " sampling(sampling) heapprofiler sampling\n" + " sampling-stop(sampling-stop) heapprofiler sampling stop\n" + " collectgarbage(gc) heapprofiler collectgarbage\n" + " cpuprofile(cp) cpuprofile start\n" + " cpuprofile-stop(cp-stop) cpuprofile stop\n" + " cpuprofile-enable(cp-enable) cpuprofile enable\n" + " cpuprofile-disable(cp-disable) cpuprofile disable\n" + " runtime-enable(rt-enable) runtime enable\n" + " heapusage(hu) runtime getHeapUsage\n" + " break(b) break with options\n" + " backtrack(bt) backtrace\n" + " continue(c) continue\n" + " delete(d) delete with options\n" + " disable disable\n" + " display display\n" + " enable enable\n" + " finish(fin) finish\n" + " frame(f) frame\n" + " help(h) list available commands\n" + " ignore(ig) ignore\n" + " infobreakpoints(infob) info-breakpoints\n" + " infosource(infos) info-source\n" + " jump(j) jump\n" + " list(l) list\n" + " next(n) next\n" + " print(p) print with options\n" + " ptype ptype\n" + " quit(q) quit\n" + " run(r) run\n" + " setvar(sv) set value with options\n" + " step(s) step\n" + " undisplay undisplay\n" + " watch watch\n"; const std::vector cmdList = { "allocationtrack", + "allocationtrack-stop", + "heapdump", + "heapprofiler-enable", + "heapprofiler-disable", + "sampling", + "sampling-stop", + "collectgarbage", + "cpuprofile", + "cpuprofile-stop", + "cpuprofile-enable", + "cpuprofile-disable", + "runtime-enable", + "heapusage", "break", "backtrack", "continue", - "cpuprofile", "delete", "disable", "display", "enable", "finish", "frame", - "heapdump", "help", "ignore", "infobreakpoints", @@ -79,112 +101,98 @@ const std::vector cmdList = { "undisplay", "watch" }; -std::string CliCommand::ExecCommand() +ErrCode CliCommand::ExecCommand() { + CreateCommandMap(); - int result = CreateCommandMap(); - if (result != ERR_OK) { - LOGE("failed to create command map."); - } - - result = OnCommand(); - if (result != ERR_OK) { - LOGE("failed to execute your command."); - resultReceiver_ = "error: failed to execute your command.\n"; - } - return resultReceiver_; + int result = OnCommand(); + return result; } -ErrCode CliCommand::CreateCommandMap() +void CliCommand::CreateCommandMap() { commandMap_ = { - {std::make_pair("allocationtrack","at"), std::bind(&CliCommand::ExecAllocationTrackCommand, this)}, - {std::make_pair("break","b"), std::bind(&CliCommand::ExecBreakCommand, this)}, - {std::make_pair("backtrack","bt"), std::bind(&CliCommand::ExecBackTrackCommand, this)}, - {std::make_pair("continue","c"), std::bind(&CliCommand::ExecContinueCommand, this)}, - {std::make_pair("cpuprofile","cp"), std::bind(&CliCommand::ExecCpuProfileCommand, this)}, - {std::make_pair("delete","d"), std::bind(&CliCommand::ExecDeleteCommand, this)}, - {std::make_pair("disable","disable"), std::bind(&CliCommand::ExecDisableCommand, this)}, - {std::make_pair("display","display"), std::bind(&CliCommand::ExecDisplayCommand, this)}, - {std::make_pair("enable","enable"), std::bind(&CliCommand::ExecEnableCommand, this)}, - {std::make_pair("finish","fin"), std::bind(&CliCommand::ExecFinishCommand, this)}, - {std::make_pair("frame","f"), std::bind(&CliCommand::ExecFrameCommand, this)}, - {std::make_pair("heapdump","hd"), std::bind(&CliCommand::ExecHeapDumpCommand, this)}, + {std::make_pair("allocationtrack","at"), std::bind(&CliCommand::HeapProfilerCommand, this, "allocationtrack")}, + {std::make_pair("allocationtrack-stop","at-stop"), + std::bind(&CliCommand::HeapProfilerCommand, this, "allocationtrack-stop")}, + {std::make_pair("heapdump","hd"), std::bind(&CliCommand::HeapProfilerCommand, this, "heapdump")}, + {std::make_pair("heapprofiler-enable","hp-enable"), + std::bind(&CliCommand::HeapProfilerCommand, this, "heapprofiler-enable")}, + {std::make_pair("heapprofiler-disable","hp-disable"), + std::bind(&CliCommand::HeapProfilerCommand, this, "heapprofiler-disable")}, + {std::make_pair("sampling","sampling"), std::bind(&CliCommand::HeapProfilerCommand, this, "sampling")}, + {std::make_pair("sampling-stop","sampling-stop"), + std::bind(&CliCommand::HeapProfilerCommand, this, "sampling-stop")}, + {std::make_pair("collectgarbage","gc"), std::bind(&CliCommand::HeapProfilerCommand, this, "collectgarbage")}, + {std::make_pair("cpuprofile","cp"), std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile")}, + {std::make_pair("cpuprofile-stop","cp-stop"), + std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-stop")}, + {std::make_pair("cpuprofile-enable","cp-enable"), + std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-enable")}, + {std::make_pair("cpuprofile-disable","cp-disable"), + std::bind(&CliCommand::CpuProfileCommand, this, "cpuprofile-disable")}, + {std::make_pair("runtime-enable","rt-enable"), std::bind(&CliCommand::RuntimeCommand, this, "runtime-enable")}, + {std::make_pair("heapusage","hu"), std::bind(&CliCommand::RuntimeCommand, this, "heapusage")}, + {std::make_pair("break","b"), std::bind(&CliCommand::DebuggerCommand, this, "break")}, + {std::make_pair("backtrack","bt"), std::bind(&CliCommand::DebuggerCommand, this, "backtrack")}, + {std::make_pair("continue","c"), std::bind(&CliCommand::DebuggerCommand, this, "continue")}, + {std::make_pair("delete","d"), std::bind(&CliCommand::DebuggerCommand, this, "delete")}, + {std::make_pair("disable","disable"), std::bind(&CliCommand::DebuggerCommand, this, "disable")}, + {std::make_pair("display","display"), std::bind(&CliCommand::DebuggerCommand, this, "display")}, + {std::make_pair("enable","enable"), std::bind(&CliCommand::DebuggerCommand, this, "enable")}, + {std::make_pair("finish","fin"), std::bind(&CliCommand::DebuggerCommand, this, "finish")}, + {std::make_pair("frame","f"), std::bind(&CliCommand::DebuggerCommand, this, "frame")}, {std::make_pair("help","h"), std::bind(&CliCommand::ExecHelpCommand, this)}, - {std::make_pair("ignore","ig"), std::bind(&CliCommand::ExecIgnoreCommand, this)}, - {std::make_pair("infobreakpoints","infob"), std::bind(&CliCommand::ExecInfoBCommand, this)}, - {std::make_pair("infosource","infos"), std::bind(&CliCommand::ExecInfoSCommand, this)}, - {std::make_pair("jump","j"), std::bind(&CliCommand::ExecJumpCommand, this)}, - {std::make_pair("list","l"), std::bind(&CliCommand::ExecListCommand, this)}, - {std::make_pair("next","n"), std::bind(&CliCommand::ExecNextCommand, this)}, - {std::make_pair("print","p"), std::bind(&CliCommand::ExecPrintCommand, this)}, - {std::make_pair("ptype","ptype"), std::bind(&CliCommand::ExecPtypeCommand, this)}, - {std::make_pair("run","r"), std::bind(&CliCommand::ExecRunCommand, this)}, - {std::make_pair("setvar","sv"), std::bind(&CliCommand::ExecSetValueCommand, this)}, - {std::make_pair("step","s"), std::bind(&CliCommand::ExecStepCommand, this)}, - {std::make_pair("undisplay","undisplay"), std::bind(&CliCommand::ExecUndisplayCommand, this)}, - {std::make_pair("watch","wa"), std::bind(&CliCommand::ExecWatchCommand, this)}, + {std::make_pair("ignore","ig"), std::bind(&CliCommand::DebuggerCommand, this, "ignore")}, + {std::make_pair("infobreakpoints","infob"), std::bind(&CliCommand::DebuggerCommand, this, "infobreakpoints")}, + {std::make_pair("infosource","infos"), std::bind(&CliCommand::DebuggerCommand, this, "infosource")}, + {std::make_pair("jump","j"), std::bind(&CliCommand::DebuggerCommand, this, "jump")}, + {std::make_pair("list","l"), std::bind(&CliCommand::DebuggerCommand, this, "list")}, + {std::make_pair("next","n"), std::bind(&CliCommand::DebuggerCommand, this, "next")}, + {std::make_pair("print","p"), std::bind(&CliCommand::DebuggerCommand, this, "print")}, + {std::make_pair("ptype","ptype"), std::bind(&CliCommand::DebuggerCommand, this, "ptype")}, + {std::make_pair("run","r"), std::bind(&CliCommand::DebuggerCommand, this, "run")}, + {std::make_pair("setvar","sv"), std::bind(&CliCommand::DebuggerCommand, this, "setvar")}, + {std::make_pair("step","s"), std::bind(&CliCommand::DebuggerCommand, this, "step")}, + {std::make_pair("undisplay","undisplay"), std::bind(&CliCommand::DebuggerCommand, this, "undisplay")}, + {std::make_pair("watch","wa"), std::bind(&CliCommand::DebuggerCommand, this, "watch")}, }; - - return ERR_OK; -} - -ErrCode CliCommand::ExecAllocationTrackCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecBreakCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecBackTrackCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecContinueCommand() -{ - return ERR_OK; } -ErrCode CliCommand::ExecCpuProfileCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecDeleteCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecDisableCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecDisplayCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecEnableCommand() -{ +ErrCode CliCommand::HeapProfilerCommand(const std::string cmd) +{ + std::cout << "exe success, cmd is " << cmd << std::endl; + std::string request; + bool result = false; + LOGE("HeapProfilerCommand: %{public}d", id_); + result = heapProfilerCli_.DispatcherCmd(id_, cmd, &request); + std::string lastReply = "{\"id\":" + std::to_string(id_) + ",\"result\":{}}"; + if (result) { + cliSocket_->ClientSendReq(request); + while (cliSocket_->IsConnected()) { + std::string decMessage = cliSocket_->Decode(); + std::cout << decMessage << std::endl; + if (strstr(decMessage.c_str(), lastReply.c_str())) { + break; + } + } + } else { + std::cout << request << std::endl; + } return ERR_OK; } -ErrCode CliCommand::ExecFinishCommand() +ErrCode CliCommand::CpuProfileCommand(const std::string cmd) { return ERR_OK; } -ErrCode CliCommand::ExecFrameCommand() +ErrCode CliCommand::DebuggerCommand(const std::string cmd) { return ERR_OK; } -ErrCode CliCommand::ExecHeapDumpCommand() +ErrCode CliCommand::RuntimeCommand(const std::string cmd) { return ERR_OK; } @@ -195,70 +203,6 @@ ErrCode CliCommand::ExecHelpCommand() return ERR_OK; } -ErrCode CliCommand::ExecIgnoreCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecInfoBCommand() -{ - return ERR_OK; -} -ErrCode CliCommand::ExecInfoSCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecJumpCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecListCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecNextCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecPrintCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecPtypeCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecRunCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecSetValueCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecStepCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecUndisplayCommand() -{ - return ERR_OK; -} - -ErrCode CliCommand::ExecWatchCommand() -{ - return ERR_OK; -} - ErrCode CliCommand::OnCommand() { std::map>::iterator it; @@ -271,7 +215,6 @@ ErrCode CliCommand::OnCommand() ||!strcmp(cmdPair.second.c_str(), cmd_.c_str())) { auto respond = it->second; respond(); - std::cout << "exe success, cmd is " << cmd_ << std::endl; return ERR_OK; } } @@ -288,8 +231,8 @@ ErrCode CliCommand::OnCommand() } else { ExecHelpCommand(); } - - return ERR_OK; + + return ERR_FAIL; } } // namespace OHOS::ArkCompiler::Toolchain diff --git a/tooling/client/toolchain_cli/cli_command.h b/tooling/client/toolchain_cli/cli_command.h index a3896038..6ff46878 100644 --- a/tooling/client/toolchain_cli/cli_command.h +++ b/tooling/client/toolchain_cli/cli_command.h @@ -20,8 +20,10 @@ #include #include #include -#include "../websocket/websocket_client.h" + #include "log_wrapper.h" +#include "websocket/websocket_client.h" +#include "domain/heapprofiler_client.h" namespace OHOS::ArkCompiler::Toolchain{ using ErrCode = int; @@ -34,56 +36,37 @@ enum { class CliCommand { public: - CliCommand(ToolchainWebsocket* cliSocket, std::vector cliCmdStr) + CliCommand(ToolchainWebsocket* cliSocket, std::vector cliCmdStr, int cmdId) { cliSocket_ = std::move(cliSocket); + id_ = cmdId; cmd_ = cliCmdStr[0]; for (unsigned int i = 1; i < cliCmdStr.size(); i++) { argList_.push_back(cliCmdStr[i]); } } - + ~CliCommand() { } ErrCode OnCommand(); - std::string ExecCommand(); - std::string GetCommand(const std::string &str); - ErrCode CreateCommandMap(); - ErrCode ExecAllocationTrackCommand(); - ErrCode ExecBreakCommand(); - ErrCode ExecBackTrackCommand(); - ErrCode ExecContinueCommand(); - ErrCode ExecCpuProfileCommand(); - ErrCode ExecDeleteCommand(); - ErrCode ExecDisableCommand(); - ErrCode ExecDisplayCommand(); - ErrCode ExecEnableCommand(); - ErrCode ExecFinishCommand(); - ErrCode ExecFrameCommand(); - ErrCode ExecHeapDumpCommand(); + ErrCode ExecCommand(); + void CreateCommandMap(); + ErrCode HeapProfilerCommand(const std::string cmd); + ErrCode DebuggerCommand(const std::string cmd); + ErrCode CpuProfileCommand(const std::string cmd); + ErrCode RuntimeCommand(const std::string cmd); ErrCode ExecHelpCommand(); - ErrCode ExecIgnoreCommand(); - ErrCode ExecInfoBCommand(); - ErrCode ExecInfoSCommand(); - ErrCode ExecJumpCommand(); - ErrCode ExecListCommand(); - ErrCode ExecNextCommand(); - ErrCode ExecPrintCommand(); - ErrCode ExecPtypeCommand(); - ErrCode ExecRunCommand(); - ErrCode ExecSetValueCommand(); - ErrCode ExecStepCommand(); - ErrCode ExecUndisplayCommand(); - ErrCode ExecWatchCommand(); - + private: std::string cmd_; VecStr argList_; std::map> commandMap_; std::string resultReceiver_ = ""; ToolchainWebsocket* cliSocket_ {nullptr}; + HeapProfilerClient heapProfilerCli_; + int id_ = 0; }; } // namespace OHOS::ArkCompiler::Toolchain diff --git a/tooling/client/toolchain_cli/main.cpp b/tooling/client/toolchain_cli/main.cpp index af7eba39..bc4d42aa 100644 --- a/tooling/client/toolchain_cli/main.cpp +++ b/tooling/client/toolchain_cli/main.cpp @@ -88,6 +88,7 @@ int Main(const int argc, const char** argv) std::cout << ">>> "; std::string inputStr; + int cmdId = 0; while(getline(std::cin, inputStr)) { if((!strcmp(inputStr.c_str(), "quit"))||(!strcmp(inputStr.c_str(), "q"))) { LOGE("toolchain_cli: quit"); @@ -95,8 +96,11 @@ int Main(const int argc, const char** argv) break; } std::vector cliCmdStr = SplitString(inputStr, " "); - OHOS::ArkCompiler::Toolchain::CliCommand cmd(&cliSocket, cliCmdStr); - std::cout << cmd.ExecCommand(); + cmdId += 1; + OHOS::ArkCompiler::Toolchain::CliCommand cmd(&cliSocket, cliCmdStr, cmdId); + if(ERR_FAIL == cmd.ExecCommand()) { + cmdId -= 1; + } std::cout << ">>> "; } } -- Gitee From 5047d5276d4dc790d5900f516814d8e3006e1733 Mon Sep 17 00:00:00 2001 From: zhouwenxuan Date: Thu, 17 Aug 2023 15:17:02 +0800 Subject: [PATCH 4/5] Add variable manager for toolchain client. issue: https://gitee.com/openharmony/arkcompiler_toolchain/issues/I7TYUN Signed-off-by: zhouwenxuan --- tooling/client/domain/debugger_client.cpp | 216 +++++++++++++++++++ tooling/client/domain/debugger_client.h | 50 +++++ tooling/client/domain/runtime_client.cpp | 124 +++++++++++ tooling/client/domain/runtime_client.h | 45 ++++ tooling/client/manager/domain_manager.cpp | 80 +++++++ tooling/client/manager/domain_manager.h | 58 +++++ tooling/client/manager/variable_manager.cpp | 69 ++++++ tooling/client/manager/variable_manager.h | 39 ++++ tooling/client/toolchain_cli/cli_command.cpp | 70 ++++-- tooling/client/toolchain_cli/cli_command.h | 23 +- 10 files changed, 753 insertions(+), 21 deletions(-) create mode 100644 tooling/client/manager/domain_manager.cpp create mode 100644 tooling/client/manager/domain_manager.h diff --git a/tooling/client/domain/debugger_client.cpp b/tooling/client/domain/debugger_client.cpp index 9703852d..60ca2696 100644 --- a/tooling/client/domain/debugger_client.cpp +++ b/tooling/client/domain/debugger_client.cpp @@ -12,3 +12,219 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include "domain/debugger_client.h" +#include "pt_json.h" +#include "log_wrapper.h" + +#include +#include +#include + +using PtJson = panda::ecmascript::tooling::PtJson; +namespace OHOS::ArkCompiler::Toolchain { +bool DebugerClient::DispatcherCmd(int id, const std::string cmd, std::string* reqStr) +{ + std::map> dispatcherTable { + { "break", std::bind(&DebugerClient::BreakCommand, this, id)}, + { "backtrack", std::bind(&DebugerClient::BacktrackCommand, this, id)}, + { "continue", std::bind(&DebugerClient::ContinueCommand, this, id)}, + { "delete", std::bind(&DebugerClient::DeleteCommand, this, id)}, + { "jump", std::bind(&DebugerClient::JumpCommand, this, id)}, + { "disable", std::bind(&DebugerClient::DisableCommand, this, id)}, + { "display", std::bind(&DebugerClient::DisplayCommand, this, id)}, + { "enable", std::bind(&DebugerClient::EnableCommand, this, id)}, + { "finish", std::bind(&DebugerClient::FinishCommand, this, id)}, + { "frame", std::bind(&DebugerClient::FrameCommand, this, id)}, + { "ignore", std::bind(&DebugerClient::IgnoreCommand, this, id)}, + { "infobreakpoints", std::bind(&DebugerClient::InfobreakpointsCommand, this, id)}, + { "infosource", std::bind(&DebugerClient::InfosourceCommand, this, id)}, + { "list", std::bind(&DebugerClient::NextCommand, this, id)}, + { "next", std::bind(&DebugerClient::ListCommand, this, id)}, + { "print", std::bind(&DebugerClient::PrintCommand, this, id)}, + { "ptype", std::bind(&DebugerClient::PtypeCommand, this, id)}, + { "run", std::bind(&DebugerClient::RunCommand, this, id)}, + { "setvar", std::bind(&DebugerClient::SetvarCommand, this, id)}, + { "step", std::bind(&DebugerClient::StepCommand, this, id)}, + { "undisplay", std::bind(&DebugerClient::UndisplayCommand, this, id)}, + { "watch", std::bind(&DebugerClient::WatchCommand, this, id)}, + { "resume", std::bind(&DebugerClient::ResumeCommand, this, id)} + }; + + auto entry = dispatcherTable.find(cmd); + + if (entry != dispatcherTable.end() && entry->second != nullptr) { + *reqStr = entry->second(); + LOGE("DebugerClient DispatcherCmd reqStr1: %{public}s", reqStr->c_str()); + return true; + } else { + *reqStr = "Unknown commond: " + cmd; + LOGE("DebugerClient DispatcherCmd reqStr2: %{public}s", reqStr->c_str()); + return false; + } +} + +std::string DebugerClient::BreakCommand(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Debugger.setBreakpointByUrl"); + + std::unique_ptr params = PtJson::CreateObject(); + params->Add("columnNumber", 0); + params->Add("lineNumber", 248); + params->Add("url", "entry/src/main/ets/pages/Index.ets"); + request->Add("params", params); + return request->Stringify(); +} + +std::string DebugerClient::BacktrackCommand(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "HeapProfiler.startTrackingHeapObjects"); + return request->Stringify(); +} + +std::string DebugerClient::ContinueCommand(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "HeapProfiler.stopTrackingHeapObjects"); + return request->Stringify(); +} + +std::string DebugerClient::DeleteCommand(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Debugger.removeBreakpoint"); + + std::unique_ptr params = PtJson::CreateObject(); + request->Add("params", params); + return request->Stringify(); +} + +std::string DebugerClient::DisableCommand(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Debugger.disable"); + + std::unique_ptr params = PtJson::CreateObject(); + request->Add("params", params); + return request->Stringify(); +} + +std::string DebugerClient::DisplayCommand([[maybe_unused]] int id) +{ + return "display"; +} + +std::string DebugerClient::EnableCommand([[maybe_unused]] int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Debugger.enable"); + + std::unique_ptr params = PtJson::CreateObject(); + // params->Add("maxScriptsCacheSize", 1.0E7); + request->Add("params", params); + return request->Stringify(); +} + +std::string DebugerClient::FinishCommand([[maybe_unused]] int id) +{ + return "finish"; +} + +std::string DebugerClient::FrameCommand([[maybe_unused]] int id) +{ + return "frame"; +} + +std::string DebugerClient::IgnoreCommand([[maybe_unused]] int id) +{ + return "ignore"; +} + +std::string DebugerClient::InfobreakpointsCommand([[maybe_unused]] int id) +{ + return "infobreakpoint"; +} + +std::string DebugerClient::InfosourceCommand([[maybe_unused]] int id) +{ + return "infosource"; +} + +std::string DebugerClient::JumpCommand([[maybe_unused]] int id) +{ + return "jump"; +} + +std::string DebugerClient::NextCommand([[maybe_unused]] int id) +{ + return "next"; +} + +std::string DebugerClient::ListCommand([[maybe_unused]] int id) +{ + return "list"; +} + +std::string DebugerClient::PrintCommand([[maybe_unused]] int id) +{ + return "print"; +} + +std::string DebugerClient::PtypeCommand([[maybe_unused]] int id) +{ + return "ptype"; +} + +std::string DebugerClient::RunCommand([[maybe_unused]] int id) +{ + return "run"; +} + +std::string DebugerClient::SetvarCommand([[maybe_unused]] int id) +{ + return "Debugger.setVariableValue"; +} + +std::string DebugerClient::StepCommand([[maybe_unused]] int id) +{ + return "step"; +} + +std::string DebugerClient::UndisplayCommand([[maybe_unused]] int id) +{ + return "undisplay"; +} + +std::string DebugerClient::WatchCommand([[maybe_unused]] int id) +{ + return "Debugger.evaluateOnCallFrame"; +} + +std::string DebugerClient::ResumeCommand(int id) +{ + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Debugger.resume"); + + std::unique_ptr params = PtJson::CreateObject(); + request->Add("params", params); + return request->Stringify(); +} + +void DebugerClient::AddBreakPointInfo(std::string url, std::string lineNumber) +{ + BreakPointInfo breakPointInfo; + breakPointInfo.url = url; + breakPointInfo.lineNumber = lineNumber; + breakPointInfoList_.emplace_back(breakPointInfo); +} + +} //OHOS::ArkCompiler::Toolchain \ No newline at end of file diff --git a/tooling/client/domain/debugger_client.h b/tooling/client/domain/debugger_client.h index 9703852d..a427a229 100644 --- a/tooling/client/domain/debugger_client.h +++ b/tooling/client/domain/debugger_client.h @@ -12,3 +12,53 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#ifndef ECMASCRIPT_TOOLING_CLIENT_DOMAIN_DEBUGGER_CLIENT_H +#define ECMASCRIPT_TOOLING_CLIENT_DOMAIN_DEBUGGER_CLIENT_H + +#include +#include +#include "toolchain_cli/cli_command.h" + +namespace OHOS::ArkCompiler::Toolchain { +struct BreakPointInfo { + std::string lineNumber; + std::string url; +}; +class DebugerClient final { +public: + DebugerClient() = default; + ~DebugerClient() = default; + + bool DispatcherCmd(int id, const std::string cmd, std::string* reqStr); + std::string BreakCommand(int id); + std::string BacktrackCommand(int id); + std::string ContinueCommand(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 PrintCommand(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); + + void AddBreakPointInfo(std::string url, std::string lineNumber); + +private: + std::vector breakPointInfoList_; +}; +} //OHOS::ArkCompiler::Toolchain +#endif \ No newline at end of file diff --git a/tooling/client/domain/runtime_client.cpp b/tooling/client/domain/runtime_client.cpp index 9703852d..4e351d08 100644 --- a/tooling/client/domain/runtime_client.cpp +++ b/tooling/client/domain/runtime_client.cpp @@ -12,3 +12,127 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include "domain/runtime_client.h" +#include "pt_json.h" +#include "log_wrapper.h" + +#include +#include +#include + +using PtJson = panda::ecmascript::tooling::PtJson; +namespace OHOS::ArkCompiler::Toolchain { +bool RuntimeClient::DispatcherCmd(int id, const std::string cmd, std::string* reqStr ) +{ + std::map> dispatcherTable { + { "heapusage", std::bind(&RuntimeClient::HeapusageCommand, this, id)}, + { "runtime-enable", std::bind(&RuntimeClient::RuntimeEnableCommand, this, id)}, + { "runtime-disable", std::bind(&RuntimeClient::RuntimeDisableCommand, this, id)}, + { "print", std::bind(&RuntimeClient::GetPropertiesCommand, this, id)}, + { "print2", std::bind(&RuntimeClient::GetPropertiesCommand2, this, id)}, + { "run", std::bind(&RuntimeClient::RunIfWaitingForDebuggerCommand, this, id)}, + }; + + auto entry = dispatcherTable.find(cmd); + + if (entry != dispatcherTable.end() && entry->second != nullptr) { + *reqStr = entry->second(); + LOGE("RuntimeClient DispatcherCmd reqStr1: %{public}s", reqStr->c_str()); + return true; + } else { + *reqStr = "Unknown commond: " + cmd; + LOGE("RuntimeClient DispatcherCmd reqStr2: %{public}s", reqStr->c_str()); + return false; + } +} + +std::string RuntimeClient::HeapusageCommand(int id) +{ + idMethodMap_.emplace("getHeapUsage", id); + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Runtime.getHeapUsage"); + + std::unique_ptr params = PtJson::CreateObject(); + request->Add("params", params); + return request->Stringify(); +} + +std::string RuntimeClient::RuntimeEnableCommand(int id) +{ + idMethodMap_.emplace("enable", id); + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Runtime.enable"); + + std::unique_ptr params = PtJson::CreateObject(); + request->Add("params", params); + return request->Stringify(); +} + +std::string RuntimeClient::RuntimeDisableCommand(int id) +{ + idMethodMap_.emplace("disable", id); + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Runtime.disable"); + + std::unique_ptr params = PtJson::CreateObject(); + request->Add("params", params); + return request->Stringify(); +} + +std::string RuntimeClient::RunIfWaitingForDebuggerCommand(int id) +{ + idMethodMap_.emplace("runIfWaitingForDebugger", id); + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Runtime.runIfWaitingForDebugger"); + + std::unique_ptr params = PtJson::CreateObject(); + request->Add("params", params); + return request->Stringify(); +} + +std::string RuntimeClient::GetPropertiesCommand(int id) +{ + idMethodMap_.emplace("getProperties", id); + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Runtime.getProperties"); + + std::unique_ptr 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); + return request->Stringify(); +} + +std::string RuntimeClient::GetPropertiesCommand2(int id) +{ + idMethodMap_.emplace("getProperties", id); + std::unique_ptr request = PtJson::CreateObject(); + request->Add("id", id); + request->Add("method", "Runtime.getProperties"); + + std::unique_ptr params = PtJson::CreateObject(); + params->Add("accessorPropertiesOnly", true); + params->Add("generatePreview", true); + params->Add("objectId", "0"); + params->Add("ownProperties", false); + request->Add("params", params); + return request->Stringify(); +} + +int RuntimeClient::GetIdByMethod(const std::string method) +{ + auto it = idMethodMap_.find(method); + if (it != idMethodMap_.end()) { + return it->second; + } + return 0; +} +} //OHOS::ArkCompiler::Toolchain \ No newline at end of file diff --git a/tooling/client/domain/runtime_client.h b/tooling/client/domain/runtime_client.h index 9703852d..69459eb8 100644 --- a/tooling/client/domain/runtime_client.h +++ b/tooling/client/domain/runtime_client.h @@ -12,3 +12,48 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#ifndef ECMASCRIPT_TOOLING_CLIENT_DOMAIN_RUNTIME_CLIENT_H +#define ECMASCRIPT_TOOLING_CLIENT_DOMAIN_RUNTIME_CLIENT_H + +#include +#include + +namespace OHOS::ArkCompiler::Toolchain { +class RuntimeClient final { +public: + RuntimeClient(const RuntimeClient&) = delete; + RuntimeClient& operator=(const RuntimeClient&) = delete; + + static RuntimeClient& getInstance() { + static RuntimeClient instance; + return instance; + } + + 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); + + std::map GetIdMethodMap() const { + return idMethodMap_; + } + + void SetObjectId(const std::string objectId) { + objectId_ = objectId; + } + + int GetIdByMethod(const std::string method); + +private: + RuntimeClient() = default; + ~RuntimeClient() = default; + std::map idMethodMap_; + std::string objectId_ {"0"}; + +}; +} //OHOS::ArkCompiler::Toolchain +#endif \ No newline at end of file diff --git a/tooling/client/manager/domain_manager.cpp b/tooling/client/manager/domain_manager.cpp new file mode 100644 index 00000000..76365069 --- /dev/null +++ b/tooling/client/manager/domain_manager.cpp @@ -0,0 +1,80 @@ +/* + * 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 + +#include "manager/domain_manager.h" +#include "log_wrapper.h" +#include "pt_json.h" +#include "manager/variable_manager.h" + +using PtJson = panda::ecmascript::tooling::PtJson; +using Result = panda::ecmascript::tooling::Result; +namespace OHOS::ArkCompiler::Toolchain { +void DomainManager::DispatcherReply(char* msg) +{ + std::string decMessage = std::string(msg); + std::unique_ptr json = PtJson::Parse(decMessage); + if (json == nullptr) { + LOGE("json parse error"); + return; + } + + if (!json->IsObject()) { + LOGE("json parse format error"); + json->ReleaseRoot(); + return; + } + + std::string domain; + Result ret; + int32_t id; + ret = json->GetInt("id", &id); + if (ret == Result::SUCCESS) { + domain = GetDomainById(id); + RemoveDomainById(id); + } + + std::string wholeMethod; + std::string method; + ret = json->GetString("method", &wholeMethod); + if (ret == Result::SUCCESS) { + std::string::size_type length = wholeMethod.length(); + std::string::size_type indexPoint; + indexPoint = wholeMethod.find_first_of('.', 0); + if (indexPoint == std::string::npos || indexPoint == 0 || indexPoint == length - 1) { + return; + } + domain = wholeMethod.substr(0, indexPoint); + } + + if (domain == "HeapProfiler") { + heapProfilerClient_.RecvReply(std::move(json)); + } else if (domain == "Profiler") { + LOGI("Profiler replay message is %{public}s", json->Stringify().c_str()); + } else if (domain == "Runtime") { + RuntimeClient &runtimeClient = RuntimeClient::getInstance(); + if (static_cast(id) == runtimeClient.GetIdByMethod("getproperties")) { + VariableManager &variableManager = VariableManager::getInstance(); + variableManager.HandleMessage(std::move(json)); + variableManager.ShowVariableInfos(); + } else { + LOGI("Debugger replay message is %{public}s", json->Stringify().c_str()); + } + } else if (domain == "Debugger") { + LOGI("Debugger replay message is %{public}s", json->Stringify().c_str()); + } +} +} \ No newline at end of file diff --git a/tooling/client/manager/domain_manager.h b/tooling/client/manager/domain_manager.h new file mode 100644 index 00000000..f606f311 --- /dev/null +++ b/tooling/client/manager/domain_manager.h @@ -0,0 +1,58 @@ +/* + * 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_DOMAIN_MANAGER_H +#define ECMASCRIPT_TOOLING_CLIENT_MANAGER_DOMAIN_MANAGER_H + +#include + +#include "toolchain_cli/cli_command.h" + +namespace OHOS::ArkCompiler::Toolchain { +class DomainManager{ +public: + DomainManager() = default; + ~DomainManager() = default; + + void DispatcherReply(char* decMessage); + + std::string GetDomainById(uint32_t id) + { + auto iter = idDomainMap_.find(id); + if (iter == idDomainMap_.end()) { + return ""; + } + return iter->second; + } + + void SetDomainById(uint32_t id, std::string domain) + { + idDomainMap_.emplace(id, domain); + } + + void RemoveDomainById(uint32_t id) + { + auto it = idDomainMap_.find(id); + if (it != idDomainMap_.end()) { + idDomainMap_.erase(it); + } + } + +private: + HeapProfilerClient heapProfilerClient_; + std::map idDomainMap_; +}; +} //OHOS::ArkCompiler::Toolchain +#endif \ No newline at end of file diff --git a/tooling/client/manager/variable_manager.cpp b/tooling/client/manager/variable_manager.cpp index 9703852d..545279ca 100644 --- a/tooling/client/manager/variable_manager.cpp +++ b/tooling/client/manager/variable_manager.cpp @@ -12,3 +12,72 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#include + +#include "log_wrapper.h" +#include "manager/variable_manager.h" + +using PtJson = panda::ecmascript::tooling::PtJson; +using Result = panda::ecmascript::tooling::Result; +namespace OHOS::ArkCompiler::Toolchain { +void VariableManager::HandleMessage(const std::unique_ptr json) +{ + if (json == nullptr) { + LOGE("toolchain_client: json parse error"); + return; + } + + if (!json->IsObject()) { + LOGE("toolchain_client: json parse format error"); + json->ReleaseRoot(); + return; + } + + std::unique_ptr result; + Result ret = json->GetObject("result", &result); + if (ret != Result::SUCCESS) { + LOGE("toolchain_client: find result error"); + return; + } + + std::unique_ptr innerResult; + ret = result->GetArray("result", &innerResult); + if (ret != Result::SUCCESS) { + LOGE("toolchain_client: find innerResult error"); + return; + } + + for (int32_t i = 0; i < innerResult->GetSize(); i++) { + std::unique_ptr variableInfo = PropertyDescriptor::Create(*(innerResult->Get(i))); + variableInfos_.emplace(i + 4, std::move(variableInfo)); + } +} + +void VariableManager::ShowVariableInfos() +{ + std::cout << std::endl; + std::cout << "1. LOCAL" << std::endl; + for (const auto& info : variableInfos_) { + if (info.second->GetValue()->HasDescription()) { + std::cout << " " << info.first << ". " << info.second->GetName() << " = " << + info.second->GetValue()->GetDescription() << std::endl; + } else { + std::cout << " " << info.first << ". " << info.second->GetName() << " = " << + info.second->GetValue()->GetType() << std::endl; + } + } + std::cout << "2. MODULE" << std::endl; + std::cout << "3. GLOBAL" << std::endl; +} + +std::string VariableManager::FindObjectIdByIndex(const int32_t index) +{ + auto it = variableInfos_.find(index); + if (it != variableInfos_.end()) { + return std::to_string(it->second->GetValue()->GetObjectId()); + } + LOGE("index not found"); + return ""; +} +} \ No newline at end of file diff --git a/tooling/client/manager/variable_manager.h b/tooling/client/manager/variable_manager.h index 9703852d..9d978acb 100644 --- a/tooling/client/manager/variable_manager.h +++ b/tooling/client/manager/variable_manager.h @@ -12,3 +12,42 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + +#ifndef ECMASCRIPT_TOOLING_CLIENT_MANAGER_VARIABLE_MANAGER_H +#define ECMASCRIPT_TOOLING_CLIENT_MANAGER_VARIABLE_MANAGER_H + +#include +#include +#include "pt_json.h" +#include "pt_types.h" + +using PtJson = panda::ecmascript::tooling::PtJson; +namespace OHOS::ArkCompiler::Toolchain { +using panda::ecmascript::tooling::PropertyDescriptor; +class VariableManager final { +public: + VariableManager(const VariableManager&) = delete; + VariableManager& operator=(const VariableManager&) = delete; + + static VariableManager& getInstance() { + static VariableManager instance; + return instance; + } + + void HandleMessage(std::unique_ptr json); + + void ShowVariableInfos(); + + std::string FindObjectIdByIndex(const int32_t index); + + std::multimap> &GetVariableInfos() { + return variableInfos_; + } + +private: + VariableManager() {} + ~VariableManager() {} + std::multimap> variableInfos_; +}; +} //OHOS::ArkCompiler::Toolchain +#endif \ No newline at end of file diff --git a/tooling/client/toolchain_cli/cli_command.cpp b/tooling/client/toolchain_cli/cli_command.cpp index 060e58cc..ee622f6d 100644 --- a/tooling/client/toolchain_cli/cli_command.cpp +++ b/tooling/client/toolchain_cli/cli_command.cpp @@ -17,10 +17,18 @@ #include #include #include +#include + #include "cli_command.h" #include "log_wrapper.h" +#include "manager/domain_manager.h" +#include "domain/debugger_client.h" +#include "manager/variable_manager.h" +#include "domain/runtime_client.h" namespace OHOS::ArkCompiler::Toolchain{ +extern ToolchainWebsocket g_cliSocket; +extern DomainManager g_domainManager; const std::string HELP_MSG = "usage: \n" " These are common commands list:\n" " allocationtrack(at) allocation-track-start with options\n" @@ -60,7 +68,7 @@ const std::string HELP_MSG = "usage: \n" " setvar(sv) set value with options\n" " step(s) step\n" " undisplay undisplay\n" - " watch watch\n"; + " watch(wa) watch\n"; const std::vector cmdList = { "allocationtrack", @@ -149,13 +157,15 @@ void CliCommand::CreateCommandMap() {std::make_pair("jump","j"), std::bind(&CliCommand::DebuggerCommand, this, "jump")}, {std::make_pair("list","l"), std::bind(&CliCommand::DebuggerCommand, this, "list")}, {std::make_pair("next","n"), std::bind(&CliCommand::DebuggerCommand, this, "next")}, - {std::make_pair("print","p"), std::bind(&CliCommand::DebuggerCommand, this, "print")}, + {std::make_pair("print","p"), std::bind(&CliCommand::RuntimeCommand, this, "print")}, + {std::make_pair("print2","p2"), std::bind(&CliCommand::RuntimeCommand, this, "print2")}, {std::make_pair("ptype","ptype"), std::bind(&CliCommand::DebuggerCommand, this, "ptype")}, - {std::make_pair("run","r"), std::bind(&CliCommand::DebuggerCommand, this, "run")}, + {std::make_pair("run","r"), std::bind(&CliCommand::RuntimeCommand, this, "run")}, {std::make_pair("setvar","sv"), std::bind(&CliCommand::DebuggerCommand, this, "setvar")}, {std::make_pair("step","s"), std::bind(&CliCommand::DebuggerCommand, this, "step")}, {std::make_pair("undisplay","undisplay"), std::bind(&CliCommand::DebuggerCommand, this, "undisplay")}, {std::make_pair("watch","wa"), std::bind(&CliCommand::DebuggerCommand, this, "watch")}, + {std::make_pair("resume","resume"), std::bind(&CliCommand::DebuggerCommand, this, "resume")}, }; } @@ -166,34 +176,66 @@ ErrCode CliCommand::HeapProfilerCommand(const std::string cmd) bool result = false; LOGE("HeapProfilerCommand: %{public}d", id_); result = heapProfilerCli_.DispatcherCmd(id_, cmd, &request); - std::string lastReply = "{\"id\":" + std::to_string(id_) + ",\"result\":{}}"; if (result) { - cliSocket_->ClientSendReq(request); - while (cliSocket_->IsConnected()) { - std::string decMessage = cliSocket_->Decode(); - std::cout << decMessage << std::endl; - if (strstr(decMessage.c_str(), lastReply.c_str())) { - break; - } + g_cliSocket.ClientSendReq(request); + if (g_domainManager.GetDomainById(id_) == "") { + g_domainManager.SetDomainById(id_, "heapprofiler"); } } else { - std::cout << request << std::endl; + return ERR_FAIL; } return ERR_OK; } ErrCode CliCommand::CpuProfileCommand(const std::string cmd) { + std::cout << "exe success, cmd is " << cmd << std::endl; return ERR_OK; } ErrCode CliCommand::DebuggerCommand(const std::string cmd) { + std::cout << "exe success, cmd is " << cmd << std::endl; + std::string request; + bool result = false; + LOGE("DebuggerCommand: %{public}d", id_); + DebugerClient debuggerCli; + if (GetArgList().size() == 2) { + debuggerCli.AddBreakPointInfo(GetArgList()[0], GetArgList()[1]); + } + result = debuggerCli.DispatcherCmd(id_, cmd, &request); + if (result) { + g_cliSocket.ClientSendReq(request); + if (g_domainManager.GetDomainById(id_) == "") { + g_domainManager.SetDomainById(id_, "Debugger"); + } + } else { + return ERR_FAIL; + } return ERR_OK; } ErrCode CliCommand::RuntimeCommand(const std::string cmd) { + std::cout << "exe success, cmd is " << cmd << std::endl; + std::string request; + bool result = false; + LOGE("RuntimeCommand: %{public}d", id_); + RuntimeClient runtimeClient = RuntimeClient::getInstance(); + VariableManager variableManager = VariableManager::getInstance(); + if (cmd == "print" && GetArgList().size() == 1) { + std::string objectId = variableManager.FindObjectIdByIndex(static_cast(GetArgList()[0])); + runtimeClient.SetObjectId(objectId); + } + result = runtimeClient.DispatcherCmd(id_, cmd, &request); + if (result) { + g_cliSocket.ClientSendReq(request); + if (g_domainManager.GetDomainById(id_) == "") { + g_domainManager.SetDomainById(id_, "Runtime"); + } + } else { + return ERR_FAIL; + } return ERR_OK; } @@ -214,8 +256,7 @@ ErrCode CliCommand::OnCommand() if (!strcmp(cmdPair.first.c_str(), cmd_.c_str()) ||!strcmp(cmdPair.second.c_str(), cmd_.c_str())) { auto respond = it->second; - respond(); - return ERR_OK; + return respond(); } } @@ -234,5 +275,4 @@ ErrCode CliCommand::OnCommand() return ERR_FAIL; } - } // namespace OHOS::ArkCompiler::Toolchain diff --git a/tooling/client/toolchain_cli/cli_command.h b/tooling/client/toolchain_cli/cli_command.h index 6ff46878..df645446 100644 --- a/tooling/client/toolchain_cli/cli_command.h +++ b/tooling/client/toolchain_cli/cli_command.h @@ -16,14 +16,16 @@ #ifndef ECMASCRIPT_TOOLING_CLIENT_TOOLCHAIN_CLI_COMMAND_H #define ECMASCRIPT_TOOLING_CLIENT_TOOLCHAIN_CLI_COMMAND_H -#include -#include #include #include +#include +#include #include "log_wrapper.h" #include "websocket/websocket_client.h" #include "domain/heapprofiler_client.h" +#include "domain/runtime_client.h" + namespace OHOS::ArkCompiler::Toolchain{ using ErrCode = int; @@ -36,9 +38,8 @@ enum { class CliCommand { public: - CliCommand(ToolchainWebsocket* cliSocket, std::vector cliCmdStr, int cmdId) + CliCommand(std::vector cliCmdStr, int cmdId) { - cliSocket_ = std::move(cliSocket); id_ = cmdId; cmd_ = cliCmdStr[0]; for (unsigned int i = 1; i < cliCmdStr.size(); i++) { @@ -59,14 +60,24 @@ public: ErrCode RuntimeCommand(const std::string cmd); ErrCode ExecHelpCommand(); + uint32_t GetId() const + { + return id_; + } + + VecStr GetArgList() const + { + return argList_; + } + private: std::string cmd_; VecStr argList_; std::map> commandMap_; std::string resultReceiver_ = ""; - ToolchainWebsocket* cliSocket_ {nullptr}; HeapProfilerClient heapProfilerCli_; - int id_ = 0; + // RuntimeClient runtimeCli_; + uint32_t id_ = 0; }; } // namespace OHOS::ArkCompiler::Toolchain -- Gitee From 54e1cd7180b587e41a8822c0db837c372a3ebd7d Mon Sep 17 00:00:00 2001 From: duning Date: Fri, 1 Sep 2023 15:32:49 +0800 Subject: [PATCH 5/5] Signed-off-by: duning Change-Id: I0fe3053dd46894e1389abfb5bdb632d57dbfbeaa --- tooling/client/BUILD.gn | 6 ++ tooling/client/manager/breakpoint_manager.cpp | 65 +++++++++++++++++++ tooling/client/manager/breakpoint_manager.h | 39 +++++++++++ tooling/client/manager/domain_manager.cpp | 3 + tooling/client/toolchain_cli/cli_command.cpp | 18 ++++- 5 files changed, 130 insertions(+), 1 deletion(-) diff --git a/tooling/client/BUILD.gn b/tooling/client/BUILD.gn index bf9360f7..a248ecf3 100644 --- a/tooling/client/BUILD.gn +++ b/tooling/client/BUILD.gn @@ -56,6 +56,12 @@ ohos_source_set("libark_toolchain_client_set") { sources = [ "websocket/websocket_client.cpp", "domain/heapprofiler_client.cpp", + "domain/debugger_client.cpp", + "domain/runtime_client.cpp", + "domain/profiler_client.cpp", + "manager/domain_manager.cpp", + "manager/variable_manager.cpp", + "manager/breakpoint_manager.cpp", ] deps += [ diff --git a/tooling/client/manager/breakpoint_manager.cpp b/tooling/client/manager/breakpoint_manager.cpp index 9703852d..93e64165 100644 --- a/tooling/client/manager/breakpoint_manager.cpp +++ b/tooling/client/manager/breakpoint_manager.cpp @@ -12,3 +12,68 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include + +#include "log_wrapper.h" +#include "manager/breakpoint_manager.h" +#include "toolchain_cli/cli_command.h" +using PtJson = panda::ecmascript::tooling::PtJson; +using Result = panda::ecmascript::tooling::Result; +namespace OHOS::ArkCompiler::Toolchain { + void Breakpoint::HandleMessage(const std::unique_ptr json){ + if (json == nullptr) { + LOGE("toolchain_client: json parse error"); + return; + } + + if (!json->IsObject()) { + LOGE("toolchain_client: json parse format error"); + json->ReleaseRoot(); + return; + } + Result ret; + std::unique_ptr result; + ret = json->GetObject("result", &result); + if (ret != Result::SUCCESS) { + LOGE("toolchain_client: find result error"); + return; + } + std::string breakpointId; + Breaklocation breaklocation; + ret = result->GetString("breakpointId", &breakpointId); + int flag=0; + if(ret == Result::SUCCESS) { + breaklocation.breakpointId=breakpointId; + int length=breakpointId.size(); + for(int i=0;i::iterator it=breaklist.begin()+num-1; + breaklist.erase(it); + } +} \ No newline at end of file diff --git a/tooling/client/manager/breakpoint_manager.h b/tooling/client/manager/breakpoint_manager.h index 9703852d..2568cbf8 100644 --- a/tooling/client/manager/breakpoint_manager.h +++ b/tooling/client/manager/breakpoint_manager.h @@ -12,3 +12,42 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#ifndef ECMASCRIPT_TOOLING_CLIENT_MANAGER_BREAKPOINT_MANAGER_H +#define ECMASCRIPT_TOOLING_CLIENT_MANAGER_BREAKPOINT_MANAGER_H + +#include +#include +#include +#include +#include +#include "pt_json.h" +#include "pt_types.h" +namespace OHOS::ArkCompiler::Toolchain { +using PtJson = panda::ecmascript::tooling::PtJson; +using Result = panda::ecmascript::tooling::Result; +struct Breaklocation{ + std::string breakpointId; + std::string url; + std::string lineNumber; + std::string columnNumber; +}; +class Breakpoint{ +public: + Breakpoint(const Breakpoint&) = delete; + Breakpoint& operator=(const Breakpoint&) = delete; + + static Breakpoint& getInstance() { + static Breakpoint instance; + return instance; + } + + std::vector breaklist; + void HandleMessage(const std::unique_ptr json); + void show(); + void deletebreaklocation(unsigned int num); +private: + Breakpoint() = default; + ~Breakpoint() = default; +}; +} +#endif \ No newline at end of file diff --git a/tooling/client/manager/domain_manager.cpp b/tooling/client/manager/domain_manager.cpp index 76365069..7c93c24f 100644 --- a/tooling/client/manager/domain_manager.cpp +++ b/tooling/client/manager/domain_manager.cpp @@ -19,6 +19,7 @@ #include "log_wrapper.h" #include "pt_json.h" #include "manager/variable_manager.h" +#include "manager/breakpoint_manager.h" using PtJson = panda::ecmascript::tooling::PtJson; using Result = panda::ecmascript::tooling::Result; @@ -74,6 +75,8 @@ void DomainManager::DispatcherReply(char* msg) LOGI("Debugger replay message is %{public}s", json->Stringify().c_str()); } } else if (domain == "Debugger") { + Breakpoint &breakpoint = Breakpoint::getInstance(); + breakpoint.HandleMessage(std::move(json)); LOGI("Debugger replay message is %{public}s", json->Stringify().c_str()); } } diff --git a/tooling/client/toolchain_cli/cli_command.cpp b/tooling/client/toolchain_cli/cli_command.cpp index ee622f6d..57ec624a 100644 --- a/tooling/client/toolchain_cli/cli_command.cpp +++ b/tooling/client/toolchain_cli/cli_command.cpp @@ -25,6 +25,7 @@ #include "domain/debugger_client.h" #include "manager/variable_manager.h" #include "domain/runtime_client.h" +#include "manager/breakpoint_manager.h" namespace OHOS::ArkCompiler::Toolchain{ extern ToolchainWebsocket g_cliSocket; @@ -197,9 +198,24 @@ ErrCode CliCommand::DebuggerCommand(const std::string cmd) { std::cout << "exe success, cmd is " << cmd << std::endl; std::string request; + DebugerClient debuggerCli; + Breakpoint &breakpoint=Breakpoint::getInstance(); + if(cmd=="display"){ + breakpoint.show(); + return ERR_OK; + } + if(cmd=="delete"){ + std::string bnumber=GetArgList()[0]; + unsigned int num=std::stoi(bnumber); + if(num<=breakpoint.breaklist.size()&&num>0){ + debuggerCli.AddBreakPointInfo(breakpoint.breaklist[num-1].breakpointId,"0"); + breakpoint.deletebreaklocation(num); + } + else + return ERR_FAIL; + } bool result = false; LOGE("DebuggerCommand: %{public}d", id_); - DebugerClient debuggerCli; if (GetArgList().size() == 2) { debuggerCli.AddBreakPointInfo(GetArgList()[0], GetArgList()[1]); } -- Gitee