1800b99b8Sopenharmony_ci/* 2800b99b8Sopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3800b99b8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4800b99b8Sopenharmony_ci * you may not use this file except in compliance with the License. 5800b99b8Sopenharmony_ci * You may obtain a copy of the License at 6800b99b8Sopenharmony_ci * 7800b99b8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8800b99b8Sopenharmony_ci * 9800b99b8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10800b99b8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11800b99b8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12800b99b8Sopenharmony_ci * See the License for the specific language governing permissions and 13800b99b8Sopenharmony_ci * limitations under the License. 14800b99b8Sopenharmony_ci */ 15800b99b8Sopenharmony_ci 16800b99b8Sopenharmony_ci#include "fault_logger_daemon.h" 17800b99b8Sopenharmony_ci 18800b99b8Sopenharmony_ci#include <algorithm> 19800b99b8Sopenharmony_ci#include <cerrno> 20800b99b8Sopenharmony_ci#include <csignal> 21800b99b8Sopenharmony_ci#include <cstring> 22800b99b8Sopenharmony_ci#include <ctime> 23800b99b8Sopenharmony_ci#include <dirent.h> 24800b99b8Sopenharmony_ci#include <fcntl.h> 25800b99b8Sopenharmony_ci#include <fstream> 26800b99b8Sopenharmony_ci#include <securec.h> 27800b99b8Sopenharmony_ci#include <sstream> 28800b99b8Sopenharmony_ci#include <unistd.h> 29800b99b8Sopenharmony_ci#include <vector> 30800b99b8Sopenharmony_ci 31800b99b8Sopenharmony_ci#include <sys/epoll.h> 32800b99b8Sopenharmony_ci#include <sys/socket.h> 33800b99b8Sopenharmony_ci#include <sys/stat.h> 34800b99b8Sopenharmony_ci#include <sys/syscall.h> 35800b99b8Sopenharmony_ci#include <sys/types.h> 36800b99b8Sopenharmony_ci#include <sys/un.h> 37800b99b8Sopenharmony_ci#include <sys/wait.h> 38800b99b8Sopenharmony_ci 39800b99b8Sopenharmony_ci#include "dfx_define.h" 40800b99b8Sopenharmony_ci#include "dfx_exception.h" 41800b99b8Sopenharmony_ci#include "dfx_log.h" 42800b99b8Sopenharmony_ci#include "dfx_trace.h" 43800b99b8Sopenharmony_ci#include "dfx_util.h" 44800b99b8Sopenharmony_ci#include "string_printf.h" 45800b99b8Sopenharmony_ci#include "directory_ex.h" 46800b99b8Sopenharmony_ci#include "fault_logger_config.h" 47800b99b8Sopenharmony_ci#include "faultloggerd_socket.h" 48800b99b8Sopenharmony_ci#ifndef is_ohos_lite 49800b99b8Sopenharmony_ci#include "parameters.h" 50800b99b8Sopenharmony_ci#endif 51800b99b8Sopenharmony_ci#ifndef HISYSEVENT_DISABLE 52800b99b8Sopenharmony_ci#include "hisysevent.h" 53800b99b8Sopenharmony_ci#endif 54800b99b8Sopenharmony_ci 55800b99b8Sopenharmony_cinamespace OHOS { 56800b99b8Sopenharmony_cinamespace HiviewDFX { 57800b99b8Sopenharmony_cistd::shared_ptr<FaultLoggerConfig> faultLoggerConfig_; 58800b99b8Sopenharmony_cistd::shared_ptr<FaultLoggerPipeMap> faultLoggerPipeMap_; 59800b99b8Sopenharmony_ci 60800b99b8Sopenharmony_cinamespace { 61800b99b8Sopenharmony_ciconstexpr int32_t MAX_CONNECTION = 30; 62800b99b8Sopenharmony_ciconstexpr int32_t REQUEST_BUF_SIZE = 2048; 63800b99b8Sopenharmony_ciconstexpr int32_t MAX_EPOLL_EVENT = 1024; 64800b99b8Sopenharmony_ciconst int32_t FAULTLOG_FILE_PROP = 0640; 65800b99b8Sopenharmony_ci 66800b99b8Sopenharmony_cistatic constexpr uint32_t ROOT_UID = 0; 67800b99b8Sopenharmony_cistatic constexpr uint32_t BMS_UID = 1000; 68800b99b8Sopenharmony_cistatic constexpr uint32_t HIVIEW_UID = 1201; 69800b99b8Sopenharmony_cistatic constexpr uint32_t HIDUMPER_SERVICE_UID = 1212; 70800b99b8Sopenharmony_cistatic constexpr uint32_t FOUNDATION_UID = 5523; 71800b99b8Sopenharmony_cistatic const std::string FAULTLOGGERD_TAG = "FaultLoggerd"; 72800b99b8Sopenharmony_cistatic const std::string DAEMON_RESP = "RESP:COMPLETE"; 73800b99b8Sopenharmony_cistatic const int DAEMON_REMOVE_FILE_TIME_S = 60; 74800b99b8Sopenharmony_ci 75800b99b8Sopenharmony_cistatic std::string GetRequestTypeName(int32_t type) 76800b99b8Sopenharmony_ci{ 77800b99b8Sopenharmony_ci switch (type) { 78800b99b8Sopenharmony_ci case (int32_t)FaultLoggerType::CPP_CRASH: 79800b99b8Sopenharmony_ci return "cppcrash"; 80800b99b8Sopenharmony_ci case (int32_t)FaultLoggerType::CPP_STACKTRACE: // change the name to nativestack ? 81800b99b8Sopenharmony_ci return "stacktrace"; 82800b99b8Sopenharmony_ci case (int32_t)FaultLoggerType::JS_STACKTRACE: 83800b99b8Sopenharmony_ci return "jsstack"; 84800b99b8Sopenharmony_ci case (int32_t)FaultLoggerType::JS_HEAP_SNAPSHOT: 85800b99b8Sopenharmony_ci case (int32_t)FaultLoggerType::JS_RAW_SNAPSHOT: 86800b99b8Sopenharmony_ci return "jsheap"; 87800b99b8Sopenharmony_ci case (int32_t)FaultLoggerType::JS_HEAP_LEAK_LIST: 88800b99b8Sopenharmony_ci return "leaklist"; 89800b99b8Sopenharmony_ci case (int32_t)FaultLoggerType::LEAK_STACKTRACE: 90800b99b8Sopenharmony_ci return "leakstack"; 91800b99b8Sopenharmony_ci case (int32_t)FaultLoggerType::FFRT_CRASH_LOG: 92800b99b8Sopenharmony_ci return "ffrtlog"; 93800b99b8Sopenharmony_ci case (int32_t)FaultLoggerType::JIT_CODE_LOG: 94800b99b8Sopenharmony_ci return "jitcode"; 95800b99b8Sopenharmony_ci default: 96800b99b8Sopenharmony_ci return "unsupported"; 97800b99b8Sopenharmony_ci } 98800b99b8Sopenharmony_ci} 99800b99b8Sopenharmony_ci 100800b99b8Sopenharmony_cistatic bool CheckCallerUID(uint32_t callerUid) 101800b99b8Sopenharmony_ci{ 102800b99b8Sopenharmony_ci // If caller's is BMS / root or caller's uid/pid is validate, just return true 103800b99b8Sopenharmony_ci if ((callerUid == BMS_UID) || 104800b99b8Sopenharmony_ci (callerUid == ROOT_UID) || 105800b99b8Sopenharmony_ci (callerUid == HIVIEW_UID) || 106800b99b8Sopenharmony_ci (callerUid == HIDUMPER_SERVICE_UID) || 107800b99b8Sopenharmony_ci (callerUid == FOUNDATION_UID)) { 108800b99b8Sopenharmony_ci return true; 109800b99b8Sopenharmony_ci } 110800b99b8Sopenharmony_ci DFXLOGW("%{public}s :: CheckCallerUID :: Caller Uid(%{public}d) is unexpectly.\n", 111800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), callerUid); 112800b99b8Sopenharmony_ci return false; 113800b99b8Sopenharmony_ci} 114800b99b8Sopenharmony_ci} 115800b99b8Sopenharmony_ci 116800b99b8Sopenharmony_cistatic void ReportExceptionToSysEvent(CrashDumpException& exception) 117800b99b8Sopenharmony_ci{ 118800b99b8Sopenharmony_ci#ifndef HISYSEVENT_DISABLE 119800b99b8Sopenharmony_ci std::string errMessage; 120800b99b8Sopenharmony_ci if (exception.error == CRASH_DUMP_LOCAL_REPORT) { 121800b99b8Sopenharmony_ci std::ifstream rfile; 122800b99b8Sopenharmony_ci if (strlen(exception.message) == 0) { 123800b99b8Sopenharmony_ci return; 124800b99b8Sopenharmony_ci } 125800b99b8Sopenharmony_ci rfile.open(exception.message, std::ios::binary | std::ios::ate); 126800b99b8Sopenharmony_ci if (!rfile.is_open()) { 127800b99b8Sopenharmony_ci return; 128800b99b8Sopenharmony_ci } 129800b99b8Sopenharmony_ci std::streamsize size = rfile.tellg(); 130800b99b8Sopenharmony_ci rfile.seekg(0, std::ios::beg); 131800b99b8Sopenharmony_ci std::vector<char> buf(size); 132800b99b8Sopenharmony_ci rfile.read(buf.data(), size); 133800b99b8Sopenharmony_ci errMessage = std::string(buf.begin(), buf.end()); 134800b99b8Sopenharmony_ci } else { 135800b99b8Sopenharmony_ci errMessage = exception.message; 136800b99b8Sopenharmony_ci } 137800b99b8Sopenharmony_ci HiSysEventWrite( 138800b99b8Sopenharmony_ci HiSysEvent::Domain::RELIABILITY, 139800b99b8Sopenharmony_ci "CPP_CRASH_EXCEPTION", 140800b99b8Sopenharmony_ci HiSysEvent::EventType::FAULT, 141800b99b8Sopenharmony_ci "PID", exception.pid, 142800b99b8Sopenharmony_ci "UID", exception.uid, 143800b99b8Sopenharmony_ci "HAPPEN_TIME", exception.time, 144800b99b8Sopenharmony_ci "ERROR_CODE", exception.error, 145800b99b8Sopenharmony_ci "ERROR_MSG", errMessage); 146800b99b8Sopenharmony_ci#endif 147800b99b8Sopenharmony_ci} 148800b99b8Sopenharmony_ci 149800b99b8Sopenharmony_ciFaultLoggerDaemon::FaultLoggerDaemon() 150800b99b8Sopenharmony_ci{ 151800b99b8Sopenharmony_ci#ifndef is_ohos_lite 152800b99b8Sopenharmony_ci isBeta_ = OHOS::system::GetParameter("const.logsystem.versiontype", "false") == "beta"; 153800b99b8Sopenharmony_ci#endif 154800b99b8Sopenharmony_ci} 155800b99b8Sopenharmony_ci 156800b99b8Sopenharmony_ciint32_t FaultLoggerDaemon::StartServer() 157800b99b8Sopenharmony_ci{ 158800b99b8Sopenharmony_ci if (!CreateSockets()) { 159800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to create faultloggerd sockets.", FAULTLOGGERD_TAG.c_str()); 160800b99b8Sopenharmony_ci CleanupSockets(); 161800b99b8Sopenharmony_ci return -1; 162800b99b8Sopenharmony_ci } 163800b99b8Sopenharmony_ci 164800b99b8Sopenharmony_ci if (!InitEnvironment()) { 165800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to init environment.", FAULTLOGGERD_TAG.c_str()); 166800b99b8Sopenharmony_ci CleanupSockets(); 167800b99b8Sopenharmony_ci return -1; 168800b99b8Sopenharmony_ci } 169800b99b8Sopenharmony_ci 170800b99b8Sopenharmony_ci if (!CreateEventFd()) { 171800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to create eventFd.", FAULTLOGGERD_TAG.c_str()); 172800b99b8Sopenharmony_ci CleanupSockets(); 173800b99b8Sopenharmony_ci return -1; 174800b99b8Sopenharmony_ci } 175800b99b8Sopenharmony_ci RemoveTempFileIfNeed(); 176800b99b8Sopenharmony_ci // loop in WaitForRequest 177800b99b8Sopenharmony_ci WaitForRequest(); 178800b99b8Sopenharmony_ci CleanupEventFd(); 179800b99b8Sopenharmony_ci CleanupSockets(); 180800b99b8Sopenharmony_ci return 0; 181800b99b8Sopenharmony_ci} 182800b99b8Sopenharmony_ci 183800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleAccept(int32_t epollFd, int32_t socketFd) 184800b99b8Sopenharmony_ci{ 185800b99b8Sopenharmony_ci DFX_TRACE_SCOPED("HandleAccept"); 186800b99b8Sopenharmony_ci struct sockaddr_un clientAddr; 187800b99b8Sopenharmony_ci socklen_t clientAddrSize = static_cast<socklen_t>(sizeof(clientAddr)); 188800b99b8Sopenharmony_ci 189800b99b8Sopenharmony_ci int connectionFd = OHOS_TEMP_FAILURE_RETRY(accept(socketFd, 190800b99b8Sopenharmony_ci reinterpret_cast<struct sockaddr *>(&clientAddr), &clientAddrSize)); 191800b99b8Sopenharmony_ci if (connectionFd < 0) { 192800b99b8Sopenharmony_ci DFXLOGW("%{public}s :: Failed to accept connection", FAULTLOGGERD_TAG.c_str()); 193800b99b8Sopenharmony_ci return; 194800b99b8Sopenharmony_ci } 195800b99b8Sopenharmony_ci 196800b99b8Sopenharmony_ci AddEvent(eventFd_, connectionFd, EPOLLIN); 197800b99b8Sopenharmony_ci connectionMap_[connectionFd] = socketFd; 198800b99b8Sopenharmony_ci} 199800b99b8Sopenharmony_ci 200800b99b8Sopenharmony_ci#ifdef FAULTLOGGERD_FUZZER 201800b99b8Sopenharmony_cibool FaultLoggerDaemon::HandleStaticForFuzzer(int32_t type, uint32_t callerUid) 202800b99b8Sopenharmony_ci{ 203800b99b8Sopenharmony_ci std::string str = GetRequestTypeName(type); 204800b99b8Sopenharmony_ci bool ret = CheckCallerUID(callerUid); 205800b99b8Sopenharmony_ci if (str == "unsupported" || !ret) { 206800b99b8Sopenharmony_ci return false; 207800b99b8Sopenharmony_ci } else { 208800b99b8Sopenharmony_ci return true; 209800b99b8Sopenharmony_ci } 210800b99b8Sopenharmony_ci} 211800b99b8Sopenharmony_ci 212800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleRequestForFuzzer(int32_t epollFd, int32_t connectionFd, 213800b99b8Sopenharmony_ci const FaultLoggerdRequest *requestConst, FaultLoggerdRequest *request) 214800b99b8Sopenharmony_ci{ 215800b99b8Sopenharmony_ci if (faultLoggerConfig_ == nullptr) { 216800b99b8Sopenharmony_ci faultLoggerConfig_ = std::make_shared<FaultLoggerConfig>(LOG_FILE_NUMBER, LOG_FILE_SIZE, 217800b99b8Sopenharmony_ci LOG_FILE_PATH, DEBUG_LOG_FILE_PATH); 218800b99b8Sopenharmony_ci } 219800b99b8Sopenharmony_ci HandleRequest(epollFd, connectionFd); 220800b99b8Sopenharmony_ci HandleLogFileDesClientRequest(connectionFd, requestConst); 221800b99b8Sopenharmony_ci HandlePrintTHilogClientRequest(connectionFd, request); 222800b99b8Sopenharmony_ci HandlePermissionRequest(connectionFd, request); 223800b99b8Sopenharmony_ci HandleSdkDumpRequest(connectionFd, request); 224800b99b8Sopenharmony_ci HandleExceptionRequest(connectionFd, request); 225800b99b8Sopenharmony_ci} 226800b99b8Sopenharmony_ci#endif 227800b99b8Sopenharmony_ci 228800b99b8Sopenharmony_cistatic bool CheckReadRequest(ssize_t nread, ssize_t size) 229800b99b8Sopenharmony_ci{ 230800b99b8Sopenharmony_ci if (nread < 0) { 231800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to read message", FAULTLOGGERD_TAG.c_str()); 232800b99b8Sopenharmony_ci return false; 233800b99b8Sopenharmony_ci } else if (nread == 0) { 234800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Read null from request socket", FAULTLOGGERD_TAG.c_str()); 235800b99b8Sopenharmony_ci return false; 236800b99b8Sopenharmony_ci } else if (nread != static_cast<long>(size)) { 237800b99b8Sopenharmony_ci return false; 238800b99b8Sopenharmony_ci } 239800b99b8Sopenharmony_ci return true; 240800b99b8Sopenharmony_ci} 241800b99b8Sopenharmony_ci 242800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleRequestByClientType(int32_t connectionFd, FaultLoggerdRequest* request) 243800b99b8Sopenharmony_ci{ 244800b99b8Sopenharmony_ci switch (request->clientType) { 245800b99b8Sopenharmony_ci case static_cast<int32_t>(FaultLoggerClientType::DEFAULT_CLIENT): 246800b99b8Sopenharmony_ci HandleDefaultClientRequest(connectionFd, request); 247800b99b8Sopenharmony_ci break; 248800b99b8Sopenharmony_ci case static_cast<int32_t>(FaultLoggerClientType::LOG_FILE_DES_CLIENT): 249800b99b8Sopenharmony_ci HandleLogFileDesClientRequest(connectionFd, request); 250800b99b8Sopenharmony_ci break; 251800b99b8Sopenharmony_ci case static_cast<int32_t>(FaultLoggerClientType::PRINT_T_HILOG_CLIENT): 252800b99b8Sopenharmony_ci HandlePrintTHilogClientRequest(connectionFd, request); 253800b99b8Sopenharmony_ci break; 254800b99b8Sopenharmony_ci case static_cast<int32_t>(FaultLoggerClientType::PERMISSION_CLIENT): 255800b99b8Sopenharmony_ci HandlePermissionRequest(connectionFd, request); 256800b99b8Sopenharmony_ci break; 257800b99b8Sopenharmony_ci case static_cast<int32_t>(FaultLoggerClientType::SDK_DUMP_CLIENT): 258800b99b8Sopenharmony_ci HandleSdkDumpRequest(connectionFd, request); 259800b99b8Sopenharmony_ci break; 260800b99b8Sopenharmony_ci case static_cast<int32_t>(FaultLoggerClientType::PIPE_FD_CLIENT): 261800b99b8Sopenharmony_ci HandlePipeFdClientRequest(connectionFd, request); 262800b99b8Sopenharmony_ci break; 263800b99b8Sopenharmony_ci case static_cast<int32_t>(FaultLoggerClientType::REPORT_EXCEPTION_CLIENT): 264800b99b8Sopenharmony_ci HandleExceptionRequest(connectionFd, request); 265800b99b8Sopenharmony_ci break; 266800b99b8Sopenharmony_ci default: 267800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: unknown clientType(%{public}d).\n", FAULTLOGGERD_TAG.c_str(), request->clientType); 268800b99b8Sopenharmony_ci break; 269800b99b8Sopenharmony_ci } 270800b99b8Sopenharmony_ci} 271800b99b8Sopenharmony_ci 272800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleRequest(int32_t epollFd, int32_t connectionFd) 273800b99b8Sopenharmony_ci{ 274800b99b8Sopenharmony_ci if (epollFd < 0 || connectionFd < 3) { // 3: not allow fd = 0,1,2 because they are reserved by system 275800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: HandleRequest recieved invalid fd parmeters.", FAULTLOGGERD_TAG.c_str()); 276800b99b8Sopenharmony_ci return; 277800b99b8Sopenharmony_ci } 278800b99b8Sopenharmony_ci 279800b99b8Sopenharmony_ci std::vector<uint8_t> buf(REQUEST_BUF_SIZE, 0); 280800b99b8Sopenharmony_ci do { 281800b99b8Sopenharmony_ci ssize_t nread = OHOS_TEMP_FAILURE_RETRY(read(connectionFd, buf.data(), REQUEST_BUF_SIZE)); 282800b99b8Sopenharmony_ci if (CheckReadRequest(nread, sizeof(FaultLoggerdStatsRequest))) { 283800b99b8Sopenharmony_ci HandleDumpStats(connectionFd, reinterpret_cast<FaultLoggerdStatsRequest *>(buf.data())); 284800b99b8Sopenharmony_ci break; 285800b99b8Sopenharmony_ci } 286800b99b8Sopenharmony_ci if (!CheckReadRequest(nread, sizeof(FaultLoggerdRequest))) { 287800b99b8Sopenharmony_ci break; 288800b99b8Sopenharmony_ci } 289800b99b8Sopenharmony_ci auto request = reinterpret_cast<FaultLoggerdRequest *>(buf.data()); 290800b99b8Sopenharmony_ci if (!CheckRequestCredential(connectionFd, request)) { 291800b99b8Sopenharmony_ci break; 292800b99b8Sopenharmony_ci } 293800b99b8Sopenharmony_ci DFXLOGD("%{public}s :: clientType(%{public}d).", FAULTLOGGERD_TAG.c_str(), request->clientType); 294800b99b8Sopenharmony_ci HandleRequestByClientType(connectionFd, request); 295800b99b8Sopenharmony_ci } while (false); 296800b99b8Sopenharmony_ci DelEvent(eventFd_, connectionFd, EPOLLIN); 297800b99b8Sopenharmony_ci connectionMap_.erase(connectionFd); 298800b99b8Sopenharmony_ci} 299800b99b8Sopenharmony_ci 300800b99b8Sopenharmony_cibool FaultLoggerDaemon::InitEnvironment() 301800b99b8Sopenharmony_ci{ 302800b99b8Sopenharmony_ci faultLoggerConfig_ = std::make_shared<FaultLoggerConfig>(LOG_FILE_NUMBER, LOG_FILE_SIZE, 303800b99b8Sopenharmony_ci LOG_FILE_PATH, DEBUG_LOG_FILE_PATH); 304800b99b8Sopenharmony_ci faultLoggerPipeMap_ = std::make_shared<FaultLoggerPipeMap>(); 305800b99b8Sopenharmony_ci 306800b99b8Sopenharmony_ci if (!OHOS::ForceCreateDirectory(faultLoggerConfig_->GetLogFilePath())) { 307800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to ForceCreateDirectory GetLogFilePath", FAULTLOGGERD_TAG.c_str()); 308800b99b8Sopenharmony_ci return false; 309800b99b8Sopenharmony_ci } 310800b99b8Sopenharmony_ci 311800b99b8Sopenharmony_ci signal(SIGCHLD, SIG_IGN); 312800b99b8Sopenharmony_ci signal(SIGPIPE, SIG_IGN); 313800b99b8Sopenharmony_ci return true; 314800b99b8Sopenharmony_ci} 315800b99b8Sopenharmony_ci 316800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleDefaultClientRequest(int32_t connectionFd, const FaultLoggerdRequest * request) 317800b99b8Sopenharmony_ci{ 318800b99b8Sopenharmony_ci DFX_TRACE_SCOPED("HandleDefaultClientRequest"); 319800b99b8Sopenharmony_ci int fd = CreateFileForRequest(request->type, request->pid, request->tid, request->time); 320800b99b8Sopenharmony_ci if (fd < 0) { 321800b99b8Sopenharmony_ci DFXLOGE("[%{public}d]: %{public}s :: Failed to create log file, errno(%{public}d)", __LINE__, 322800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), errno); 323800b99b8Sopenharmony_ci return; 324800b99b8Sopenharmony_ci } 325800b99b8Sopenharmony_ci RecordFileCreation(request->type, request->pid); 326800b99b8Sopenharmony_ci SendFileDescriptorToSocket(connectionFd, fd); 327800b99b8Sopenharmony_ci 328800b99b8Sopenharmony_ci close(fd); 329800b99b8Sopenharmony_ci} 330800b99b8Sopenharmony_ci 331800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleLogFileDesClientRequest(int32_t connectionFd, const FaultLoggerdRequest * request) 332800b99b8Sopenharmony_ci{ 333800b99b8Sopenharmony_ci int fd = CreateFileForRequest(request->type, request->pid, request->tid, request->time); 334800b99b8Sopenharmony_ci if (fd < 0) { 335800b99b8Sopenharmony_ci DFXLOGE("[%{public}d]: %{public}s :: Failed to create log file, errno(%{public}d)", __LINE__, 336800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), errno); 337800b99b8Sopenharmony_ci return; 338800b99b8Sopenharmony_ci } 339800b99b8Sopenharmony_ci SendFileDescriptorToSocket(connectionFd, fd); 340800b99b8Sopenharmony_ci 341800b99b8Sopenharmony_ci close(fd); 342800b99b8Sopenharmony_ci} 343800b99b8Sopenharmony_ci 344800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleExceptionRequest(int32_t connectionFd, FaultLoggerdRequest * request) 345800b99b8Sopenharmony_ci{ 346800b99b8Sopenharmony_ci if (OHOS_TEMP_FAILURE_RETRY(write(connectionFd, 347800b99b8Sopenharmony_ci DAEMON_RESP.c_str(), DAEMON_RESP.length())) != static_cast<ssize_t>(DAEMON_RESP.length())) { 348800b99b8Sopenharmony_ci DFXLOGE("[%{public}d]: %{public}s :: Failed to write DAEMON_RESP.", __LINE__, FAULTLOGGERD_TAG.c_str()); 349800b99b8Sopenharmony_ci } 350800b99b8Sopenharmony_ci 351800b99b8Sopenharmony_ci CrashDumpException exception; 352800b99b8Sopenharmony_ci (void)memset_s(&exception, sizeof(CrashDumpException), 0, sizeof(CrashDumpException)); 353800b99b8Sopenharmony_ci ssize_t nread = OHOS_TEMP_FAILURE_RETRY(read(connectionFd, &exception, sizeof(CrashDumpException))); 354800b99b8Sopenharmony_ci exception.message[LINE_BUF_SIZE - 1] = '\0'; 355800b99b8Sopenharmony_ci if (!CheckReadRequest(nread, sizeof(CrashDumpException))) { 356800b99b8Sopenharmony_ci return; 357800b99b8Sopenharmony_ci } 358800b99b8Sopenharmony_ci 359800b99b8Sopenharmony_ci ReportExceptionToSysEvent(exception); 360800b99b8Sopenharmony_ci} 361800b99b8Sopenharmony_ci 362800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleReadBuf(int& fd, int32_t connectionFd, FaultLoggerdRequest* request, 363800b99b8Sopenharmony_ci FaultLoggerPipe2* faultLoggerPipe) 364800b99b8Sopenharmony_ci{ 365800b99b8Sopenharmony_ci FaultLoggerCheckPermissionResp resSecurityCheck = SecurityCheck(connectionFd, request); 366800b99b8Sopenharmony_ci if (FaultLoggerCheckPermissionResp::CHECK_PERMISSION_PASS != resSecurityCheck) { 367800b99b8Sopenharmony_ci return; 368800b99b8Sopenharmony_ci } 369800b99b8Sopenharmony_ci if ((faultLoggerPipe->faultLoggerPipeBuf_) != nullptr) { 370800b99b8Sopenharmony_ci fd = faultLoggerPipe->faultLoggerPipeBuf_->GetReadFd(); 371800b99b8Sopenharmony_ci } 372800b99b8Sopenharmony_ci} 373800b99b8Sopenharmony_ci 374800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleWriteBuf(int& fd, FaultLoggerPipe2* faultLoggerPipe) 375800b99b8Sopenharmony_ci{ 376800b99b8Sopenharmony_ci if ((faultLoggerPipe->faultLoggerPipeBuf_) != nullptr) { 377800b99b8Sopenharmony_ci fd = faultLoggerPipe->faultLoggerPipeBuf_->GetWriteFd(); 378800b99b8Sopenharmony_ci } 379800b99b8Sopenharmony_ci} 380800b99b8Sopenharmony_ci 381800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleReadRes(int& fd, int32_t connectionFd, FaultLoggerdRequest* request, 382800b99b8Sopenharmony_ci FaultLoggerPipe2* faultLoggerPipe) 383800b99b8Sopenharmony_ci{ 384800b99b8Sopenharmony_ci FaultLoggerCheckPermissionResp resSecurityCheck = SecurityCheck(connectionFd, request); 385800b99b8Sopenharmony_ci if (FaultLoggerCheckPermissionResp::CHECK_PERMISSION_PASS != resSecurityCheck) { 386800b99b8Sopenharmony_ci return; 387800b99b8Sopenharmony_ci } 388800b99b8Sopenharmony_ci if ((faultLoggerPipe->faultLoggerPipeRes_) != nullptr) { 389800b99b8Sopenharmony_ci fd = faultLoggerPipe->faultLoggerPipeRes_->GetReadFd(); 390800b99b8Sopenharmony_ci } 391800b99b8Sopenharmony_ci} 392800b99b8Sopenharmony_ci 393800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleWriteRes(int& fd, FaultLoggerPipe2* faultLoggerPipe) 394800b99b8Sopenharmony_ci{ 395800b99b8Sopenharmony_ci if ((faultLoggerPipe->faultLoggerPipeRes_) != nullptr) { 396800b99b8Sopenharmony_ci fd = faultLoggerPipe->faultLoggerPipeRes_->GetWriteFd(); 397800b99b8Sopenharmony_ci } 398800b99b8Sopenharmony_ci} 399800b99b8Sopenharmony_ci 400800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleDelete(FaultLoggerdRequest* request) 401800b99b8Sopenharmony_ci{ 402800b99b8Sopenharmony_ci faultLoggerPipeMap_->Del(request->pid); 403800b99b8Sopenharmony_ci} 404800b99b8Sopenharmony_ci 405800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleJsonReadBuf(int& fd, int32_t connectionFd, FaultLoggerdRequest* request, 406800b99b8Sopenharmony_ci FaultLoggerPipe2* faultLoggerPipe) 407800b99b8Sopenharmony_ci{ 408800b99b8Sopenharmony_ci FaultLoggerCheckPermissionResp resSecurityCheck = SecurityCheck(connectionFd, request); 409800b99b8Sopenharmony_ci if (FaultLoggerCheckPermissionResp::CHECK_PERMISSION_PASS != resSecurityCheck) { 410800b99b8Sopenharmony_ci return; 411800b99b8Sopenharmony_ci } 412800b99b8Sopenharmony_ci if ((faultLoggerPipe->faultLoggerJsonPipeBuf_) != nullptr) { 413800b99b8Sopenharmony_ci fd = faultLoggerPipe->faultLoggerJsonPipeBuf_->GetReadFd(); 414800b99b8Sopenharmony_ci } 415800b99b8Sopenharmony_ci} 416800b99b8Sopenharmony_ci 417800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleJsonWriteBuf(int& fd, FaultLoggerPipe2* faultLoggerPipe) 418800b99b8Sopenharmony_ci{ 419800b99b8Sopenharmony_ci if ((faultLoggerPipe->faultLoggerJsonPipeBuf_) != nullptr) { 420800b99b8Sopenharmony_ci fd = faultLoggerPipe->faultLoggerJsonPipeBuf_->GetWriteFd(); 421800b99b8Sopenharmony_ci } 422800b99b8Sopenharmony_ci} 423800b99b8Sopenharmony_ci 424800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleJsonReadRes(int& fd, int32_t connectionFd, FaultLoggerdRequest* request, 425800b99b8Sopenharmony_ci FaultLoggerPipe2* faultLoggerPipe) 426800b99b8Sopenharmony_ci{ 427800b99b8Sopenharmony_ci FaultLoggerCheckPermissionResp resSecurityCheck = SecurityCheck(connectionFd, request); 428800b99b8Sopenharmony_ci if (FaultLoggerCheckPermissionResp::CHECK_PERMISSION_PASS != resSecurityCheck) { 429800b99b8Sopenharmony_ci return; 430800b99b8Sopenharmony_ci } 431800b99b8Sopenharmony_ci if ((faultLoggerPipe->faultLoggerJsonPipeRes_) != nullptr) { 432800b99b8Sopenharmony_ci fd = faultLoggerPipe->faultLoggerJsonPipeRes_->GetReadFd(); 433800b99b8Sopenharmony_ci } 434800b99b8Sopenharmony_ci} 435800b99b8Sopenharmony_ci 436800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleJsonWriteRes(int& fd, FaultLoggerPipe2* faultLoggerPipe) 437800b99b8Sopenharmony_ci{ 438800b99b8Sopenharmony_ci if ((faultLoggerPipe->faultLoggerJsonPipeRes_) != nullptr) { 439800b99b8Sopenharmony_ci fd = faultLoggerPipe->faultLoggerJsonPipeRes_->GetWriteFd(); 440800b99b8Sopenharmony_ci } 441800b99b8Sopenharmony_ci} 442800b99b8Sopenharmony_ci 443800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleRequestByPipeType(int& fd, int32_t connectionFd, FaultLoggerdRequest* request, 444800b99b8Sopenharmony_ci FaultLoggerPipe2* faultLoggerPipe) 445800b99b8Sopenharmony_ci{ 446800b99b8Sopenharmony_ci switch (request->pipeType) { 447800b99b8Sopenharmony_ci case (int32_t)FaultLoggerPipeType::PIPE_FD_READ_BUF: { 448800b99b8Sopenharmony_ci HandleReadBuf(fd, connectionFd, request, faultLoggerPipe); 449800b99b8Sopenharmony_ci break; 450800b99b8Sopenharmony_ci } 451800b99b8Sopenharmony_ci case (int32_t)FaultLoggerPipeType::PIPE_FD_WRITE_BUF: { 452800b99b8Sopenharmony_ci HandleWriteBuf(fd, faultLoggerPipe); 453800b99b8Sopenharmony_ci break; 454800b99b8Sopenharmony_ci } 455800b99b8Sopenharmony_ci case (int32_t)FaultLoggerPipeType::PIPE_FD_READ_RES: { 456800b99b8Sopenharmony_ci HandleReadRes(fd, connectionFd, request, faultLoggerPipe); 457800b99b8Sopenharmony_ci break; 458800b99b8Sopenharmony_ci } 459800b99b8Sopenharmony_ci case (int32_t)FaultLoggerPipeType::PIPE_FD_WRITE_RES: { 460800b99b8Sopenharmony_ci HandleWriteRes(fd, faultLoggerPipe); 461800b99b8Sopenharmony_ci break; 462800b99b8Sopenharmony_ci } 463800b99b8Sopenharmony_ci case (int32_t)FaultLoggerPipeType::PIPE_FD_DELETE: { 464800b99b8Sopenharmony_ci HandleDelete(request); 465800b99b8Sopenharmony_ci return; 466800b99b8Sopenharmony_ci } 467800b99b8Sopenharmony_ci case (int32_t)FaultLoggerPipeType::PIPE_FD_JSON_READ_BUF: { 468800b99b8Sopenharmony_ci HandleJsonReadBuf(fd, connectionFd, request, faultLoggerPipe); 469800b99b8Sopenharmony_ci break; 470800b99b8Sopenharmony_ci } 471800b99b8Sopenharmony_ci case (int32_t)FaultLoggerPipeType::PIPE_FD_JSON_WRITE_BUF: { 472800b99b8Sopenharmony_ci HandleJsonWriteBuf(fd, faultLoggerPipe); 473800b99b8Sopenharmony_ci break; 474800b99b8Sopenharmony_ci } 475800b99b8Sopenharmony_ci case (int32_t)FaultLoggerPipeType::PIPE_FD_JSON_READ_RES: { 476800b99b8Sopenharmony_ci HandleJsonReadRes(fd, connectionFd, request, faultLoggerPipe); 477800b99b8Sopenharmony_ci break; 478800b99b8Sopenharmony_ci } 479800b99b8Sopenharmony_ci case (int32_t)FaultLoggerPipeType::PIPE_FD_JSON_WRITE_RES: { 480800b99b8Sopenharmony_ci HandleJsonWriteRes(fd, faultLoggerPipe); 481800b99b8Sopenharmony_ci break; 482800b99b8Sopenharmony_ci } 483800b99b8Sopenharmony_ci default: 484800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: unknown pipeType(%{public}d).", FAULTLOGGERD_TAG.c_str(), request->pipeType); 485800b99b8Sopenharmony_ci return; 486800b99b8Sopenharmony_ci } 487800b99b8Sopenharmony_ci} 488800b99b8Sopenharmony_ci 489800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandlePipeFdClientRequest(int32_t connectionFd, FaultLoggerdRequest * request) 490800b99b8Sopenharmony_ci{ 491800b99b8Sopenharmony_ci DFX_TRACE_SCOPED("HandlePipeFdClientRequest"); 492800b99b8Sopenharmony_ci DFXLOGD("%{public}s :: pid(%{public}d), pipeType(%{public}d).", FAULTLOGGERD_TAG.c_str(), 493800b99b8Sopenharmony_ci request->pid, request->pipeType); 494800b99b8Sopenharmony_ci int fd = -1; 495800b99b8Sopenharmony_ci FaultLoggerPipe2* faultLoggerPipe = faultLoggerPipeMap_->Get(request->pid); 496800b99b8Sopenharmony_ci if (faultLoggerPipe == nullptr) { 497800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: cannot find pipe fd for pid(%{public}d).", FAULTLOGGERD_TAG.c_str(), request->pid); 498800b99b8Sopenharmony_ci return; 499800b99b8Sopenharmony_ci } 500800b99b8Sopenharmony_ci HandleRequestByPipeType(fd, connectionFd, request, faultLoggerPipe); 501800b99b8Sopenharmony_ci if (fd < 0) { 502800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to get pipe fd, pipeType(%{public}d)", 503800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), request->pipeType); 504800b99b8Sopenharmony_ci return; 505800b99b8Sopenharmony_ci } 506800b99b8Sopenharmony_ci SendFileDescriptorToSocket(connectionFd, fd); 507800b99b8Sopenharmony_ci} 508800b99b8Sopenharmony_ci 509800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandlePrintTHilogClientRequest(int32_t const connectionFd, FaultLoggerdRequest * request) 510800b99b8Sopenharmony_ci{ 511800b99b8Sopenharmony_ci char buf[LINE_BUF_SIZE] = {0}; 512800b99b8Sopenharmony_ci 513800b99b8Sopenharmony_ci if (OHOS_TEMP_FAILURE_RETRY(write(connectionFd, 514800b99b8Sopenharmony_ci DAEMON_RESP.c_str(), DAEMON_RESP.length())) != static_cast<ssize_t>(DAEMON_RESP.length())) { 515800b99b8Sopenharmony_ci DFXLOGE("[%{public}d]: %{public}s :: Failed to write DAEMON_RESP.", __LINE__, FAULTLOGGERD_TAG.c_str()); 516800b99b8Sopenharmony_ci } 517800b99b8Sopenharmony_ci 518800b99b8Sopenharmony_ci int nread = OHOS_TEMP_FAILURE_RETRY(read(connectionFd, buf, sizeof(buf) - 1)); 519800b99b8Sopenharmony_ci if (nread < 0) { 520800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to read message, errno(%{public}d)", FAULTLOGGERD_TAG.c_str(), errno); 521800b99b8Sopenharmony_ci } else if (nread == 0) { 522800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: HandlePrintTHilogClientRequest :: Read null from request socket", 523800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str()); 524800b99b8Sopenharmony_ci } else { 525800b99b8Sopenharmony_ci DFXLOGE("%{public}s", buf); 526800b99b8Sopenharmony_ci } 527800b99b8Sopenharmony_ci} 528800b99b8Sopenharmony_ci 529800b99b8Sopenharmony_ciFaultLoggerCheckPermissionResp FaultLoggerDaemon::SecurityCheck(int32_t connectionFd, FaultLoggerdRequest * request) 530800b99b8Sopenharmony_ci{ 531800b99b8Sopenharmony_ci FaultLoggerCheckPermissionResp resCheckPermission = FaultLoggerCheckPermissionResp::CHECK_PERMISSION_REJECT; 532800b99b8Sopenharmony_ci 533800b99b8Sopenharmony_ci struct ucred rcred; 534800b99b8Sopenharmony_ci do { 535800b99b8Sopenharmony_ci int optval = 1; 536800b99b8Sopenharmony_ci if (OHOS_TEMP_FAILURE_RETRY(setsockopt(connectionFd, 537800b99b8Sopenharmony_ci SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval))) == -1) { 538800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: setsockopt SO_PASSCRED error, errno(%{public}d)", FAULTLOGGERD_TAG.c_str(), errno); 539800b99b8Sopenharmony_ci break; 540800b99b8Sopenharmony_ci } 541800b99b8Sopenharmony_ci 542800b99b8Sopenharmony_ci if (OHOS_TEMP_FAILURE_RETRY(write(connectionFd, DAEMON_RESP.c_str(), DAEMON_RESP.length())) != 543800b99b8Sopenharmony_ci static_cast<ssize_t>(DAEMON_RESP.length())) { 544800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to write DAEMON_RESP, errno(%{public}d)", FAULTLOGGERD_TAG.c_str(), errno); 545800b99b8Sopenharmony_ci break; 546800b99b8Sopenharmony_ci } 547800b99b8Sopenharmony_ci 548800b99b8Sopenharmony_ci if (!RecvMsgCredFromSocket(connectionFd, &rcred)) { 549800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Recv msg ucred error, errno(%{public}d)", FAULTLOGGERD_TAG.c_str(), errno); 550800b99b8Sopenharmony_ci break; 551800b99b8Sopenharmony_ci } 552800b99b8Sopenharmony_ci 553800b99b8Sopenharmony_ci request->uid = rcred.uid; 554800b99b8Sopenharmony_ci request->callerPid = static_cast<int32_t>(rcred.pid); 555800b99b8Sopenharmony_ci 556800b99b8Sopenharmony_ci auto it = connectionMap_.find(connectionFd); 557800b99b8Sopenharmony_ci if (it == connectionMap_.end()) { 558800b99b8Sopenharmony_ci break; 559800b99b8Sopenharmony_ci } 560800b99b8Sopenharmony_ci 561800b99b8Sopenharmony_ci if (it->second == sdkdumpSocketFd_) { 562800b99b8Sopenharmony_ci resCheckPermission = FaultLoggerCheckPermissionResp::CHECK_PERMISSION_PASS; 563800b99b8Sopenharmony_ci break; 564800b99b8Sopenharmony_ci } 565800b99b8Sopenharmony_ci 566800b99b8Sopenharmony_ci bool res = CheckCallerUID(request->uid); 567800b99b8Sopenharmony_ci if (res) { 568800b99b8Sopenharmony_ci resCheckPermission = FaultLoggerCheckPermissionResp::CHECK_PERMISSION_PASS; 569800b99b8Sopenharmony_ci } 570800b99b8Sopenharmony_ci } while (false); 571800b99b8Sopenharmony_ci 572800b99b8Sopenharmony_ci return resCheckPermission; 573800b99b8Sopenharmony_ci} 574800b99b8Sopenharmony_ci 575800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandlePermissionRequest(int32_t connectionFd, FaultLoggerdRequest * request) 576800b99b8Sopenharmony_ci{ 577800b99b8Sopenharmony_ci FaultLoggerCheckPermissionResp resSecurityCheck = SecurityCheck(connectionFd, request); 578800b99b8Sopenharmony_ci if (FaultLoggerCheckPermissionResp::CHECK_PERMISSION_PASS == resSecurityCheck) { 579800b99b8Sopenharmony_ci OHOS_TEMP_FAILURE_RETRY(send(connectionFd, "1", strlen("1"), 0)); 580800b99b8Sopenharmony_ci } 581800b99b8Sopenharmony_ci if (FaultLoggerCheckPermissionResp::CHECK_PERMISSION_REJECT == resSecurityCheck) { 582800b99b8Sopenharmony_ci OHOS_TEMP_FAILURE_RETRY(send(connectionFd, "2", strlen("2"), 0)); 583800b99b8Sopenharmony_ci } 584800b99b8Sopenharmony_ci} 585800b99b8Sopenharmony_ci 586800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleSdkDumpRequest(int32_t connectionFd, FaultLoggerdRequest * request) 587800b99b8Sopenharmony_ci{ 588800b99b8Sopenharmony_ci DFX_TRACE_SCOPED("HandleSdkDumpRequest"); 589800b99b8Sopenharmony_ci DFXLOGI("Receive dump request for pid:%{public}d tid:%{public}d.", request->pid, request->tid); 590800b99b8Sopenharmony_ci FaultLoggerSdkDumpResp resSdkDump = FaultLoggerSdkDumpResp::SDK_DUMP_PASS; 591800b99b8Sopenharmony_ci FaultLoggerCheckPermissionResp resSecurityCheck = SecurityCheck(connectionFd, request); 592800b99b8Sopenharmony_ci 593800b99b8Sopenharmony_ci /* 594800b99b8Sopenharmony_ci * all threads my user, local pid my user, remote pid other user's process 595800b99b8Sopenharmony_ci * 3rd Y Y(in signal_handler local) Y(in signal_handler loacl) N 596800b99b8Sopenharmony_ci * system Y Y(in signal_handler local) Y(in signal_handler loacl) Y(in signal_handler remote) 597800b99b8Sopenharmony_ci * root Y Y(in signal_handler local) Y(in signal_handler loacl) Y(in signal_handler remote) 598800b99b8Sopenharmony_ci */ 599800b99b8Sopenharmony_ci 600800b99b8Sopenharmony_ci /* 601800b99b8Sopenharmony_ci * 1. pid != 0 && tid != 0: means we want dump a thread, so we send signal to a thread. 602800b99b8Sopenharmony_ci Main thread stack is tid's stack, we need ignore other thread info. 603800b99b8Sopenharmony_ci * 2. pid != 0 && tid == 0: means we want dump a process, so we send signal to process. 604800b99b8Sopenharmony_ci Main thead stack is pid's stack, we need other tread info. 605800b99b8Sopenharmony_ci */ 606800b99b8Sopenharmony_ci 607800b99b8Sopenharmony_ci /* 608800b99b8Sopenharmony_ci * in signal_handler we need to check caller pid and tid(which is send to signal handler by SYS_rt_sig.). 609800b99b8Sopenharmony_ci * 1. caller pid == signal pid, means we do back trace in ourself process, means local backtrace. 610800b99b8Sopenharmony_ci * |- we do all tid back trace in signal handler's local unwind. 611800b99b8Sopenharmony_ci * 2. pid != signal pid, means we do remote back trace. 612800b99b8Sopenharmony_ci */ 613800b99b8Sopenharmony_ci 614800b99b8Sopenharmony_ci /* 615800b99b8Sopenharmony_ci * in local back trace, all unwind stack will save to signal_handler global var.(mutex lock in signal handler.) 616800b99b8Sopenharmony_ci * in remote back trace, all unwind stack will save to file, and read in dump_catcher, then return. 617800b99b8Sopenharmony_ci */ 618800b99b8Sopenharmony_ci 619800b99b8Sopenharmony_ci do { 620800b99b8Sopenharmony_ci if ((request->pid <= 0) || (FaultLoggerCheckPermissionResp::CHECK_PERMISSION_REJECT == resSecurityCheck)) { 621800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: HandleSdkDumpRequest :: pid(%{public}d) or resSecurityCheck(%{public}d) fail.\n", \ 622800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), request->pid, (int)resSecurityCheck); 623800b99b8Sopenharmony_ci resSdkDump = FaultLoggerSdkDumpResp::SDK_DUMP_REJECT; 624800b99b8Sopenharmony_ci break; 625800b99b8Sopenharmony_ci } 626800b99b8Sopenharmony_ci DFXLOGI("Sdk dump pid(%{public}d) request pass permission verification.", request->pid); 627800b99b8Sopenharmony_ci if (IsCrashed(request->pid)) { 628800b99b8Sopenharmony_ci resSdkDump = FaultLoggerSdkDumpResp::SDK_PROCESS_CRASHED; 629800b99b8Sopenharmony_ci DFXLOGW("%{public}s :: pid(%{public}d) has been crashed, break.\n", 630800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), request->pid); 631800b99b8Sopenharmony_ci break; 632800b99b8Sopenharmony_ci } 633800b99b8Sopenharmony_ci if (faultLoggerPipeMap_->Check(request->pid, request->time)) { 634800b99b8Sopenharmony_ci resSdkDump = FaultLoggerSdkDumpResp::SDK_DUMP_REPEAT; 635800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: pid(%{public}d) is dumping, break.\n", FAULTLOGGERD_TAG.c_str(), request->pid); 636800b99b8Sopenharmony_ci break; 637800b99b8Sopenharmony_ci } 638800b99b8Sopenharmony_ci faultLoggerPipeMap_->Set(request->pid, request->time, request->isJson); 639800b99b8Sopenharmony_ci 640800b99b8Sopenharmony_ci#pragma clang diagnostic push 641800b99b8Sopenharmony_ci#pragma clang diagnostic ignored "-Winitializer-overrides" 642800b99b8Sopenharmony_ci // defined in out/hi3516dv300/obj/third_party/musl/intermidiates/linux/musl_src_ported/include/signal.h 643800b99b8Sopenharmony_ci siginfo_t si {0}; 644800b99b8Sopenharmony_ci si.si_signo = SIGDUMP; 645800b99b8Sopenharmony_ci si.si_errno = 0; 646800b99b8Sopenharmony_ci si.si_value.sival_int = request->tid; 647800b99b8Sopenharmony_ci if (request->tid == 0 && sizeof(void *) == 8) { // 8 : platform 64 648800b99b8Sopenharmony_ci si.si_value.sival_ptr = reinterpret_cast<void *>(request->endTime | (1ULL << 63)); // 63 : platform 64 649800b99b8Sopenharmony_ci } 650800b99b8Sopenharmony_ci si.si_code = request->sigCode; 651800b99b8Sopenharmony_ci si.si_pid = request->callerPid; 652800b99b8Sopenharmony_ci si.si_uid = static_cast<uid_t>(request->callerTid); 653800b99b8Sopenharmony_ci#pragma clang diagnostic pop 654800b99b8Sopenharmony_ci /* 655800b99b8Sopenharmony_ci * means we need dump all the threads in a process 656800b99b8Sopenharmony_ci * -------- 657800b99b8Sopenharmony_ci * Accroding to the linux manual, A process-directed signal may be delivered to any one of the 658800b99b8Sopenharmony_ci * threads that does not currently have the signal blocked. 659800b99b8Sopenharmony_ci */ 660800b99b8Sopenharmony_ci if (syscall(SYS_rt_sigqueueinfo, request->pid, si.si_signo, &si) != 0) { 661800b99b8Sopenharmony_ci DFXLOGE("Failed to SYS_rt_sigqueueinfo signal(%{public}d), errno(%{public}d).", si.si_signo, errno); 662800b99b8Sopenharmony_ci resSdkDump = FaultLoggerSdkDumpResp::SDK_DUMP_NOPROC; 663800b99b8Sopenharmony_ci } 664800b99b8Sopenharmony_ci } while (false); 665800b99b8Sopenharmony_ci auto retMsg = std::to_string(resSdkDump); 666800b99b8Sopenharmony_ci if (OHOS_TEMP_FAILURE_RETRY(send(connectionFd, retMsg.data(), retMsg.length(), 0)) != 667800b99b8Sopenharmony_ci static_cast<ssize_t>(retMsg.length())) { 668800b99b8Sopenharmony_ci DFXLOGE("Failed to send result message to client, errno(%{public}d).", errno); 669800b99b8Sopenharmony_ci } 670800b99b8Sopenharmony_ci} 671800b99b8Sopenharmony_ci 672800b99b8Sopenharmony_civoid FaultLoggerDaemon::RecordFileCreation(int32_t type, int32_t pid) 673800b99b8Sopenharmony_ci{ 674800b99b8Sopenharmony_ci if (type == static_cast<int32_t>(FaultLoggerType::CPP_CRASH)) { 675800b99b8Sopenharmony_ci ClearTimeOutRecords(); 676800b99b8Sopenharmony_ci crashTimeMap_[pid] = time(nullptr); 677800b99b8Sopenharmony_ci } 678800b99b8Sopenharmony_ci} 679800b99b8Sopenharmony_ci 680800b99b8Sopenharmony_civoid FaultLoggerDaemon::ClearTimeOutRecords() 681800b99b8Sopenharmony_ci{ 682800b99b8Sopenharmony_ci constexpr int validTime = 8; 683800b99b8Sopenharmony_ci auto currentTime = time(nullptr); 684800b99b8Sopenharmony_ci for (auto it = crashTimeMap_.begin(); it != crashTimeMap_.end();) { 685800b99b8Sopenharmony_ci if ((it->second + validTime) <= currentTime) { 686800b99b8Sopenharmony_ci crashTimeMap_.erase(it++); 687800b99b8Sopenharmony_ci } else { 688800b99b8Sopenharmony_ci it++; 689800b99b8Sopenharmony_ci } 690800b99b8Sopenharmony_ci } 691800b99b8Sopenharmony_ci} 692800b99b8Sopenharmony_ci 693800b99b8Sopenharmony_cibool FaultLoggerDaemon::IsCrashed(int32_t pid) 694800b99b8Sopenharmony_ci{ 695800b99b8Sopenharmony_ci DFX_TRACE_SCOPED("IsCrashed"); 696800b99b8Sopenharmony_ci ClearTimeOutRecords(); 697800b99b8Sopenharmony_ci return crashTimeMap_.find(pid) != crashTimeMap_.end(); 698800b99b8Sopenharmony_ci} 699800b99b8Sopenharmony_ci 700800b99b8Sopenharmony_ciint32_t FaultLoggerDaemon::CreateFileForRequest(int32_t type, int32_t pid, int32_t tid, uint64_t time) const 701800b99b8Sopenharmony_ci{ 702800b99b8Sopenharmony_ci RemoveTempFileIfNeed(); 703800b99b8Sopenharmony_ci std::string typeStr = GetRequestTypeName(type); 704800b99b8Sopenharmony_ci if (typeStr == "unsupported") { 705800b99b8Sopenharmony_ci DFXLOGE("Unsupported request type(%{public}d)", type); 706800b99b8Sopenharmony_ci return -1; 707800b99b8Sopenharmony_ci } 708800b99b8Sopenharmony_ci 709800b99b8Sopenharmony_ci std::string folderPath = ""; 710800b99b8Sopenharmony_ci folderPath = faultLoggerConfig_->GetLogFilePath(); 711800b99b8Sopenharmony_ci 712800b99b8Sopenharmony_ci if (time == 0) { 713800b99b8Sopenharmony_ci time = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>\ 714800b99b8Sopenharmony_ci (std::chrono::system_clock::now().time_since_epoch()).count()); 715800b99b8Sopenharmony_ci } 716800b99b8Sopenharmony_ci 717800b99b8Sopenharmony_ci std::string ss = folderPath + "/" + typeStr + "-" + std::to_string(pid); 718800b99b8Sopenharmony_ci if (type == FaultLoggerType::JS_HEAP_SNAPSHOT || type == FaultLoggerType::JS_RAW_SNAPSHOT) { 719800b99b8Sopenharmony_ci ss += "-" + std::to_string(tid); 720800b99b8Sopenharmony_ci } 721800b99b8Sopenharmony_ci ss += "-" + std::to_string(time); 722800b99b8Sopenharmony_ci if (type == FaultLoggerType::JS_RAW_SNAPSHOT) { 723800b99b8Sopenharmony_ci ss += ".rawheap"; 724800b99b8Sopenharmony_ci } 725800b99b8Sopenharmony_ci const std::string path = ss; 726800b99b8Sopenharmony_ci DFXLOGI("%{public}s :: file path(%{public}s).\n", FAULTLOGGERD_TAG.c_str(), path.c_str()); 727800b99b8Sopenharmony_ci if (!VerifyFilePath(path, VALID_FILE_PATH)) { 728800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Open %{public}s fail, please check it under valid path.\n", 729800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), path.c_str()); 730800b99b8Sopenharmony_ci return -1; 731800b99b8Sopenharmony_ci } 732800b99b8Sopenharmony_ci int32_t fd = OHOS_TEMP_FAILURE_RETRY(open(path.c_str(), O_RDWR | O_CREAT, FAULTLOG_FILE_PROP)); 733800b99b8Sopenharmony_ci if (fd != -1) { 734800b99b8Sopenharmony_ci if (!ChangeModeFile(path, FAULTLOG_FILE_PROP)) { 735800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to ChangeMode CreateFileForRequest", FAULTLOGGERD_TAG.c_str()); 736800b99b8Sopenharmony_ci } 737800b99b8Sopenharmony_ci } 738800b99b8Sopenharmony_ci return fd; 739800b99b8Sopenharmony_ci} 740800b99b8Sopenharmony_ci 741800b99b8Sopenharmony_civoid FaultLoggerDaemon::RemoveTempFileIfNeed() const 742800b99b8Sopenharmony_ci{ 743800b99b8Sopenharmony_ci int maxFileCount = 50; 744800b99b8Sopenharmony_ci int currentLogCounts = 0; 745800b99b8Sopenharmony_ci 746800b99b8Sopenharmony_ci std::string logFilePath = faultLoggerConfig_->GetLogFilePath(); 747800b99b8Sopenharmony_ci std::vector<std::string> files; 748800b99b8Sopenharmony_ci OHOS::GetDirFiles(logFilePath, files); 749800b99b8Sopenharmony_ci constexpr uint64_t maxFileSize = 1lu << 31; // 2GB 750800b99b8Sopenharmony_ci if (!isBeta_ && OHOS::GetFolderSize(logFilePath) > maxFileSize) { 751800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: current file size is over limit, clear all files", FAULTLOGGERD_TAG.c_str()); 752800b99b8Sopenharmony_ci std::for_each(files.begin(), files.end(), OHOS::RemoveFile); 753800b99b8Sopenharmony_ci return; 754800b99b8Sopenharmony_ci } 755800b99b8Sopenharmony_ci currentLogCounts = (int)files.size(); 756800b99b8Sopenharmony_ci maxFileCount = faultLoggerConfig_->GetLogFileMaxNumber(); 757800b99b8Sopenharmony_ci if (currentLogCounts < maxFileCount) { 758800b99b8Sopenharmony_ci return; 759800b99b8Sopenharmony_ci } 760800b99b8Sopenharmony_ci 761800b99b8Sopenharmony_ci std::sort(files.begin(), files.end(), 762800b99b8Sopenharmony_ci [](const std::string& lhs, const std::string& rhs) -> int { 763800b99b8Sopenharmony_ci auto lhsSplitPos = lhs.find_last_of("-"); 764800b99b8Sopenharmony_ci auto rhsSplitPos = rhs.find_last_of("-"); 765800b99b8Sopenharmony_ci if (lhsSplitPos == std::string::npos || rhsSplitPos == std::string::npos) { 766800b99b8Sopenharmony_ci return lhs.compare(rhs) > 0; 767800b99b8Sopenharmony_ci } 768800b99b8Sopenharmony_ci 769800b99b8Sopenharmony_ci return lhs.substr(lhsSplitPos).compare(rhs.substr(rhsSplitPos)) > 0; 770800b99b8Sopenharmony_ci }); 771800b99b8Sopenharmony_ci 772800b99b8Sopenharmony_ci time_t currentTime = static_cast<time_t>(time(nullptr)); 773800b99b8Sopenharmony_ci if (currentTime <= 0) { 774800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: currentTime is less than zero CreateFileForRequest", FAULTLOGGERD_TAG.c_str()); 775800b99b8Sopenharmony_ci } 776800b99b8Sopenharmony_ci 777800b99b8Sopenharmony_ci constexpr int deleteNum = 1; 778800b99b8Sopenharmony_ci int startIndex = maxFileCount > deleteNum ? maxFileCount - deleteNum : maxFileCount; 779800b99b8Sopenharmony_ci for (unsigned int index = (unsigned int)startIndex; index < files.size(); index++) { 780800b99b8Sopenharmony_ci struct stat st; 781800b99b8Sopenharmony_ci int err = stat(files[index].c_str(), &st); 782800b99b8Sopenharmony_ci if (err != 0) { 783800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Get log stat failed, errno(%{public}d).", FAULTLOGGERD_TAG.c_str(), errno); 784800b99b8Sopenharmony_ci } else { 785800b99b8Sopenharmony_ci if ((currentTime - st.st_mtime) <= DAEMON_REMOVE_FILE_TIME_S) { 786800b99b8Sopenharmony_ci continue; 787800b99b8Sopenharmony_ci } 788800b99b8Sopenharmony_ci } 789800b99b8Sopenharmony_ci 790800b99b8Sopenharmony_ci OHOS::RemoveFile(files[index]); 791800b99b8Sopenharmony_ci DFXLOGD("%{public}s :: Now we rm file(%{public}s) as max log number exceeded.", \ 792800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), files[index].c_str()); 793800b99b8Sopenharmony_ci } 794800b99b8Sopenharmony_ci} 795800b99b8Sopenharmony_ci 796800b99b8Sopenharmony_civoid FaultLoggerDaemon::AddEvent(int32_t epollFd, int32_t addFd, uint32_t event) 797800b99b8Sopenharmony_ci{ 798800b99b8Sopenharmony_ci epoll_event ev; 799800b99b8Sopenharmony_ci ev.events = event; 800800b99b8Sopenharmony_ci ev.data.fd = addFd; 801800b99b8Sopenharmony_ci int ret = epoll_ctl(epollFd, EPOLL_CTL_ADD, addFd, &ev); 802800b99b8Sopenharmony_ci if (ret < 0) { 803800b99b8Sopenharmony_ci DFXLOGW("%{public}s :: Failed to epoll ctl add Fd(%{public}d), errno(%{public}d)", 804800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), addFd, errno); 805800b99b8Sopenharmony_ci } 806800b99b8Sopenharmony_ci} 807800b99b8Sopenharmony_ci 808800b99b8Sopenharmony_civoid FaultLoggerDaemon::DelEvent(int32_t epollFd, int32_t delFd, uint32_t event) 809800b99b8Sopenharmony_ci{ 810800b99b8Sopenharmony_ci epoll_event ev; 811800b99b8Sopenharmony_ci ev.events = event; 812800b99b8Sopenharmony_ci ev.data.fd = delFd; 813800b99b8Sopenharmony_ci int ret = epoll_ctl(epollFd, EPOLL_CTL_DEL, delFd, &ev); 814800b99b8Sopenharmony_ci if (ret < 0) { 815800b99b8Sopenharmony_ci DFXLOGW("%{public}s :: Failed to epoll ctl del Fd(%{public}d), errno(%{public}d)", 816800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), delFd, errno); 817800b99b8Sopenharmony_ci } 818800b99b8Sopenharmony_ci close(delFd); 819800b99b8Sopenharmony_ci} 820800b99b8Sopenharmony_ci 821800b99b8Sopenharmony_cibool FaultLoggerDaemon::CheckRequestCredential(int32_t connectionFd, FaultLoggerdRequest* request) 822800b99b8Sopenharmony_ci{ 823800b99b8Sopenharmony_ci if (request == nullptr) { 824800b99b8Sopenharmony_ci return false; 825800b99b8Sopenharmony_ci } 826800b99b8Sopenharmony_ci 827800b99b8Sopenharmony_ci auto it = connectionMap_.find(connectionFd); 828800b99b8Sopenharmony_ci if (it == connectionMap_.end()) { 829800b99b8Sopenharmony_ci DFXLOGE("%{public}s : Failed to find fd:%{public}d, map size:%{public}zu", FAULTLOGGERD_TAG.c_str(), 830800b99b8Sopenharmony_ci connectionFd, connectionMap_.size()); 831800b99b8Sopenharmony_ci return false; 832800b99b8Sopenharmony_ci } 833800b99b8Sopenharmony_ci 834800b99b8Sopenharmony_ci if (it->second == crashSocketFd_ || it->second == sdkdumpSocketFd_) { 835800b99b8Sopenharmony_ci // only processdump use this socket 836800b99b8Sopenharmony_ci return true; 837800b99b8Sopenharmony_ci } 838800b99b8Sopenharmony_ci 839800b99b8Sopenharmony_ci struct ucred creds = {}; 840800b99b8Sopenharmony_ci socklen_t credSize = sizeof(creds); 841800b99b8Sopenharmony_ci int err = getsockopt(connectionFd, SOL_SOCKET, SO_PEERCRED, &creds, &credSize); 842800b99b8Sopenharmony_ci if (err != 0) { 843800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: Failed to CheckRequestCredential, errno(%{public}d)", FAULTLOGGERD_TAG.c_str(), errno); 844800b99b8Sopenharmony_ci return false; 845800b99b8Sopenharmony_ci } 846800b99b8Sopenharmony_ci 847800b99b8Sopenharmony_ci if (CheckCallerUID(creds.uid)) { 848800b99b8Sopenharmony_ci return true; 849800b99b8Sopenharmony_ci } 850800b99b8Sopenharmony_ci 851800b99b8Sopenharmony_ci bool isCredentialMatched = (creds.pid == request->pid); 852800b99b8Sopenharmony_ci if (request->clientType == (int32_t)REPORT_EXCEPTION_CLIENT) { 853800b99b8Sopenharmony_ci isCredentialMatched = (creds.uid == request->uid); /* check uid when report exception */ 854800b99b8Sopenharmony_ci } 855800b99b8Sopenharmony_ci if (!isCredentialMatched) { 856800b99b8Sopenharmony_ci DFXLOGW("Failed to check request credential request:%{public}d:" \ 857800b99b8Sopenharmony_ci "%{public}d cred:%{public}d:%{public}d fd:%{public}d:%{public}d", 858800b99b8Sopenharmony_ci request->pid, request->uid, creds.pid, creds.uid, it->second, crashSocketFd_); 859800b99b8Sopenharmony_ci } 860800b99b8Sopenharmony_ci return isCredentialMatched; 861800b99b8Sopenharmony_ci} 862800b99b8Sopenharmony_ci 863800b99b8Sopenharmony_cibool FaultLoggerDaemon::CreateSockets() 864800b99b8Sopenharmony_ci{ 865800b99b8Sopenharmony_ci if (!StartListen(defaultSocketFd_, SERVER_SOCKET_NAME, MAX_CONNECTION)) { 866800b99b8Sopenharmony_ci return false; 867800b99b8Sopenharmony_ci } 868800b99b8Sopenharmony_ci 869800b99b8Sopenharmony_ci if (!StartListen(crashSocketFd_, SERVER_CRASH_SOCKET_NAME, MAX_CONNECTION)) { 870800b99b8Sopenharmony_ci close(defaultSocketFd_); 871800b99b8Sopenharmony_ci defaultSocketFd_ = -1; 872800b99b8Sopenharmony_ci return false; 873800b99b8Sopenharmony_ci } 874800b99b8Sopenharmony_ci#ifndef is_ohos_lite 875800b99b8Sopenharmony_ci if (!StartListen(sdkdumpSocketFd_, SERVER_SDKDUMP_SOCKET_NAME, MAX_CONNECTION)) { 876800b99b8Sopenharmony_ci close(defaultSocketFd_); 877800b99b8Sopenharmony_ci defaultSocketFd_ = -1; 878800b99b8Sopenharmony_ci close(crashSocketFd_); 879800b99b8Sopenharmony_ci crashSocketFd_ = -1; 880800b99b8Sopenharmony_ci return false; 881800b99b8Sopenharmony_ci } 882800b99b8Sopenharmony_ci#endif 883800b99b8Sopenharmony_ci return true; 884800b99b8Sopenharmony_ci} 885800b99b8Sopenharmony_ci 886800b99b8Sopenharmony_civoid FaultLoggerDaemon::CleanupSockets() 887800b99b8Sopenharmony_ci{ 888800b99b8Sopenharmony_ci if (defaultSocketFd_ >= 0) { 889800b99b8Sopenharmony_ci close(defaultSocketFd_); 890800b99b8Sopenharmony_ci defaultSocketFd_ = -1; 891800b99b8Sopenharmony_ci } 892800b99b8Sopenharmony_ci 893800b99b8Sopenharmony_ci if (crashSocketFd_ >= 0) { 894800b99b8Sopenharmony_ci close(crashSocketFd_); 895800b99b8Sopenharmony_ci crashSocketFd_ = -1; 896800b99b8Sopenharmony_ci } 897800b99b8Sopenharmony_ci 898800b99b8Sopenharmony_ci if (sdkdumpSocketFd_ >= 0) { 899800b99b8Sopenharmony_ci close(sdkdumpSocketFd_); 900800b99b8Sopenharmony_ci sdkdumpSocketFd_ = -1; 901800b99b8Sopenharmony_ci } 902800b99b8Sopenharmony_ci} 903800b99b8Sopenharmony_ci 904800b99b8Sopenharmony_cibool FaultLoggerDaemon::CreateEventFd() 905800b99b8Sopenharmony_ci{ 906800b99b8Sopenharmony_ci eventFd_ = epoll_create(MAX_EPOLL_EVENT); 907800b99b8Sopenharmony_ci if (eventFd_ < 0) { 908800b99b8Sopenharmony_ci return false; 909800b99b8Sopenharmony_ci } 910800b99b8Sopenharmony_ci return true; 911800b99b8Sopenharmony_ci} 912800b99b8Sopenharmony_ci 913800b99b8Sopenharmony_civoid FaultLoggerDaemon::WaitForRequest() 914800b99b8Sopenharmony_ci{ 915800b99b8Sopenharmony_ci AddEvent(eventFd_, defaultSocketFd_, EPOLLIN); 916800b99b8Sopenharmony_ci AddEvent(eventFd_, crashSocketFd_, EPOLLIN); 917800b99b8Sopenharmony_ci AddEvent(eventFd_, sdkdumpSocketFd_, EPOLLIN); 918800b99b8Sopenharmony_ci epoll_event events[MAX_CONNECTION]; 919800b99b8Sopenharmony_ci DFXLOGD("%{public}s :: %{public}s: start epoll wait.", FAULTLOGGERD_TAG.c_str(), __func__); 920800b99b8Sopenharmony_ci do { 921800b99b8Sopenharmony_ci int epollNum = OHOS_TEMP_FAILURE_RETRY(epoll_wait(eventFd_, events, MAX_CONNECTION, -1)); 922800b99b8Sopenharmony_ci if (epollNum < 0) { 923800b99b8Sopenharmony_ci DFXLOGE("%{public}s :: %{public}s: epoll wait error, errno(%{public}d).", 924800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), __func__, errno); 925800b99b8Sopenharmony_ci continue; 926800b99b8Sopenharmony_ci } 927800b99b8Sopenharmony_ci for (int i = 0; i < epollNum; i++) { 928800b99b8Sopenharmony_ci if (!(events[i].events & EPOLLIN)) { 929800b99b8Sopenharmony_ci DFXLOGW("%{public}s :: %{public}s: epoll event(%{public}d) error.", 930800b99b8Sopenharmony_ci FAULTLOGGERD_TAG.c_str(), __func__, events[i].events); 931800b99b8Sopenharmony_ci continue; 932800b99b8Sopenharmony_ci } 933800b99b8Sopenharmony_ci 934800b99b8Sopenharmony_ci int fd = events[i].data.fd; 935800b99b8Sopenharmony_ci if (fd == defaultSocketFd_ || fd == crashSocketFd_ || fd == sdkdumpSocketFd_) { 936800b99b8Sopenharmony_ci HandleAccept(eventFd_, fd); 937800b99b8Sopenharmony_ci } else { 938800b99b8Sopenharmony_ci HandleRequest(eventFd_, fd); 939800b99b8Sopenharmony_ci } 940800b99b8Sopenharmony_ci } 941800b99b8Sopenharmony_ci } while (true); 942800b99b8Sopenharmony_ci} 943800b99b8Sopenharmony_ci 944800b99b8Sopenharmony_civoid FaultLoggerDaemon::CleanupEventFd() 945800b99b8Sopenharmony_ci{ 946800b99b8Sopenharmony_ci DelEvent(eventFd_, defaultSocketFd_, EPOLLIN); 947800b99b8Sopenharmony_ci DelEvent(eventFd_, crashSocketFd_, EPOLLIN); 948800b99b8Sopenharmony_ci DelEvent(eventFd_, sdkdumpSocketFd_, EPOLLIN); 949800b99b8Sopenharmony_ci 950800b99b8Sopenharmony_ci if (eventFd_ > 0) { 951800b99b8Sopenharmony_ci close(eventFd_); 952800b99b8Sopenharmony_ci eventFd_ = -1; 953800b99b8Sopenharmony_ci } 954800b99b8Sopenharmony_ci} 955800b99b8Sopenharmony_ci 956800b99b8Sopenharmony_cistd::string GetElfName(FaultLoggerdStatsRequest* request) 957800b99b8Sopenharmony_ci{ 958800b99b8Sopenharmony_ci if (request == nullptr || strlen(request->callerElf) > NAME_BUF_LEN) { 959800b99b8Sopenharmony_ci return ""; 960800b99b8Sopenharmony_ci } 961800b99b8Sopenharmony_ci 962800b99b8Sopenharmony_ci std::string ss = StringPrintf("%s(%p)", request->callerElf, reinterpret_cast<void *>(request->offset)); 963800b99b8Sopenharmony_ci return ss; 964800b99b8Sopenharmony_ci} 965800b99b8Sopenharmony_ci 966800b99b8Sopenharmony_civoid FaultLoggerDaemon::HandleDumpStats(int32_t connectionFd, FaultLoggerdStatsRequest* request) 967800b99b8Sopenharmony_ci{ 968800b99b8Sopenharmony_ci DFXLOGI("%{public}s :: %{public}s: HandleDumpStats", FAULTLOGGERD_TAG.c_str(), __func__); 969800b99b8Sopenharmony_ci size_t index = 0; 970800b99b8Sopenharmony_ci bool hasRecord = false; 971800b99b8Sopenharmony_ci for (index = 0; index < stats_.size(); index++) { 972800b99b8Sopenharmony_ci if (stats_[index].pid == request->pid) { 973800b99b8Sopenharmony_ci hasRecord = true; 974800b99b8Sopenharmony_ci break; 975800b99b8Sopenharmony_ci } 976800b99b8Sopenharmony_ci } 977800b99b8Sopenharmony_ci 978800b99b8Sopenharmony_ci DumpStats stats; 979800b99b8Sopenharmony_ci if (request->type == PROCESS_DUMP && !hasRecord) { 980800b99b8Sopenharmony_ci stats.pid = request->pid; 981800b99b8Sopenharmony_ci stats.signalTime = request->signalTime; 982800b99b8Sopenharmony_ci stats.processdumpStartTime = request->processdumpStartTime; 983800b99b8Sopenharmony_ci stats.processdumpFinishTime = request->processdumpFinishTime; 984800b99b8Sopenharmony_ci stats.targetProcessName = request->targetProcess; 985800b99b8Sopenharmony_ci stats_.emplace_back(stats); 986800b99b8Sopenharmony_ci } else if (request->type == DUMP_CATCHER && hasRecord) { 987800b99b8Sopenharmony_ci stats_[index].requestTime = request->requestTime; 988800b99b8Sopenharmony_ci stats_[index].dumpCatcherFinishTime = request->dumpCatcherFinishTime; 989800b99b8Sopenharmony_ci stats_[index].callerElfName = GetElfName(request); 990800b99b8Sopenharmony_ci stats_[index].callerProcessName = request->callerProcess; 991800b99b8Sopenharmony_ci stats_[index].result = request->result; 992800b99b8Sopenharmony_ci stats_[index].summary = request->summary; 993800b99b8Sopenharmony_ci ReportDumpStats(stats_[index]); 994800b99b8Sopenharmony_ci stats_.erase(stats_.begin() + index); 995800b99b8Sopenharmony_ci } else if (request->type == DUMP_CATCHER) { 996800b99b8Sopenharmony_ci stats.pid = request->pid; 997800b99b8Sopenharmony_ci stats.requestTime = request->requestTime; 998800b99b8Sopenharmony_ci stats.dumpCatcherFinishTime = request->dumpCatcherFinishTime; 999800b99b8Sopenharmony_ci stats.callerElfName = GetElfName(request); 1000800b99b8Sopenharmony_ci stats.result = request->result; 1001800b99b8Sopenharmony_ci stats.callerProcessName = request->callerProcess; 1002800b99b8Sopenharmony_ci stats.summary = request->summary; 1003800b99b8Sopenharmony_ci stats.targetProcessName = request->targetProcess; 1004800b99b8Sopenharmony_ci ReportDumpStats(stats); 1005800b99b8Sopenharmony_ci } 1006800b99b8Sopenharmony_ci RemoveTimeoutDumpStats(); 1007800b99b8Sopenharmony_ci} 1008800b99b8Sopenharmony_ci 1009800b99b8Sopenharmony_civoid FaultLoggerDaemon::RemoveTimeoutDumpStats() 1010800b99b8Sopenharmony_ci{ 1011800b99b8Sopenharmony_ci const uint64_t timeout = 10000; 1012800b99b8Sopenharmony_ci uint64_t now = GetTimeMilliSeconds(); 1013800b99b8Sopenharmony_ci for (auto it = stats_.begin(); it != stats_.end();) { 1014800b99b8Sopenharmony_ci if (((now > it->signalTime) && (now - it->signalTime > timeout)) || 1015800b99b8Sopenharmony_ci (now <= it->signalTime)) { 1016800b99b8Sopenharmony_ci it = stats_.erase(it); 1017800b99b8Sopenharmony_ci } else { 1018800b99b8Sopenharmony_ci ++it; 1019800b99b8Sopenharmony_ci } 1020800b99b8Sopenharmony_ci } 1021800b99b8Sopenharmony_ci} 1022800b99b8Sopenharmony_ci 1023800b99b8Sopenharmony_civoid FaultLoggerDaemon::ReportDumpStats(const DumpStats& stat) 1024800b99b8Sopenharmony_ci{ 1025800b99b8Sopenharmony_ci#ifndef HISYSEVENT_DISABLE 1026800b99b8Sopenharmony_ci HiSysEventWrite( 1027800b99b8Sopenharmony_ci HiSysEvent::Domain::HIVIEWDFX, 1028800b99b8Sopenharmony_ci "DUMP_CATCHER_STATS", 1029800b99b8Sopenharmony_ci HiSysEvent::EventType::STATISTIC, 1030800b99b8Sopenharmony_ci "CALLER_PROCESS_NAME", stat.callerProcessName, 1031800b99b8Sopenharmony_ci "CALLER_FUNC_NAME", stat.callerElfName, 1032800b99b8Sopenharmony_ci "TARGET_PROCESS_NAME", stat.targetProcessName, 1033800b99b8Sopenharmony_ci "RESULT", stat.result, 1034800b99b8Sopenharmony_ci "SUMMARY", stat.summary, // we need to parse summary when interface return false 1035800b99b8Sopenharmony_ci "PID", stat.pid, 1036800b99b8Sopenharmony_ci "REQUEST_TIME", stat.requestTime, 1037800b99b8Sopenharmony_ci "OVERALL_TIME", stat.dumpCatcherFinishTime - stat.requestTime, 1038800b99b8Sopenharmony_ci "SIGNAL_TIME", stat.signalTime - stat.requestTime, 1039800b99b8Sopenharmony_ci "DUMPER_START_TIME", stat.processdumpStartTime - stat.signalTime, 1040800b99b8Sopenharmony_ci "UNWIND_TIME", stat.processdumpFinishTime - stat.processdumpStartTime); 1041800b99b8Sopenharmony_ci#endif 1042800b99b8Sopenharmony_ci} 1043800b99b8Sopenharmony_ci} // namespace HiviewDFX 1044800b99b8Sopenharmony_ci} // namespace OHOS 1045