1020a203aSopenharmony_ci/* 2020a203aSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4020a203aSopenharmony_ci * you may not use this file except in compliance with the License. 5020a203aSopenharmony_ci * You may obtain a copy of the License at 6020a203aSopenharmony_ci * 7020a203aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8020a203aSopenharmony_ci * 9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12020a203aSopenharmony_ci * See the License for the specific language governing permissions and 13020a203aSopenharmony_ci * limitations under the License. 14020a203aSopenharmony_ci */ 15020a203aSopenharmony_ci 16020a203aSopenharmony_ci#include <unistd.h> 17020a203aSopenharmony_ci#include "faultlogger_ffi.h" 18020a203aSopenharmony_ci#include "faultlogger_client.h" 19020a203aSopenharmony_ci#include "faultlogger_info.h" 20020a203aSopenharmony_ci#include "hiview_logger.h" 21020a203aSopenharmony_ci#include <mutex> 22020a203aSopenharmony_ci#include "faultlog_query_result.h" 23020a203aSopenharmony_ci#include "faultlog_info.h" 24020a203aSopenharmony_ci#include "common_utils.h" 25020a203aSopenharmony_ci 26020a203aSopenharmony_ciusing namespace OHOS::HiviewDFX; 27020a203aSopenharmony_ci 28020a203aSopenharmony_ciDEFINE_LOG_LABEL(0xD002D11, "Faultlogger-cj"); 29020a203aSopenharmony_cistd::mutex g_mutex; 30020a203aSopenharmony_ci 31020a203aSopenharmony_cichar* MallocCString(const std::string& origin) 32020a203aSopenharmony_ci{ 33020a203aSopenharmony_ci if (origin.empty()) { 34020a203aSopenharmony_ci return nullptr; 35020a203aSopenharmony_ci } 36020a203aSopenharmony_ci auto length = origin.length() + 1; 37020a203aSopenharmony_ci char* res = static_cast<char*>(malloc(sizeof(char) * length)); 38020a203aSopenharmony_ci if (res == nullptr) { 39020a203aSopenharmony_ci return nullptr; 40020a203aSopenharmony_ci } 41020a203aSopenharmony_ci return std::char_traits<char>::copy(res, origin.c_str(), length); 42020a203aSopenharmony_ci} 43020a203aSopenharmony_ci 44020a203aSopenharmony_ciCJFaultLogInfo ConvertInform(std::unique_ptr<FaultLogInfo> faultLogInfo) 45020a203aSopenharmony_ci{ 46020a203aSopenharmony_ci CJFaultLogInfo ret = { 47020a203aSopenharmony_ci .pid = faultLogInfo->GetProcessId(), 48020a203aSopenharmony_ci .uid = faultLogInfo->GetId(), 49020a203aSopenharmony_ci .type = faultLogInfo->GetFaultType(), 50020a203aSopenharmony_ci .ts = faultLogInfo->GetTimeStamp(), 51020a203aSopenharmony_ci .reason = faultLogInfo->GetFaultReason(), 52020a203aSopenharmony_ci .module = faultLogInfo->GetModuleName(), 53020a203aSopenharmony_ci .summary = faultLogInfo->GetFaultSummary(), 54020a203aSopenharmony_ci }; 55020a203aSopenharmony_ci 56020a203aSopenharmony_ci int fd = faultLogInfo->GetRawFileDescriptor(); 57020a203aSopenharmony_ci if (fd < 0) { 58020a203aSopenharmony_ci HIVIEW_LOGE("pid %{public}d Fail to get fd:%{public}d\n", faultLogInfo->GetProcessId(), fd); 59020a203aSopenharmony_ci ret.fullLog = "Fail to get log, fd is " + std::to_string(fd); 60020a203aSopenharmony_ci return ret; 61020a203aSopenharmony_ci } 62020a203aSopenharmony_ci while (fd >= 0) { 63020a203aSopenharmony_ci char buf[BUF_SIZE_512] = {0}; 64020a203aSopenharmony_ci int nread = TEMP_FAILURE_RETRY(read((fd), buf, BUF_SIZE_512 - 1)); 65020a203aSopenharmony_ci if (nread == -1) { 66020a203aSopenharmony_ci if (errno == EAGAIN) { 67020a203aSopenharmony_ci continue; 68020a203aSopenharmony_ci } else { 69020a203aSopenharmony_ci break; 70020a203aSopenharmony_ci } 71020a203aSopenharmony_ci } else if (nread == 0) { 72020a203aSopenharmony_ci break; 73020a203aSopenharmony_ci } 74020a203aSopenharmony_ci ret.fullLog += buf; 75020a203aSopenharmony_ci } 76020a203aSopenharmony_ci return ret; 77020a203aSopenharmony_ci} 78020a203aSopenharmony_ci 79020a203aSopenharmony_civoid FaultLogExecute(std::unique_ptr<CFaultLogInfoContext>& faultLogInfoContext) 80020a203aSopenharmony_ci{ 81020a203aSopenharmony_ci std::lock_guard<std::mutex> lock(g_mutex); 82020a203aSopenharmony_ci const int maxQueryCount = 10; 83020a203aSopenharmony_ci int currentCount = 0; 84020a203aSopenharmony_ci auto faultLogResult = QuerySelfFaultLog((FaultLogType)faultLogInfoContext->faultType, 85020a203aSopenharmony_ci maxQueryCount); 86020a203aSopenharmony_ci if (faultLogResult == nullptr) { 87020a203aSopenharmony_ci faultLogInfoContext->resolved = true; 88020a203aSopenharmony_ci return; 89020a203aSopenharmony_ci } 90020a203aSopenharmony_ci 91020a203aSopenharmony_ci while (faultLogResult->HasNext()) { 92020a203aSopenharmony_ci if (currentCount >= maxQueryCount) { 93020a203aSopenharmony_ci break; 94020a203aSopenharmony_ci } 95020a203aSopenharmony_ci auto faultLogInfo = faultLogResult->Next(); 96020a203aSopenharmony_ci if (faultLogInfo == nullptr) { 97020a203aSopenharmony_ci break; 98020a203aSopenharmony_ci } 99020a203aSopenharmony_ci currentCount++; 100020a203aSopenharmony_ci faultLogInfoContext->infoVector.push_back(ConvertInform(std::move(faultLogInfo))); 101020a203aSopenharmony_ci } 102020a203aSopenharmony_ci faultLogInfoContext->resolved = true; 103020a203aSopenharmony_ci} 104020a203aSopenharmony_ci 105020a203aSopenharmony_ciextern "C" { 106020a203aSopenharmony_ci CArrFaultLogInfo FfiFaultLoggerQuery(int32_t faultType, int32_t &code) 107020a203aSopenharmony_ci { 108020a203aSopenharmony_ci CArrFaultLogInfo faultInfos = {.head = nullptr, .size = 0}; 109020a203aSopenharmony_ci if (!CheckFaultloggerStatus()) { 110020a203aSopenharmony_ci code = ERR_SERVICE_STATUS; 111020a203aSopenharmony_ci return faultInfos; 112020a203aSopenharmony_ci } 113020a203aSopenharmony_ci 114020a203aSopenharmony_ci auto faultLogInfoContext = std::make_unique<CFaultLogInfoContext>(); 115020a203aSopenharmony_ci 116020a203aSopenharmony_ci faultLogInfoContext->faultType = faultType; 117020a203aSopenharmony_ci FaultLogExecute(faultLogInfoContext); 118020a203aSopenharmony_ci faultInfos.size = static_cast<int64_t>(faultLogInfoContext->infoVector.size()); 119020a203aSopenharmony_ci CFaultLogInfo *retValue = static_cast<CFaultLogInfo *>(malloc(sizeof(CFaultLogInfo) * faultInfos.size)); 120020a203aSopenharmony_ci if (faultLogInfoContext->resolved) { 121020a203aSopenharmony_ci int i = 0; 122020a203aSopenharmony_ci for (auto& infoItem : faultLogInfoContext->infoVector) { 123020a203aSopenharmony_ci retValue[i].pid = infoItem.pid; 124020a203aSopenharmony_ci retValue[i].uid = infoItem.uid; 125020a203aSopenharmony_ci retValue[i].faultLogType = infoItem.type; 126020a203aSopenharmony_ci retValue[i].timestamp = infoItem.ts; 127020a203aSopenharmony_ci retValue[i].reason = MallocCString(infoItem.reason); 128020a203aSopenharmony_ci retValue[i].module = MallocCString(infoItem.module); 129020a203aSopenharmony_ci retValue[i].summary = MallocCString(infoItem.summary); 130020a203aSopenharmony_ci retValue[i].fullLog = MallocCString(infoItem.fullLog); 131020a203aSopenharmony_ci ++i; 132020a203aSopenharmony_ci HIVIEW_LOGI("add element when resovled pid = %{public}d, uid = %{public}d, ts = %{public}" PRId64, 133020a203aSopenharmony_ci infoItem.pid, infoItem.uid, infoItem.ts); 134020a203aSopenharmony_ci } 135020a203aSopenharmony_ci faultInfos.head = retValue; 136020a203aSopenharmony_ci } else { 137020a203aSopenharmony_ci HIVIEW_LOGE("get signal info list failed"); 138020a203aSopenharmony_ci } 139020a203aSopenharmony_ci return faultInfos; 140020a203aSopenharmony_ci } 141020a203aSopenharmony_ci}