1020a203aSopenharmony_ci/*
2020a203aSopenharmony_ci * Copyright (c) 2021 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#include "faultlog_formatter.h"
16020a203aSopenharmony_ci
17020a203aSopenharmony_ci#include <cstdint>
18020a203aSopenharmony_ci#include <fstream>
19020a203aSopenharmony_ci#include <list>
20020a203aSopenharmony_ci#include "parameters.h"
21020a203aSopenharmony_ci#include <sstream>
22020a203aSopenharmony_ci#include <string>
23020a203aSopenharmony_ci#include <unistd.h>
24020a203aSopenharmony_ci
25020a203aSopenharmony_ci#include "faultlog_info.h"
26020a203aSopenharmony_ci#include "faultlog_util.h"
27020a203aSopenharmony_ci#include "file_util.h"
28020a203aSopenharmony_ci#include "string_util.h"
29020a203aSopenharmony_ci
30020a203aSopenharmony_cinamespace OHOS {
31020a203aSopenharmony_cinamespace HiviewDFX {
32020a203aSopenharmony_cinamespace FaultLogger {
33020a203aSopenharmony_cinamespace {
34020a203aSopenharmony_ciconstexpr int LOG_MAP_KEY = 0;
35020a203aSopenharmony_ciconstexpr int LOG_MAP_VALUE = 1;
36020a203aSopenharmony_ciconstexpr const char* const DEVICE_INFO[] = {"DEVICE_INFO", "Device info:"};
37020a203aSopenharmony_ciconstexpr const char* const BUILD_INFO[] = {"BUILD_INFO", "Build info:"};
38020a203aSopenharmony_ciconstexpr const char* const MODULE_NAME[] = {"MODULE", "Module name:"};
39020a203aSopenharmony_ciconstexpr const char* const PROCESS_NAME[] = {"PNAME", "Process name:"};
40020a203aSopenharmony_ciconstexpr const char* const MODULE_PID[] = {"PID", "Pid:"};
41020a203aSopenharmony_ciconstexpr const char* const MODULE_UID[] = {"UID", "Uid:"};
42020a203aSopenharmony_ciconstexpr const char* const MODULE_VERSION[] = {"VERSION", "Version:"};
43020a203aSopenharmony_ciconstexpr const char* const FAULT_TYPE[] = {"FAULT_TYPE", "Fault type:"};
44020a203aSopenharmony_ciconstexpr const char* const SYSVMTYPE[] = {"SYSVMTYPE", "SYSVMTYPE:"};
45020a203aSopenharmony_ciconstexpr const char* const APPVMTYPE[] = {"APPVMTYPE", "APPVMTYPE:"};
46020a203aSopenharmony_ciconstexpr const char* const FOREGROUND[] = {"FOREGROUND", "Foreground:"};
47020a203aSopenharmony_ciconstexpr const char* const LIFETIME[] = {"LIFETIME", "Up time:"};
48020a203aSopenharmony_ciconstexpr const char* const REASON[] = {"REASON", "Reason:"};
49020a203aSopenharmony_ciconstexpr const char* const FAULT_MESSAGE[] = {"FAULT_MESSAGE", "Fault message:"};
50020a203aSopenharmony_ciconstexpr const char* const STACKTRACE[] = {"TRUSTSTACK", "Selected stacktrace:\n"};
51020a203aSopenharmony_ciconstexpr const char* const ROOT_CAUSE[] = {"BINDERMAX", "Blocked chain:\n"};
52020a203aSopenharmony_ciconstexpr const char* const MSG_QUEUE_INFO[] = {"MSG_QUEUE_INFO", "Message queue info:\n"};
53020a203aSopenharmony_ciconstexpr const char* const BINDER_TRANSACTION_INFO[] = {"BINDER_TRANSACTION_INFO", "Binder transaction info:\n"};
54020a203aSopenharmony_ciconstexpr const char* const PROCESS_STACKTRACE[] = {"PROCESS_STACKTRACE", "Process stacktrace:\n"};
55020a203aSopenharmony_ciconstexpr const char* const OTHER_THREAD_INFO[] = {"OTHER_THREAD_INFO", "Other thread info:\n"};
56020a203aSopenharmony_ciconstexpr const char* const KEY_THREAD_INFO[] = {"KEY_THREAD_INFO", "Fault thread info:\n"};
57020a203aSopenharmony_ciconstexpr const char* const KEY_THREAD_REGISTERS[] = {"KEY_THREAD_REGISTERS", "Registers:\n"};
58020a203aSopenharmony_ciconstexpr const char* const MEMORY_USAGE[] = {"MEM_USAGE", "Memory Usage:\n"};
59020a203aSopenharmony_ciconstexpr const char* const CPU_USAGE[] = {"FAULTCPU", "CPU Usage:"};
60020a203aSopenharmony_ciconstexpr const char* const TRACE_ID[] = {"TRACEID", "Trace-Id:"};
61020a203aSopenharmony_ciconstexpr const char* const SUMMARY[] = {"SUMMARY", "Summary:\n"};
62020a203aSopenharmony_ciconstexpr const char* const TIMESTAMP[] = {"TIMESTAMP", "Timestamp:"};
63020a203aSopenharmony_ciconstexpr const char* const MEMORY_NEAR_REGISTERS[] = {"MEMORY_NEAR_REGISTERS", "Memory near registers:\n"};
64020a203aSopenharmony_ciconstexpr const char* const PRE_INSTALL[] = {"PRE_INSTALL", "PreInstalled:"};
65020a203aSopenharmony_ciconstexpr const char* const VERSION_CODE[] = {"VERSION_CODE", "VersionCode:"};
66020a203aSopenharmony_ciconstexpr const char* const FINGERPRINT[] = {"fingerPrint", "Fingerprint:"};
67020a203aSopenharmony_ciconstexpr const char* const APPEND_ORIGIN_LOG[] = {"APPEND_ORIGIN_LOG", ""};
68020a203aSopenharmony_ci
69020a203aSopenharmony_ciauto CPP_CRASH_LOG_SEQUENCE = {
70020a203aSopenharmony_ci    DEVICE_INFO, BUILD_INFO, FINGERPRINT, MODULE_NAME, MODULE_VERSION, VERSION_CODE,
71020a203aSopenharmony_ci    PRE_INSTALL, FOREGROUND, APPEND_ORIGIN_LOG, MODULE_PID, MODULE_UID, FAULT_TYPE,
72020a203aSopenharmony_ci    SYSVMTYPE, APPVMTYPE, REASON, FAULT_MESSAGE, TRACE_ID, PROCESS_NAME, KEY_THREAD_INFO,
73020a203aSopenharmony_ci    SUMMARY, KEY_THREAD_REGISTERS, OTHER_THREAD_INFO, MEMORY_NEAR_REGISTERS
74020a203aSopenharmony_ci};
75020a203aSopenharmony_ci
76020a203aSopenharmony_ciauto JAVASCRIPT_CRASH_LOG_SEQUENCE = {
77020a203aSopenharmony_ci    DEVICE_INFO, BUILD_INFO, FINGERPRINT, TIMESTAMP, MODULE_NAME, MODULE_VERSION, VERSION_CODE,
78020a203aSopenharmony_ci    PRE_INSTALL, FOREGROUND, MODULE_PID, MODULE_UID, FAULT_TYPE, FAULT_MESSAGE, SYSVMTYPE, APPVMTYPE,
79020a203aSopenharmony_ci    LIFETIME, REASON, TRACE_ID, SUMMARY
80020a203aSopenharmony_ci};
81020a203aSopenharmony_ci
82020a203aSopenharmony_ciauto APP_FREEZE_LOG_SEQUENCE = {
83020a203aSopenharmony_ci    DEVICE_INFO, BUILD_INFO, FINGERPRINT, TIMESTAMP, MODULE_NAME, MODULE_VERSION, VERSION_CODE,
84020a203aSopenharmony_ci    PRE_INSTALL, FOREGROUND, MODULE_PID, MODULE_UID, FAULT_TYPE, SYSVMTYPE,
85020a203aSopenharmony_ci    APPVMTYPE, REASON, TRACE_ID, CPU_USAGE, MEMORY_USAGE, ROOT_CAUSE, STACKTRACE,
86020a203aSopenharmony_ci    MSG_QUEUE_INFO, BINDER_TRANSACTION_INFO, PROCESS_STACKTRACE, SUMMARY
87020a203aSopenharmony_ci};
88020a203aSopenharmony_ci
89020a203aSopenharmony_ciauto SYS_FREEZE_LOG_SEQUENCE = {
90020a203aSopenharmony_ci    DEVICE_INFO, BUILD_INFO, FINGERPRINT, TIMESTAMP, MODULE_NAME, MODULE_VERSION, FOREGROUND,
91020a203aSopenharmony_ci    MODULE_PID, MODULE_UID, FAULT_TYPE, SYSVMTYPE, APPVMTYPE, REASON,
92020a203aSopenharmony_ci    TRACE_ID, CPU_USAGE, MEMORY_USAGE, ROOT_CAUSE, STACKTRACE,
93020a203aSopenharmony_ci    MSG_QUEUE_INFO, BINDER_TRANSACTION_INFO, PROCESS_STACKTRACE, SUMMARY
94020a203aSopenharmony_ci};
95020a203aSopenharmony_ci
96020a203aSopenharmony_ciauto SYS_WARNING_LOG_SEQUENCE = {
97020a203aSopenharmony_ci    DEVICE_INFO, BUILD_INFO, FINGERPRINT, TIMESTAMP, MODULE_NAME, MODULE_VERSION, FOREGROUND,
98020a203aSopenharmony_ci    MODULE_PID, MODULE_UID, FAULT_TYPE, SYSVMTYPE, APPVMTYPE, REASON,
99020a203aSopenharmony_ci    TRACE_ID, CPU_USAGE, MEMORY_USAGE, ROOT_CAUSE, STACKTRACE,
100020a203aSopenharmony_ci    MSG_QUEUE_INFO, BINDER_TRANSACTION_INFO, PROCESS_STACKTRACE, SUMMARY
101020a203aSopenharmony_ci};
102020a203aSopenharmony_ci
103020a203aSopenharmony_ciauto RUST_PANIC_LOG_SEQUENCE = {
104020a203aSopenharmony_ci    DEVICE_INFO, BUILD_INFO, FINGERPRINT, TIMESTAMP, MODULE_NAME, MODULE_VERSION, MODULE_PID,
105020a203aSopenharmony_ci    MODULE_UID, FAULT_TYPE, FAULT_MESSAGE, APPVMTYPE, REASON, SUMMARY
106020a203aSopenharmony_ci};
107020a203aSopenharmony_ci
108020a203aSopenharmony_ciauto ADDR_SANITIZER_LOG_SEQUENCE = {
109020a203aSopenharmony_ci    DEVICE_INFO, BUILD_INFO, FINGERPRINT, TIMESTAMP, MODULE_NAME, MODULE_VERSION, MODULE_PID,
110020a203aSopenharmony_ci    MODULE_UID, FAULT_TYPE, FAULT_MESSAGE, APPVMTYPE, REASON, SUMMARY
111020a203aSopenharmony_ci};
112020a203aSopenharmony_ci}
113020a203aSopenharmony_cistd::list<const char* const*> GetLogParseList(int32_t logType)
114020a203aSopenharmony_ci{
115020a203aSopenharmony_ci    switch (logType) {
116020a203aSopenharmony_ci        case FaultLogType::CPP_CRASH:
117020a203aSopenharmony_ci            return CPP_CRASH_LOG_SEQUENCE;
118020a203aSopenharmony_ci        case FaultLogType::JS_CRASH:
119020a203aSopenharmony_ci            return JAVASCRIPT_CRASH_LOG_SEQUENCE;
120020a203aSopenharmony_ci        case FaultLogType::APP_FREEZE:
121020a203aSopenharmony_ci            return APP_FREEZE_LOG_SEQUENCE;
122020a203aSopenharmony_ci        case FaultLogType::SYS_FREEZE:
123020a203aSopenharmony_ci            return SYS_FREEZE_LOG_SEQUENCE;
124020a203aSopenharmony_ci        case FaultLogType::SYS_WARNING:
125020a203aSopenharmony_ci            return SYS_WARNING_LOG_SEQUENCE;
126020a203aSopenharmony_ci        case FaultLogType::RUST_PANIC:
127020a203aSopenharmony_ci            return RUST_PANIC_LOG_SEQUENCE;
128020a203aSopenharmony_ci        case FaultLogType::ADDR_SANITIZER:
129020a203aSopenharmony_ci            return ADDR_SANITIZER_LOG_SEQUENCE;
130020a203aSopenharmony_ci        default:
131020a203aSopenharmony_ci            return {};
132020a203aSopenharmony_ci    }
133020a203aSopenharmony_ci}
134020a203aSopenharmony_ci
135020a203aSopenharmony_cistd::string GetSummaryByType(int32_t logType, std::map<std::string, std::string> sections)
136020a203aSopenharmony_ci{
137020a203aSopenharmony_ci    std::string summary = "";
138020a203aSopenharmony_ci    switch (logType) {
139020a203aSopenharmony_ci        case FaultLogType::JS_CRASH:
140020a203aSopenharmony_ci        case FaultLogType::APP_FREEZE:
141020a203aSopenharmony_ci        case FaultLogType::SYS_FREEZE:
142020a203aSopenharmony_ci        case FaultLogType::SYS_WARNING:
143020a203aSopenharmony_ci            summary = sections[STACKTRACE[LOG_MAP_KEY]];
144020a203aSopenharmony_ci            break;
145020a203aSopenharmony_ci        case FaultLogType::CPP_CRASH:
146020a203aSopenharmony_ci            summary = sections[KEY_THREAD_INFO[LOG_MAP_KEY]];
147020a203aSopenharmony_ci            break;
148020a203aSopenharmony_ci        case FaultLogType::ADDR_SANITIZER:
149020a203aSopenharmony_ci        default:
150020a203aSopenharmony_ci            summary = "Could not figure out summary for this fault.";
151020a203aSopenharmony_ci            break;
152020a203aSopenharmony_ci    }
153020a203aSopenharmony_ci
154020a203aSopenharmony_ci    return summary;
155020a203aSopenharmony_ci}
156020a203aSopenharmony_ci
157020a203aSopenharmony_cibool ParseFaultLogLine(const std::list<const char* const*>& parseList, const std::string& line,
158020a203aSopenharmony_ci    const std::string& multline, std::string& multlineName, FaultLogInfo& info)
159020a203aSopenharmony_ci{
160020a203aSopenharmony_ci    for (auto &item : parseList) {
161020a203aSopenharmony_ci        if (strlen(item[LOG_MAP_VALUE]) <= 1) {
162020a203aSopenharmony_ci            continue;
163020a203aSopenharmony_ci        }
164020a203aSopenharmony_ci        std::string sectionHead = std::string(item[LOG_MAP_VALUE], strlen(item[LOG_MAP_VALUE]) - 1);
165020a203aSopenharmony_ci        if (line.find(sectionHead) == std::string::npos) {
166020a203aSopenharmony_ci            continue;
167020a203aSopenharmony_ci        }
168020a203aSopenharmony_ci        if (!line.empty() && line.at(line.size() - 1) == ':') {
169020a203aSopenharmony_ci            if ((item[LOG_MAP_KEY] != multlineName) && (!multline.empty())) {
170020a203aSopenharmony_ci                info.sectionMap[multlineName] = multline;
171020a203aSopenharmony_ci            }
172020a203aSopenharmony_ci            multlineName = item[LOG_MAP_KEY];
173020a203aSopenharmony_ci        } else {
174020a203aSopenharmony_ci            info.sectionMap[item[LOG_MAP_KEY]] = line.substr(line.find_first_of(":") + 1);
175020a203aSopenharmony_ci        }
176020a203aSopenharmony_ci        return false;
177020a203aSopenharmony_ci    }
178020a203aSopenharmony_ci    return true;
179020a203aSopenharmony_ci}
180020a203aSopenharmony_ci
181020a203aSopenharmony_civoid WriteStackTraceFromLog(int32_t fd, const std::string& pidStr, const std::string& path)
182020a203aSopenharmony_ci{
183020a203aSopenharmony_ci    std::string realPath;
184020a203aSopenharmony_ci    if (!FileUtil::PathToRealPath(path, realPath)) {
185020a203aSopenharmony_ci        FileUtil::SaveStringToFd(fd, "Log file not exist.\n");
186020a203aSopenharmony_ci        return;
187020a203aSopenharmony_ci    }
188020a203aSopenharmony_ci
189020a203aSopenharmony_ci    std::ifstream logFile(realPath);
190020a203aSopenharmony_ci    std::string line;
191020a203aSopenharmony_ci    bool startWrite = false;
192020a203aSopenharmony_ci    while (std::getline(logFile, line)) {
193020a203aSopenharmony_ci        if (!logFile.good()) {
194020a203aSopenharmony_ci            break;
195020a203aSopenharmony_ci        }
196020a203aSopenharmony_ci
197020a203aSopenharmony_ci        if (line.empty()) {
198020a203aSopenharmony_ci            continue;
199020a203aSopenharmony_ci        }
200020a203aSopenharmony_ci
201020a203aSopenharmony_ci        if ((line.find("----- pid") != std::string::npos) &&
202020a203aSopenharmony_ci            (line.find(pidStr) != std::string::npos)) {
203020a203aSopenharmony_ci            startWrite = true;
204020a203aSopenharmony_ci        }
205020a203aSopenharmony_ci
206020a203aSopenharmony_ci        if ((line.find("----- end") != std::string::npos) &&
207020a203aSopenharmony_ci            (line.find(pidStr) != std::string::npos)) {
208020a203aSopenharmony_ci            FileUtil::SaveStringToFd(fd, line + "\n");
209020a203aSopenharmony_ci            break;
210020a203aSopenharmony_ci        }
211020a203aSopenharmony_ci
212020a203aSopenharmony_ci        if (startWrite) {
213020a203aSopenharmony_ci            FileUtil::SaveStringToFd(fd, line + "\n");
214020a203aSopenharmony_ci        }
215020a203aSopenharmony_ci    }
216020a203aSopenharmony_ci}
217020a203aSopenharmony_ci
218020a203aSopenharmony_civoid WriteDfxLogToFile(int32_t fd)
219020a203aSopenharmony_ci{
220020a203aSopenharmony_ci    std::string dfxStr = std::string("Generated by HiviewDFX@OpenHarmony\n");
221020a203aSopenharmony_ci    std::string sepStr = std::string("================================================================\n");
222020a203aSopenharmony_ci    FileUtil::SaveStringToFd(fd, dfxStr);
223020a203aSopenharmony_ci    FileUtil::SaveStringToFd(fd, sepStr);
224020a203aSopenharmony_ci}
225020a203aSopenharmony_ci
226020a203aSopenharmony_civoid WriteFaultLogToFile(int32_t fd, int32_t logType, std::map<std::string, std::string> sections)
227020a203aSopenharmony_ci{
228020a203aSopenharmony_ci    auto seq = GetLogParseList(logType);
229020a203aSopenharmony_ci    for (auto &item : seq) {
230020a203aSopenharmony_ci        auto value = sections[item[LOG_MAP_KEY]];
231020a203aSopenharmony_ci        if (!value.empty()) {
232020a203aSopenharmony_ci            std::string keyStr = item[LOG_MAP_KEY];
233020a203aSopenharmony_ci            if (keyStr.find(APPEND_ORIGIN_LOG[LOG_MAP_KEY]) != std::string::npos) {
234020a203aSopenharmony_ci                if (WriteLogToFile(fd, value)) {
235020a203aSopenharmony_ci                    break;
236020a203aSopenharmony_ci                }
237020a203aSopenharmony_ci            }
238020a203aSopenharmony_ci
239020a203aSopenharmony_ci            // Does not require adding an identifier header for Summary section
240020a203aSopenharmony_ci            if (keyStr.find(SUMMARY[LOG_MAP_KEY]) == std::string::npos) {
241020a203aSopenharmony_ci                FileUtil::SaveStringToFd(fd, item[LOG_MAP_VALUE]);
242020a203aSopenharmony_ci            }
243020a203aSopenharmony_ci
244020a203aSopenharmony_ci            if (value.back() != '\n') {
245020a203aSopenharmony_ci                value.append("\n");
246020a203aSopenharmony_ci            }
247020a203aSopenharmony_ci            FileUtil::SaveStringToFd(fd, value);
248020a203aSopenharmony_ci        }
249020a203aSopenharmony_ci    }
250020a203aSopenharmony_ci
251020a203aSopenharmony_ci    if (!sections["KEYLOGFILE"].empty()) {
252020a203aSopenharmony_ci        FileUtil::SaveStringToFd(fd, "Additional Logs:\n");
253020a203aSopenharmony_ci        WriteStackTraceFromLog(fd, sections["PID"], sections["KEYLOGFILE"]);
254020a203aSopenharmony_ci    }
255020a203aSopenharmony_ci}
256020a203aSopenharmony_ci
257020a203aSopenharmony_cistatic void UpdateFaultLogInfoFromTempFile(FaultLogInfo& info)
258020a203aSopenharmony_ci{
259020a203aSopenharmony_ci    if (!info.module.empty()) {
260020a203aSopenharmony_ci        return;
261020a203aSopenharmony_ci    }
262020a203aSopenharmony_ci
263020a203aSopenharmony_ci    StringUtil::ConvertStringTo<int32_t>(info.sectionMap[MODULE_UID[LOG_MAP_KEY]], info.id);
264020a203aSopenharmony_ci    info.module = info.sectionMap[PROCESS_NAME[LOG_MAP_KEY]];
265020a203aSopenharmony_ci    info.reason = info.sectionMap[REASON[LOG_MAP_KEY]];
266020a203aSopenharmony_ci    info.summary = info.sectionMap[KEY_THREAD_INFO[LOG_MAP_KEY]];
267020a203aSopenharmony_ci    info.registers = info.sectionMap[KEY_THREAD_REGISTERS[LOG_MAP_KEY]];
268020a203aSopenharmony_ci    info.otherThreadInfo = info.sectionMap[OTHER_THREAD_INFO[LOG_MAP_KEY]];
269020a203aSopenharmony_ci    size_t removeStartPos = info.summary.find("Tid:");
270020a203aSopenharmony_ci    size_t removeEndPos = info.summary.find("Name:");
271020a203aSopenharmony_ci    if (removeStartPos != std::string::npos && removeEndPos != std::string::npos) {
272020a203aSopenharmony_ci        auto iterator = info.summary.begin() + removeEndPos;
273020a203aSopenharmony_ci        while (iterator != info.summary.end() && *iterator != '\n') {
274020a203aSopenharmony_ci            if (isdigit(*iterator)) {
275020a203aSopenharmony_ci                iterator = info.summary.erase(iterator);
276020a203aSopenharmony_ci            } else {
277020a203aSopenharmony_ci                iterator++;
278020a203aSopenharmony_ci            }
279020a203aSopenharmony_ci        }
280020a203aSopenharmony_ci        info.summary.replace(removeStartPos, removeEndPos - removeStartPos + 1, "Thread n");
281020a203aSopenharmony_ci    }
282020a203aSopenharmony_ci}
283020a203aSopenharmony_ci
284020a203aSopenharmony_ciFaultLogInfo ParseFaultLogInfoFromFile(const std::string &path, bool isTempFile)
285020a203aSopenharmony_ci{
286020a203aSopenharmony_ci    auto fileName = FileUtil::ExtractFileName(path);
287020a203aSopenharmony_ci    FaultLogInfo info;
288020a203aSopenharmony_ci    if (!isTempFile) {
289020a203aSopenharmony_ci        info = ExtractInfoFromFileName(fileName);
290020a203aSopenharmony_ci    } else {
291020a203aSopenharmony_ci        info = ExtractInfoFromTempFile(fileName);
292020a203aSopenharmony_ci    }
293020a203aSopenharmony_ci
294020a203aSopenharmony_ci    auto parseList = GetLogParseList(info.faultLogType);
295020a203aSopenharmony_ci    std::ifstream logFile(path);
296020a203aSopenharmony_ci    std::string line;
297020a203aSopenharmony_ci    std::string multline;
298020a203aSopenharmony_ci    std::string multlineName;
299020a203aSopenharmony_ci    while (std::getline(logFile, line)) {
300020a203aSopenharmony_ci        if (!logFile.good()) {
301020a203aSopenharmony_ci            break;
302020a203aSopenharmony_ci        }
303020a203aSopenharmony_ci
304020a203aSopenharmony_ci        if (line.empty()) {
305020a203aSopenharmony_ci            continue;
306020a203aSopenharmony_ci        }
307020a203aSopenharmony_ci
308020a203aSopenharmony_ci        if (ParseFaultLogLine(parseList, line, multline, multlineName, info)) {
309020a203aSopenharmony_ci            multline.append(line).append("\n");
310020a203aSopenharmony_ci        } else {
311020a203aSopenharmony_ci            multline.clear();
312020a203aSopenharmony_ci        }
313020a203aSopenharmony_ci    }
314020a203aSopenharmony_ci
315020a203aSopenharmony_ci    if (!multline.empty() && !multlineName.empty()) {
316020a203aSopenharmony_ci        info.sectionMap[multlineName] = multline;
317020a203aSopenharmony_ci    }
318020a203aSopenharmony_ci    UpdateFaultLogInfoFromTempFile(info);
319020a203aSopenharmony_ci    return info;
320020a203aSopenharmony_ci}
321020a203aSopenharmony_ci
322020a203aSopenharmony_cibool WriteLogToFile(int32_t fd, const std::string& path)
323020a203aSopenharmony_ci{
324020a203aSopenharmony_ci    if ((fd < 0) || path.empty()) {
325020a203aSopenharmony_ci        return false;
326020a203aSopenharmony_ci    }
327020a203aSopenharmony_ci
328020a203aSopenharmony_ci    std::string line;
329020a203aSopenharmony_ci    std::ifstream logFile(path);
330020a203aSopenharmony_ci    bool hasFindFirstLine = false;
331020a203aSopenharmony_ci    while (std::getline(logFile, line)) {
332020a203aSopenharmony_ci        if (logFile.eof()) {
333020a203aSopenharmony_ci            break;
334020a203aSopenharmony_ci        }
335020a203aSopenharmony_ci        if (!logFile.good()) {
336020a203aSopenharmony_ci            return false;
337020a203aSopenharmony_ci        }
338020a203aSopenharmony_ci        if (!hasFindFirstLine && line.find("Build info:") != std::string::npos) {
339020a203aSopenharmony_ci            continue;
340020a203aSopenharmony_ci        }
341020a203aSopenharmony_ci        hasFindFirstLine = true;
342020a203aSopenharmony_ci        FileUtil::SaveStringToFd(fd, line);
343020a203aSopenharmony_ci        FileUtil::SaveStringToFd(fd, "\n");
344020a203aSopenharmony_ci    }
345020a203aSopenharmony_ci    return true;
346020a203aSopenharmony_ci}
347020a203aSopenharmony_ci
348020a203aSopenharmony_cibool IsFaultLogLimit()
349020a203aSopenharmony_ci{
350020a203aSopenharmony_ci    std::string isDev = OHOS::system::GetParameter("const.security.developermode.state", "");
351020a203aSopenharmony_ci    std::string isBeta = OHOS::system::GetParameter("const.logsystem.versiontype", "");
352020a203aSopenharmony_ci    if ((isDev == "true") || (isBeta == "beta")) {
353020a203aSopenharmony_ci        return false;
354020a203aSopenharmony_ci    }
355020a203aSopenharmony_ci    return true;
356020a203aSopenharmony_ci}
357020a203aSopenharmony_ci
358020a203aSopenharmony_civoid LimitCppCrashLog(int32_t fd, int32_t logType)
359020a203aSopenharmony_ci{
360020a203aSopenharmony_ci    if ((fd < 0) || (logType != FaultLogType::CPP_CRASH) || !IsFaultLogLimit()) {
361020a203aSopenharmony_ci        return;
362020a203aSopenharmony_ci    }
363020a203aSopenharmony_ci    constexpr int maxLogSize = 512 * 1024;
364020a203aSopenharmony_ci    off_t  endPos = lseek(fd, 0, SEEK_END);
365020a203aSopenharmony_ci    if ((endPos == -1) || (endPos <= maxLogSize)) {
366020a203aSopenharmony_ci        return;
367020a203aSopenharmony_ci    }
368020a203aSopenharmony_ci
369020a203aSopenharmony_ci    if (ftruncate(fd, maxLogSize) < 0) {
370020a203aSopenharmony_ci        return;
371020a203aSopenharmony_ci    }
372020a203aSopenharmony_ci    endPos = lseek(fd, maxLogSize, SEEK_SET);
373020a203aSopenharmony_ci    if (endPos != -1) {
374020a203aSopenharmony_ci        FileUtil::SaveStringToFd(fd, "\ncpp crash log is limit output.\n");
375020a203aSopenharmony_ci    }
376020a203aSopenharmony_ci}
377020a203aSopenharmony_ci} // namespace FaultLogger
378020a203aSopenharmony_ci} // namespace HiviewDFX
379020a203aSopenharmony_ci} // namespace OHOS
380