已合并
[PROFILING]msprof dynamic profiler support collection multi process at once #406
mei-feiyao创建于 2月7日
[PROFILING]msprof dynamic profiler support collection multi process at once #406
已合并
mei-feiyao创建于 2月7日
7 个文件变更+85-21
@@ -23,7 +23,7 @@ sockaddr_un LocalSocket::GetUnixSockAddr(const std::string &key)
23{23{
24 sockaddr_un sockAddr;24 sockaddr_un sockAddr;
25 (void)memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr));25 (void)memset_s(&sockAddr, sizeof(sockAddr), 0, sizeof(sockAddr));
26- auto ret = strcpy_s(sockAddr.sun_path + 1, sizeof(sockAddr.sun_path) - 1, key.c_str());26+ auto ret = strcpy_s(sockAddr.sun_path, sizeof(sockAddr.sun_path), key.c_str());
27 if (ret != EOK) {27 if (ret != EOK) {
28 MSPROF_LOGE("local socket path copy failed");28 MSPROF_LOGE("local socket path copy failed");
29 }29 }
@@ -43,6 +43,7 @@ int32_t LocalSocket::Create(const std::string &key, int32_t backlog)
43 return PROFILING_FAILED;43 return PROFILING_FAILED;
44 }44 }
45 45 
46+ OsalUnlink(key.c_str());
46 auto sockAddr = GetUnixSockAddr(key);47 auto sockAddr = GetUnixSockAddr(key);
47 auto ret = OsalBind(fd, reinterpret_cast<OsalSockAddr *>(&sockAddr),48 auto ret = OsalBind(fd, reinterpret_cast<OsalSockAddr *>(&sockAddr),
48 offsetof(sockaddr_un, sun_path) + 1 + key.size());49 offsetof(sockaddr_un, sun_path) + 1 + key.size());
@@ -52,6 +53,14 @@ int32_t LocalSocket::Create(const std::string &key, int32_t backlog)
52 return SOCKET_ERR_EADDRINUSE;53 return SOCKET_ERR_EADDRINUSE;
53 }54 }
54 MSPROF_LOGE("bind exception info: %s", Utils::GetErrno());55 MSPROF_LOGE("bind exception info: %s", Utils::GetErrno());
56+ OsalUnlink(key.c_str());
57+ Close(fd);
58+ return PROFILING_FAILED;
59+ }
60+ 
61+ if (OsalChmod(key.c_str(), S_IRUSR | S_IWUSR) != OSAL_EN_OK) {
62+ MSPROF_LOGE("chmod socket file %s failed: %s", key.c_str(), Utils::GetErrno());
63+ OsalUnlink(key.c_str());
55 Close(fd);64 Close(fd);
56 return PROFILING_FAILED;65 return PROFILING_FAILED;
57 }66 }
@@ -59,6 +68,7 @@ int32_t LocalSocket::Create(const std::string &key, int32_t backlog)
59 ret = OsalListen(fd, backlog);68 ret = OsalListen(fd, backlog);
60 if (ret != OSAL_EN_OK) {69 if (ret != OSAL_EN_OK) {
61 MSPROF_LOGE("listen exception info: %s", Utils::GetErrno());70 MSPROF_LOGE("listen exception info: %s", Utils::GetErrno());
71+ OsalUnlink(key.c_str());
62 Close(fd);72 Close(fd);
63 return PROFILING_FAILED;73 return PROFILING_FAILED;
64 }74 }
@@ -16,8 +16,11 @@
16namespace Collector {16namespace Collector {
17namespace Dvvp {17namespace Dvvp {
18namespace DynProf {18namespace DynProf {
19-static const std::string DYN_PROF_SOCK_UNIX_DOMAIN = "dyn_prof_sock_";19+static const std::string DYN_PROF_SOCK_UNIX_DOMAIN = "/dyn_prof_sock_";
20constexpr uint32_t DYN_PROF_PARAMS_MAX_LEN = 4096;20constexpr uint32_t DYN_PROF_PARAMS_MAX_LEN = 4096;
21+constexpr uint32_t DYN_PROF_MAX_ACCEPT_TIMES = 128;
22+constexpr uint32_t DYN_PROF_IDLE_LINK_HOLD_TIME = 1800; // 30 mins
23+constexpr uint32_t DYN_PROF_SERVER_PROC_MSG_MAX_NUM = 100;
21constexpr long DYN_PROF_PROC_TIME_OUT = 60;24constexpr long DYN_PROF_PROC_TIME_OUT = 60;
22 25 
23using ProcFunc = std::function<void()>;26using ProcFunc = std::function<void()>;
@@ -30,6 +33,7 @@ enum class DynProfMsgType {
30 DYN_PROF_STOP_RSQ,33 DYN_PROF_STOP_RSQ,
31 DYN_PROF_QUIT_REQ,34 DYN_PROF_QUIT_REQ,
32 DYN_PROF_QUIT_RSQ,35 DYN_PROF_QUIT_RSQ,
36+ DYN_PROF_DISCONNECT_RSQ,
33};37};
34 38 
35enum class DynProfMsgRsqCode {39enum class DynProfMsgRsqCode {
@@ -38,15 +38,18 @@ private:
38 int32_t DynProfSrvCreate();38 int32_t DynProfSrvCreate();
39 int32_t DynProfSrvRecvParams();39 int32_t DynProfSrvRecvParams();
40 void DynProfSrvRsqMsg(DynProfMsgType type, DynProfMsgRsqCode rsqCode) const;40 void DynProfSrvRsqMsg(DynProfMsgType type, DynProfMsgRsqCode rsqCode) const;
41- void DynProfSrvProc() const;41+ void DynProfSrvProc();
42 void DynProfSrvProcStart();42 void DynProfSrvProcStart();
43 void DynProfSrvProcStop();43 void DynProfSrvProcStop();
44 void DynProfSrvProcQuit();44 void DynProfSrvProcQuit();
45+ bool IdleConnectOverTime(uint32_t &recvIdleTimes) const;
46+ void NotifyClientDisconnect();
45 47 
46 int32_t srvSockFd_ { -1 };48 int32_t srvSockFd_ { -1 };
47 int32_t cliSockFd_ { -1 };49 int32_t cliSockFd_ { -1 };
48 bool srvStarted_ { false };50 bool srvStarted_ { false };
49 bool profStarted_ { false };51 bool profStarted_ { false };
52+ std::string socketPath_;
50 std::string dynProfParams_;53 std::string dynProfParams_;
51 std::map<DynProfMsgType, ProcFunc> procFuncMap_;54 std::map<DynProfMsgType, ProcFunc> procFuncMap_;
52 std::map<uint32_t, DynProfDeviceInfo> devicesInfo_;55 std::map<uint32_t, DynProfDeviceInfo> devicesInfo_;
@@ -54,8 +54,6 @@ int32_t DynProfServer::Stop()
54 MSPROF_LOGI("Dynamic profiling stop server.");54 MSPROF_LOGI("Dynamic profiling stop server.");
55 if (srvStarted_) {55 if (srvStarted_) {
56 srvStarted_ = false;56 srvStarted_ = false;
57- LocalSocket::Close(srvSockFd_);
58- LocalSocket::Close(cliSockFd_);
59 return Thread::Stop();57 return Thread::Stop();
60 }58 }
61 return PROFILING_SUCCESS;59 return PROFILING_SUCCESS;
@@ -71,15 +69,17 @@ void DynProfServer::Run(const struct error_message::Context &errorContext)
71{69{
72 MsprofErrorManager::instance()->SetErrorContext(errorContext);70 MsprofErrorManager::instance()->SetErrorContext(errorContext);
73 71 
74- while (srvStarted_) {72+ uint32_t acceptTime = 0;
73+ while (srvStarted_ && (acceptTime < DYN_PROF_MAX_ACCEPT_TIMES)) {
75 cliSockFd_ = LocalSocket::Accept(srvSockFd_);74 cliSockFd_ = LocalSocket::Accept(srvSockFd_);
76 if (cliSockFd_ == SOCKET_ERR_EAGAIN) {75 if (cliSockFd_ == SOCKET_ERR_EAGAIN) {
77 continue;76 continue;
78 }77 }
79 if (cliSockFd_ == PROFILING_FAILED) {78 if (cliSockFd_ == PROFILING_FAILED) {
80- MSPROF_LOGE("accept client failed.");79+ MSPROF_LOGE("accept client failed, cliSockFd_=%d, errno=%u.", cliSockFd_, errno);
81 break;80 break;
82 }81 }
82+ acceptTime++;
83 MSPROF_LOGI("accept client fd: %d", cliSockFd_);83 MSPROF_LOGI("accept client fd: %d", cliSockFd_);
84 if (LocalSocket::SetRecvTimeOut(cliSockFd_, 1, 0) == PROFILING_FAILED) {84 if (LocalSocket::SetRecvTimeOut(cliSockFd_, 1, 0) == PROFILING_FAILED) {
85 LocalSocket::Close(cliSockFd_);85 LocalSocket::Close(cliSockFd_);
@@ -95,6 +95,12 @@ void DynProfServer::Run(const struct error_message::Context &errorContext)
95 }95 }
96 DynProfSrvProc();96 DynProfSrvProc();
97 }97 }
98+ if (acceptTime >= DYN_PROF_MAX_ACCEPT_TIMES) {
99+ MSPROF_LOGW("accept client reach max times: %u.", acceptTime);
100+ }
101+ OsalUnlink(socketPath_.c_str());
102+ LocalSocket::Close(srvSockFd_);
103+ LocalSocket::Close(cliSockFd_);
98}104}
99 105 
100void DynProfServer::DynProfSrvInitProcFunc()106void DynProfServer::DynProfSrvInitProcFunc()
@@ -108,24 +114,23 @@ int32_t DynProfServer::DynProfSrvCreate()
108{114{
109 std::string appModeKeyPid;115 std::string appModeKeyPid;
110 MSPROF_GET_ENV(MM_ENV_DYNAMIC_PROFILING_KEY_PID, appModeKeyPid);116 MSPROF_GET_ENV(MM_ENV_DYNAMIC_PROFILING_KEY_PID, appModeKeyPid);
111- std::string key;
112 int32_t value = 0;117 int32_t value = 0;
113 if (!appModeKeyPid.empty() && !Utils::StrToInt32(value, appModeKeyPid)) {118 if (!appModeKeyPid.empty() && !Utils::StrToInt32(value, appModeKeyPid)) {
114 return PROFILING_FAILED;119 return PROFILING_FAILED;
115 }120 }
116 if (!appModeKeyPid.empty() && value > 0) {121 if (!appModeKeyPid.empty() && value > 0) {
117 // app mode --application122 // app mode --application
118- key = DYN_PROF_SOCK_UNIX_DOMAIN + appModeKeyPid;123+ socketPath_ = Utils::IdeGetHomedir() + DYN_PROF_SOCK_UNIX_DOMAIN + appModeKeyPid;
119- srvSockFd_ = LocalSocket::Create(key);124+ srvSockFd_ = LocalSocket::Create(socketPath_);
120 if (srvSockFd_ == SOCKET_ERR_EADDRINUSE) {125 if (srvSockFd_ == SOCKET_ERR_EADDRINUSE) {
121- MSPROF_LOGW("socket key %s already in use, try to create with app's pid.", key.c_str());126+ MSPROF_LOGW("socket key %s already in use, try to create with app's pid.", socketPath_.c_str());
122- key = DYN_PROF_SOCK_UNIX_DOMAIN + std::to_string(Utils::GetPid());127+ socketPath_ = Utils::IdeGetHomedir() + DYN_PROF_SOCK_UNIX_DOMAIN + std::to_string(Utils::GetPid());
123- srvSockFd_ = LocalSocket::Create(key);128+ srvSockFd_ = LocalSocket::Create(socketPath_);
124 }129 }
125 } else {130 } else {
126 // attach mode --pid131 // attach mode --pid
127- key = DYN_PROF_SOCK_UNIX_DOMAIN + std::to_string(Utils::GetPid());132+ socketPath_ = Utils::IdeGetHomedir() + DYN_PROF_SOCK_UNIX_DOMAIN + std::to_string(Utils::GetPid());
128- srvSockFd_ = LocalSocket::Create(key);133+ srvSockFd_ = LocalSocket::Create(socketPath_);
129 }134 }
130 if (srvSockFd_ < 0) {135 if (srvSockFd_ < 0) {
131 MSPROF_LOGE("create server failed.");136 MSPROF_LOGE("create server failed.");
@@ -136,7 +141,7 @@ int32_t DynProfServer::DynProfSrvCreate()
136 MSPROF_LOGE("set server recv time out failed.");141 MSPROF_LOGE("set server recv time out failed.");
137 return PROFILING_FAILED;142 return PROFILING_FAILED;
138 }143 }
139- MSPROF_LOGI("create server, key:%s, fd: %d.", key.c_str(), srvSockFd_);144+ MSPROF_LOGI("create server, socket:%s, fd:%d.", socketPath_.c_str(), srvSockFd_);
140 return PROFILING_SUCCESS;145 return PROFILING_SUCCESS;
141}146}
142 147 
@@ -170,15 +175,32 @@ void DynProfServer::DynProfSrvRsqMsg(DynProfMsgType type, DynProfMsgRsqCode rsqC
170 MSPROF_LOGI("server send rsq: %d,%d", type, rsqCode);175 MSPROF_LOGI("server send rsq: %d,%d", type, rsqCode);
171}176}
172 177 
173-void DynProfServer::DynProfSrvProc() const178+bool DynProfServer::IdleConnectOverTime(uint32_t &recvIdleTimes) const
174{179{
180+ if (profStarted_) {
181+ return false;
182+ }
183+ if (++recvIdleTimes <= DYN_PROF_IDLE_LINK_HOLD_TIME) {
184+ return false;
185+ }
186+ return true;
187+}
188+ 
189+void DynProfServer::DynProfSrvProc()
190+{
191+ uint32_t recvIdleTimes = 0;
192+ uint32_t recvMsgNum = 0;
175 while (srvStarted_) {193 while (srvStarted_) {
176 DynProfMsg reqMsg;194 DynProfMsg reqMsg;
177 const auto recvLen = LocalSocket::Recv(cliSockFd_, &(reqMsg), sizeof(reqMsg), 0);195 const auto recvLen = LocalSocket::Recv(cliSockFd_, &(reqMsg), sizeof(reqMsg), 0);
178- if (recvLen == SOCKET_ERR_EAGAIN) {196+ if (static_cast<size_t>(recvLen) != sizeof(reqMsg) && recvLen == SOCKET_ERR_EAGAIN) {
197+ if (IdleConnectOverTime(recvIdleTimes)) {
198+ MSPROF_LOGW("server disconnect client, recvIdleTimes=%u.", recvIdleTimes);
199+ break;
200+ }
179 continue;201 continue;
180 }202 }
181- if (recvLen != sizeof(reqMsg)) {203+ if (static_cast<size_t>(recvLen) != sizeof(reqMsg)) {
182 MSPROF_LOGE("recv client cmd failed");204 MSPROF_LOGE("recv client cmd failed");
183 break;205 break;
184 }206 }
@@ -192,7 +214,12 @@ void DynProfServer::DynProfSrvProc() const
192 if (reqMsg.msgType == DynProfMsgType::DYN_PROF_QUIT_REQ) {214 if (reqMsg.msgType == DynProfMsgType::DYN_PROF_QUIT_REQ) {
193 break;215 break;
194 }216 }
217+ if (++recvMsgNum > DYN_PROF_SERVER_PROC_MSG_MAX_NUM) {
218+ MSPROF_LOGW("server receive message over %u.", recvMsgNum);
219+ break;
220+ }
195 }221 }
222+ NotifyClientDisconnect();
196}223}
197 224 
198void DynProfServer::DynProfSrvProcStart()225void DynProfServer::DynProfSrvProcStart()
@@ -283,6 +310,12 @@ void DynProfServer::DynProfSrvProcQuit()
283 MSPROF_LOGI("Dynamic profiling quit message process success.");310 MSPROF_LOGI("Dynamic profiling quit message process success.");
284}311}
285 312 
313+void DynProfServer::NotifyClientDisconnect()
314+{
315+ DynProfSrvRsqMsg(DynProfMsgType::DYN_PROF_DISCONNECT_RSQ, DynProfMsgRsqCode::DYN_PROF_RSQ_SUCCESS);
316+ DynProfSrvProcQuit();
317+}
318+ 
286void DynProfServer::SaveDevicesInfo(DynProfDeviceInfo data)319void DynProfServer::SaveDevicesInfo(DynProfDeviceInfo data)
287{320{
288 std::unique_lock<std::mutex> devLk(devInfoMtx_);321 std::unique_lock<std::mutex> devLk(devInfoMtx_);
@@ -58,11 +58,16 @@ TEST_F(LOCAL_SOCKET_UTEST, LocalSocket_Create) {
58 EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);58 EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);
59 EXPECT_EQ(LocalSocket::Create(key, backlog), SOCKET_ERR_EADDRINUSE);59 EXPECT_EQ(LocalSocket::Create(key, backlog), SOCKET_ERR_EADDRINUSE);
60 60 
61+ MOCKER(mmChmod)
62+ .stubs()
63+ .will(returnValue(EN_ERROR))
64+ .then(returnValue(EN_OK));
61 MOCKER(mmListen)65 MOCKER(mmListen)
62 .stubs()66 .stubs()
63 .will(returnValue(EN_ERROR))67 .will(returnValue(EN_ERROR))
64 .then(returnValue(EN_OK));68 .then(returnValue(EN_OK));
65 EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);69 EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);
70+ EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);
66 71 
67 EXPECT_EQ(LocalSocket::Create(key, backlog), EN_OK);72 EXPECT_EQ(LocalSocket::Create(key, backlog), EN_OK);
68}73}
@@ -62,12 +62,16 @@ TEST_F(LOCAL_SOCKET_STEST, LocalSocket_create)
62 ret = localSocket->Create(key, backlog);62 ret = localSocket->Create(key, backlog);
63 EXPECT_EQ(ret, PROFILING_FAILED);63 EXPECT_EQ(ret, PROFILING_FAILED);
64 64 
65+ MOCKER(mmChmod)
66+ .stubs()
67+ .will(returnValue(EN_ERROR))
68+ .then(returnValue(EN_OK));
65 MOCKER(mmListen)69 MOCKER(mmListen)
66 .stubs()70 .stubs()
67 .will(returnValue(EN_ERROR))71 .will(returnValue(EN_ERROR))
68 .then(returnValue(EN_OK));72 .then(returnValue(EN_OK));
69- ret = localSocket->Create(key, backlog);73+ EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);
70- EXPECT_EQ(ret, PROFILING_FAILED);74+ EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);
71 75 
72 ret = localSocket->Create(key, backlog);76 ret = localSocket->Create(key, backlog);
73 EXPECT_EQ(ret, EN_OK);77 EXPECT_EQ(ret, EN_OK);
@@ -58,11 +58,16 @@ TEST_F(LOCAL_SOCKET_UTEST, LocalSocket_Create) {
58 EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);58 EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);
59 EXPECT_EQ(LocalSocket::Create(key, backlog), SOCKET_ERR_EADDRINUSE);59 EXPECT_EQ(LocalSocket::Create(key, backlog), SOCKET_ERR_EADDRINUSE);
60 60 
61+ MOCKER(mmChmod)
62+ .stubs()
63+ .will(returnValue(EN_ERROR))
64+ .then(returnValue(EN_OK));
61 MOCKER(mmListen)65 MOCKER(mmListen)
62 .stubs()66 .stubs()
63 .will(returnValue(EN_ERROR))67 .will(returnValue(EN_ERROR))
64 .then(returnValue(EN_OK));68 .then(returnValue(EN_OK));
65 EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);69 EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);
70+ EXPECT_EQ(LocalSocket::Create(key, backlog), PROFILING_FAILED);
66 71 
67 EXPECT_EQ(LocalSocket::Create(key, backlog), EN_OK);72 EXPECT_EQ(LocalSocket::Create(key, backlog), EN_OK);
68}73}