1 /*
2 * Copyright (C) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 */
16 // The process is used to test jdwp.
17 // jpid List pids of processes hosting a JDWP transport
18 #include "define.h"
19 #include "HdcJdwpSimulator.h"
20 using namespace OHOS::HiviewDFX;
21 static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "JDWP_TEST"};
22 static uv_loop_t loopMain;
23 static HdcJdwpSimulator *clsHdcJdwpSimulator = nullptr;
24
PrintMessage(const char * fmt,...)25 static void PrintMessage(const char *fmt, ...)
26 {
27 int ret = 0;
28 va_list ap;
29 va_start(ap, fmt);
30 vfprintf(stdout, fmt, ap);
31 ret = fprintf(stdout, "\n");
32 va_end(ap);
33 }
34
TryCloseHandle(const uv_handle_t * handle,bool alwaysCallback,uv_close_cb closeCallBack)35 static void TryCloseHandle(const uv_handle_t *handle, bool alwaysCallback,
36 uv_close_cb closeCallBack)
37 {
38 bool hasCallClose = false;
39 if (handle->loop && !uv_is_closing(handle)) {
40 uv_close((uv_handle_t *)handle, closeCallBack);
41 hasCallClose = true;
42 }
43 if (!hasCallClose && alwaysCallback) {
44 closeCallBack((uv_handle_t *)handle);
45 }
46 }
47
TryCloseHandle(const uv_handle_t * handle,uv_close_cb closeCallBack)48 static void TryCloseHandle(const uv_handle_t *handle, uv_close_cb closeCallBack)
49 {
50 TryCloseHandle(handle, false, closeCallBack);
51 }
52
TryCloseHandle(const uv_handle_t * handle)53 static void TryCloseHandle(const uv_handle_t *handle)
54 {
55 TryCloseHandle(handle, nullptr);
56 }
57
TryCloseLoop(uv_loop_t * ptrLoop,const char * callerName)58 static bool TryCloseLoop(uv_loop_t *ptrLoop, const char *callerName)
59 {
60 uint8_t closeRetry = 0;
61 bool ret = false;
62 constexpr int maxRetry = 3;
63 constexpr int maxHandle = 2;
64 for (closeRetry = 0; closeRetry < maxRetry; ++closeRetry) {
65 if (uv_loop_close(ptrLoop) == UV_EBUSY) {
66 if (closeRetry > maxRetry) {
67 PrintMessage("%s close busy,try:%d", callerName, closeRetry);
68 }
69
70 if (ptrLoop->active_handles >= maxHandle) {
71 PrintMessage("TryCloseLoop issue");
72 }
73 auto clearLoopTask = [](uv_handle_t *handle, void *arg) -> void {
74 TryCloseHandle(handle);
75 };
76 uv_walk(ptrLoop, clearLoopTask, nullptr);
77 // If all processing ends, Then return0,this call will block
78 if (!ptrLoop->active_handles) {
79 ret = true;
80 break;
81 }
82 if (!uv_run(ptrLoop, UV_RUN_ONCE)) {
83 ret = true;
84 break;
85 }
86 } else {
87 ret = true;
88 break;
89 }
90 }
91 return ret;
92 }
93
FreeInstance()94 static void FreeInstance()
95 {
96 if (clsHdcJdwpSimulator) {
97 clsHdcJdwpSimulator->stop();
98 delete clsHdcJdwpSimulator;
99 clsHdcJdwpSimulator = nullptr;
100 }
101 uv_stop(&loopMain);
102 TryCloseLoop(&loopMain, "Hdcjdwp test exit");
103 HiLog::Info(LABEL, "jdwp_test_process exit.");
104 PrintMessage("jdwp_test_process exit.");
105 }
106
Stop(int signo)107 static void Stop(int signo)
108 {
109 FreeInstance();
110 _exit(0);
111 }
112
main(int argc,const char * argv[])113 int main(int argc, const char *argv[])
114 {
115 uv_loop_init(&loopMain);
116
117 HiLog::Info(LABEL, "jdwp_test_process start.");
118 PrintMessage("jdwp_test_process start.");
119 if (signal(SIGINT, Stop) == SIG_ERR) {
120 PrintMessage("jdwp_test_process signal fail.");
121 }
122 clsHdcJdwpSimulator = new HdcJdwpSimulator(&loopMain, "com.example.myapplication");
123 if (!clsHdcJdwpSimulator->Connect()) {
124 PrintMessage("Connect fail.");
125 return -1;
126 }
127 uv_run(&loopMain, UV_RUN_DEFAULT);
128
129 #ifdef JS_JDWP_CONNECT
130 PrintMessage("Enter 'exit' will stop the test.");
131 std::string line;
132 while (std::getline(std::cin, line)) {
133 if (!strcmp(line.c_str(), "exit")) {
134 PrintMessage("Exit current process.");
135 break;
136 }
137 }
138 FreeInstance();
139 #endif // JS_JDWP_CONNECT
140 return 0;
141 }