1800b99b8Sopenharmony_ci/*
2800b99b8Sopenharmony_ci * Copyright (c) 2023 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#include "crash_validator.h"
16800b99b8Sopenharmony_ci
17800b99b8Sopenharmony_ci#include <cinttypes>
18800b99b8Sopenharmony_ci#include <csignal>
19800b99b8Sopenharmony_ci#ifdef HISYSEVENT_ENABLE
20800b99b8Sopenharmony_ci#include <fcntl.h>
21800b99b8Sopenharmony_ci#include <hisysevent.h>
22800b99b8Sopenharmony_ci#include <securec.h>
23800b99b8Sopenharmony_ci#include <unistd.h>
24800b99b8Sopenharmony_ci
25800b99b8Sopenharmony_ci#include "hisysevent_manager.h"
26800b99b8Sopenharmony_ci
27800b99b8Sopenharmony_cinamespace OHOS {
28800b99b8Sopenharmony_cinamespace HiviewDFX {
29800b99b8Sopenharmony_cinamespace {
30800b99b8Sopenharmony_ciconstexpr char EVENT_CPP_CRASH[] = "CPP_CRASH";
31800b99b8Sopenharmony_ciconstexpr char KEY_PROCESS_EXIT[] = "PROCESS_EXIT";
32800b99b8Sopenharmony_ciconstexpr char KEY_NAME[] = "PROCESS_NAME";
33800b99b8Sopenharmony_ciconstexpr char KEY_PID[] = "PID";
34800b99b8Sopenharmony_ciconstexpr char KEY_UID[] = "UID";
35800b99b8Sopenharmony_ciconstexpr char KEY_STATUS[] = "STATUS";
36800b99b8Sopenharmony_ciconstexpr char KEY_LOG_PATH[] = "LOG_PATH";
37800b99b8Sopenharmony_ciconstexpr char KEY_MODULE[] = "MODULE";
38800b99b8Sopenharmony_ciconstexpr char INIT_LOG_PATTERN[] = "Service warning ";
39800b99b8Sopenharmony_ciconstexpr char KEY_NO_LOG_EVENT_NAME[] = "CPP_CRASH_NO_LOG";
40800b99b8Sopenharmony_ciconstexpr char KEY_HAPPEN_TIME[] = "HAPPEN_TIME";
41800b99b8Sopenharmony_ciconstexpr int32_t LOG_SIZE = 1024;
42800b99b8Sopenharmony_ciconstexpr uint64_t MAX_LOG_GENERATE_TIME = 600; // 600 seconds
43800b99b8Sopenharmony_ciconstexpr int32_t KMSG_SIZE = 2049;
44800b99b8Sopenharmony_ci}
45800b99b8Sopenharmony_ciCrashValidator::CrashValidator() : stopReadKmsg_(false), totalEventCount_(0),
46800b99b8Sopenharmony_ci    normalEventCount_(0), kmsgReaderThread_(nullptr)
47800b99b8Sopenharmony_ci{
48800b99b8Sopenharmony_ci}
49800b99b8Sopenharmony_ci
50800b99b8Sopenharmony_ciCrashValidator::~CrashValidator()
51800b99b8Sopenharmony_ci{
52800b99b8Sopenharmony_ci    if (kmsgReaderThread_ != nullptr) {
53800b99b8Sopenharmony_ci        kmsgReaderThread_ = nullptr;
54800b99b8Sopenharmony_ci    }
55800b99b8Sopenharmony_ci}
56800b99b8Sopenharmony_ci
57800b99b8Sopenharmony_civoid CrashValidator::OnEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent)
58800b99b8Sopenharmony_ci{
59800b99b8Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
60800b99b8Sopenharmony_ci    if (sysEvent == nullptr) {
61800b99b8Sopenharmony_ci        return;
62800b99b8Sopenharmony_ci    }
63800b99b8Sopenharmony_ci    auto domain = sysEvent->GetDomain();
64800b99b8Sopenharmony_ci    auto eventName = sysEvent->GetEventName();
65800b99b8Sopenharmony_ci    if (eventName == EVENT_CPP_CRASH) {
66800b99b8Sopenharmony_ci        HandleCppCrashEvent(sysEvent);
67800b99b8Sopenharmony_ci    } else if (eventName == KEY_PROCESS_EXIT) {
68800b99b8Sopenharmony_ci        HandleProcessExitEvent(sysEvent);
69800b99b8Sopenharmony_ci    }
70800b99b8Sopenharmony_ci}
71800b99b8Sopenharmony_ci
72800b99b8Sopenharmony_civoid CrashValidator::OnServiceDied()
73800b99b8Sopenharmony_ci{
74800b99b8Sopenharmony_ci    printf("SysEventServiceDied?.\n");
75800b99b8Sopenharmony_ci}
76800b99b8Sopenharmony_ci
77800b99b8Sopenharmony_cibool CrashValidator::InitSysEventListener()
78800b99b8Sopenharmony_ci{
79800b99b8Sopenharmony_ci    std::vector<ListenerRule> sysRules;
80800b99b8Sopenharmony_ci    sysRules.emplace_back("RELIABILITY", "CPP_CRASH");
81800b99b8Sopenharmony_ci    sysRules.emplace_back("STARTUP", "PROCESS_EXIT");
82800b99b8Sopenharmony_ci    if (HiSysEventManager::AddListener(shared_from_this(), sysRules) != 0) {
83800b99b8Sopenharmony_ci        return false;
84800b99b8Sopenharmony_ci    }
85800b99b8Sopenharmony_ci
86800b99b8Sopenharmony_ci    kmsgReaderThread_ = std::make_unique<std::thread>([this] {
87800b99b8Sopenharmony_ci        ReadServiceCrashStatus();
88800b99b8Sopenharmony_ci    });
89800b99b8Sopenharmony_ci    kmsgReaderThread_->detach();
90800b99b8Sopenharmony_ci    return true;
91800b99b8Sopenharmony_ci}
92800b99b8Sopenharmony_ci
93800b99b8Sopenharmony_civoid CrashValidator::RemoveSysEventListener()
94800b99b8Sopenharmony_ci{
95800b99b8Sopenharmony_ci    int32_t result = HiSysEventManager::RemoveListener(shared_from_this());
96800b99b8Sopenharmony_ci    printf("remove listener result: %d\n", result);
97800b99b8Sopenharmony_ci}
98800b99b8Sopenharmony_ci
99800b99b8Sopenharmony_civoid CrashValidator::PrintEvents(int fd, const std::vector<CrashEvent>& events, bool isMatched)
100800b99b8Sopenharmony_ci{
101800b99b8Sopenharmony_ci    std::vector<CrashEvent>::const_iterator it = events.begin();
102800b99b8Sopenharmony_ci    while (it != events.end()) {
103800b99b8Sopenharmony_ci        if (isMatched) {
104800b99b8Sopenharmony_ci            dprintf(fd, "Module:%s Time:%" PRIu64 " Pid:%" PRIu64 " Uid:%" PRIu64 "\n",
105800b99b8Sopenharmony_ci                it->name.c_str(),
106800b99b8Sopenharmony_ci                static_cast<uint64_t>(it->time),
107800b99b8Sopenharmony_ci                static_cast<uint64_t>(it->pid),
108800b99b8Sopenharmony_ci                static_cast<uint64_t>(it->uid));
109800b99b8Sopenharmony_ci        } else {
110800b99b8Sopenharmony_ci            dprintf(fd, "Module:%s Time:%" PRIu64 " Pid:%" PRIu64 " Uid:%" PRIu64 " HasLog:%d\n",
111800b99b8Sopenharmony_ci                it->name.c_str(),
112800b99b8Sopenharmony_ci                static_cast<uint64_t>(it->time),
113800b99b8Sopenharmony_ci                static_cast<uint64_t>(it->pid),
114800b99b8Sopenharmony_ci                static_cast<uint64_t>(it->uid),
115800b99b8Sopenharmony_ci                it->isCppCrash);
116800b99b8Sopenharmony_ci        }
117800b99b8Sopenharmony_ci        ++it;
118800b99b8Sopenharmony_ci    }
119800b99b8Sopenharmony_ci}
120800b99b8Sopenharmony_ci
121800b99b8Sopenharmony_civoid CrashValidator::Dump(int fd)
122800b99b8Sopenharmony_ci{
123800b99b8Sopenharmony_ci    dprintf(fd, "Summary:\n");
124800b99b8Sopenharmony_ci    dprintf(fd, "Total Signaled Process:%d\n", totalEventCount_);
125800b99b8Sopenharmony_ci    dprintf(fd, "Total CppCrash Count:%d\n", normalEventCount_);
126800b99b8Sopenharmony_ci    if (totalEventCount_ > 0) {
127800b99b8Sopenharmony_ci        dprintf(fd, "CppCrash detect rate:%d%%\n",
128800b99b8Sopenharmony_ci            (normalEventCount_ * 100) / totalEventCount_); // 100 : percent ratio
129800b99b8Sopenharmony_ci    }
130800b99b8Sopenharmony_ci
131800b99b8Sopenharmony_ci    std::lock_guard<std::mutex> lock(lock_);
132800b99b8Sopenharmony_ci    if (!noLogEvents_.empty()) {
133800b99b8Sopenharmony_ci        dprintf(fd, "No CppCrash Log Events(%zu):\n", noLogEvents_.size());
134800b99b8Sopenharmony_ci        PrintEvents(fd, noLogEvents_, false);
135800b99b8Sopenharmony_ci    }
136800b99b8Sopenharmony_ci
137800b99b8Sopenharmony_ci    if (!pendingEvents_.empty()) {
138800b99b8Sopenharmony_ci        dprintf(fd, "Pending CppCrash Log Events(%zu):\n", pendingEvents_.size());
139800b99b8Sopenharmony_ci        PrintEvents(fd, pendingEvents_, false);
140800b99b8Sopenharmony_ci    }
141800b99b8Sopenharmony_ci
142800b99b8Sopenharmony_ci    if (!matchedEvents_.empty()) {
143800b99b8Sopenharmony_ci        dprintf(fd, "Matched Events(%zu):\n", matchedEvents_.size());
144800b99b8Sopenharmony_ci        PrintEvents(fd, matchedEvents_, true);
145800b99b8Sopenharmony_ci    }
146800b99b8Sopenharmony_ci}
147800b99b8Sopenharmony_ci
148800b99b8Sopenharmony_cibool CrashValidator::RemoveSimilarEvent(const CrashEvent& event)
149800b99b8Sopenharmony_ci{
150800b99b8Sopenharmony_ci    for (const auto& matchedEvent : matchedEvents_) {
151800b99b8Sopenharmony_ci        if (matchedEvent.pid == event.pid && matchedEvent.uid == event.uid) {
152800b99b8Sopenharmony_ci            return true;
153800b99b8Sopenharmony_ci        }
154800b99b8Sopenharmony_ci    }
155800b99b8Sopenharmony_ci    std::vector<CrashEvent>::iterator it = pendingEvents_.begin();
156800b99b8Sopenharmony_ci    while (it != pendingEvents_.end()) {
157800b99b8Sopenharmony_ci        if (it->uid == event.uid && it->pid == event.pid) {
158800b99b8Sopenharmony_ci            if (it->isCppCrash != event.isCppCrash) {
159800b99b8Sopenharmony_ci                it = pendingEvents_.erase(it);
160800b99b8Sopenharmony_ci                normalEventCount_++;
161800b99b8Sopenharmony_ci                matchedEvents_.push_back(event);
162800b99b8Sopenharmony_ci            }
163800b99b8Sopenharmony_ci            return true;
164800b99b8Sopenharmony_ci        } else {
165800b99b8Sopenharmony_ci            ++it;
166800b99b8Sopenharmony_ci        }
167800b99b8Sopenharmony_ci    }
168800b99b8Sopenharmony_ci    return false;
169800b99b8Sopenharmony_ci}
170800b99b8Sopenharmony_ci
171800b99b8Sopenharmony_civoid CrashValidator::HandleCppCrashEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent)
172800b99b8Sopenharmony_ci{
173800b99b8Sopenharmony_ci    if (sysEvent == nullptr) {
174800b99b8Sopenharmony_ci        return;
175800b99b8Sopenharmony_ci    }
176800b99b8Sopenharmony_ci    CrashEvent crashEvent;
177800b99b8Sopenharmony_ci    crashEvent.isCppCrash = true;
178800b99b8Sopenharmony_ci    sysEvent->GetParamValue(KEY_HAPPEN_TIME, crashEvent.time);
179800b99b8Sopenharmony_ci    sysEvent->GetParamValue(KEY_UID, crashEvent.uid);
180800b99b8Sopenharmony_ci    sysEvent->GetParamValue(KEY_PID, crashEvent.pid);
181800b99b8Sopenharmony_ci    sysEvent->GetParamValue(KEY_LOG_PATH, crashEvent.path);
182800b99b8Sopenharmony_ci    sysEvent->GetParamValue(KEY_MODULE, crashEvent.name);
183800b99b8Sopenharmony_ci    printf("CPPCRASH:[Pid:%" PRIi64 " Uid:%" PRIi64 " Module:%s]\n",
184800b99b8Sopenharmony_ci        crashEvent.pid, crashEvent.uid, crashEvent.name.c_str());
185800b99b8Sopenharmony_ci    if (!RemoveSimilarEvent(crashEvent)) {
186800b99b8Sopenharmony_ci        totalEventCount_++;
187800b99b8Sopenharmony_ci        pendingEvents_.push_back(crashEvent);
188800b99b8Sopenharmony_ci    }
189800b99b8Sopenharmony_ci}
190800b99b8Sopenharmony_ci
191800b99b8Sopenharmony_civoid CrashValidator::HandleProcessExitEvent(std::shared_ptr<HiviewDFX::HiSysEventRecord> sysEvent)
192800b99b8Sopenharmony_ci{
193800b99b8Sopenharmony_ci    if (sysEvent == nullptr) {
194800b99b8Sopenharmony_ci        return;
195800b99b8Sopenharmony_ci    }
196800b99b8Sopenharmony_ci    int64_t status64 = 0;
197800b99b8Sopenharmony_ci    sysEvent->GetParamValue(KEY_STATUS, status64);
198800b99b8Sopenharmony_ci    int32_t status = static_cast<int32_t>(status64);
199800b99b8Sopenharmony_ci    if (!WIFSIGNALED(status) && !WIFEXITED(status)) {
200800b99b8Sopenharmony_ci        return;
201800b99b8Sopenharmony_ci    }
202800b99b8Sopenharmony_ci
203800b99b8Sopenharmony_ci    CrashEvent crashEvent;
204800b99b8Sopenharmony_ci    crashEvent.isCppCrash = false;
205800b99b8Sopenharmony_ci    crashEvent.time = sysEvent->GetTime();
206800b99b8Sopenharmony_ci    sysEvent->GetParamValue(KEY_UID, crashEvent.uid);
207800b99b8Sopenharmony_ci    sysEvent->GetParamValue(KEY_PID, crashEvent.pid);
208800b99b8Sopenharmony_ci    sysEvent->GetParamValue(KEY_NAME, crashEvent.name);
209800b99b8Sopenharmony_ci    int exitSigno = WTERMSIG(status);
210800b99b8Sopenharmony_ci    // crash in pid namespace exit signo is zero, instead of use exit status code.
211800b99b8Sopenharmony_ci    if (exitSigno == 0) {
212800b99b8Sopenharmony_ci        exitSigno = WEXITSTATUS(status);
213800b99b8Sopenharmony_ci    }
214800b99b8Sopenharmony_ci
215800b99b8Sopenharmony_ci    int interestedSignalList[] = {
216800b99b8Sopenharmony_ci        SIGABRT, SIGBUS, SIGFPE, SIGILL,
217800b99b8Sopenharmony_ci        SIGSEGV, SIGSTKFLT, SIGSYS, SIGTRAP };
218800b99b8Sopenharmony_ci    bool shouldGenerateCppCrash = false;
219800b99b8Sopenharmony_ci    for (size_t i = 0; i < sizeof(interestedSignalList) / sizeof(interestedSignalList[0]); i++) {
220800b99b8Sopenharmony_ci        if (interestedSignalList[i] == exitSigno) {
221800b99b8Sopenharmony_ci            shouldGenerateCppCrash = true;
222800b99b8Sopenharmony_ci            break;
223800b99b8Sopenharmony_ci        }
224800b99b8Sopenharmony_ci    }
225800b99b8Sopenharmony_ci
226800b99b8Sopenharmony_ci    if (!shouldGenerateCppCrash) {
227800b99b8Sopenharmony_ci        return;
228800b99b8Sopenharmony_ci    }
229800b99b8Sopenharmony_ci
230800b99b8Sopenharmony_ci    printf("Process Exit Name:%s Time:%llu [Pid:%" PRIi64 " Uid:%" PRIi64 "] status:%d\n",
231800b99b8Sopenharmony_ci        crashEvent.name.c_str(),
232800b99b8Sopenharmony_ci        static_cast<unsigned long long>(crashEvent.time),
233800b99b8Sopenharmony_ci        crashEvent.pid,
234800b99b8Sopenharmony_ci        crashEvent.uid,
235800b99b8Sopenharmony_ci        status);
236800b99b8Sopenharmony_ci    if (!RemoveSimilarEvent(crashEvent)) {
237800b99b8Sopenharmony_ci        totalEventCount_++;
238800b99b8Sopenharmony_ci        pendingEvents_.push_back(crashEvent);
239800b99b8Sopenharmony_ci    }
240800b99b8Sopenharmony_ci}
241800b99b8Sopenharmony_ci
242800b99b8Sopenharmony_civoid CrashValidator::CheckOutOfDateEvents()
243800b99b8Sopenharmony_ci{
244800b99b8Sopenharmony_ci    std::vector<CrashEvent>::iterator it = pendingEvents_.begin();
245800b99b8Sopenharmony_ci    while (it != pendingEvents_.end()) {
246800b99b8Sopenharmony_ci        uint64_t now = time(nullptr);
247800b99b8Sopenharmony_ci        uint64_t eventTime = it->time;
248800b99b8Sopenharmony_ci        if (eventTime > now) {
249800b99b8Sopenharmony_ci            eventTime = eventTime / 1000; // 1000 : convert to second
250800b99b8Sopenharmony_ci        }
251800b99b8Sopenharmony_ci
252800b99b8Sopenharmony_ci        if (now > eventTime && now - eventTime < MAX_LOG_GENERATE_TIME) {
253800b99b8Sopenharmony_ci            ++it;
254800b99b8Sopenharmony_ci            continue;
255800b99b8Sopenharmony_ci        }
256800b99b8Sopenharmony_ci
257800b99b8Sopenharmony_ci        if (!it->isCppCrash) {
258800b99b8Sopenharmony_ci            HiSysEventWrite(HiSysEvent::Domain::RELIABILITY, KEY_NO_LOG_EVENT_NAME, HiSysEvent::EventType::FAULT,
259800b99b8Sopenharmony_ci                KEY_NAME, it->name,
260800b99b8Sopenharmony_ci                KEY_PID, it->pid,
261800b99b8Sopenharmony_ci                KEY_UID, it->uid,
262800b99b8Sopenharmony_ci                KEY_HAPPEN_TIME, it->time);
263800b99b8Sopenharmony_ci            noLogEvents_.push_back(*it);
264800b99b8Sopenharmony_ci        } else {
265800b99b8Sopenharmony_ci            totalEventCount_++;
266800b99b8Sopenharmony_ci            normalEventCount_++;
267800b99b8Sopenharmony_ci        }
268800b99b8Sopenharmony_ci        it = pendingEvents_.erase(it);
269800b99b8Sopenharmony_ci    }
270800b99b8Sopenharmony_ci}
271800b99b8Sopenharmony_ci
272800b99b8Sopenharmony_civoid CrashValidator::ReadServiceCrashStatus()
273800b99b8Sopenharmony_ci{
274800b99b8Sopenharmony_ci    char kmsg[KMSG_SIZE];
275800b99b8Sopenharmony_ci    int fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK);
276800b99b8Sopenharmony_ci    if (fd == -1) {
277800b99b8Sopenharmony_ci        printf("Failed to open /dev/kmsg.\n");
278800b99b8Sopenharmony_ci        return;
279800b99b8Sopenharmony_ci    }
280800b99b8Sopenharmony_ci    lseek(fd, 0, 3); // 3 : SEEK_DATA
281800b99b8Sopenharmony_ci    while (true) {
282800b99b8Sopenharmony_ci        ssize_t len;
283800b99b8Sopenharmony_ci        if (((len = read(fd, kmsg, sizeof(kmsg))) == -1) && errno == EPIPE) {
284800b99b8Sopenharmony_ci            continue;
285800b99b8Sopenharmony_ci        }
286800b99b8Sopenharmony_ci        if (len == -1 && errno == EINVAL) {
287800b99b8Sopenharmony_ci            printf("Failed to read kmsg\n");
288800b99b8Sopenharmony_ci            close(fd);
289800b99b8Sopenharmony_ci            return;
290800b99b8Sopenharmony_ci        }
291800b99b8Sopenharmony_ci        if (len < 1) {
292800b99b8Sopenharmony_ci            continue;
293800b99b8Sopenharmony_ci        }
294800b99b8Sopenharmony_ci        kmsg[len] = 0;
295800b99b8Sopenharmony_ci        if (stopReadKmsg_) {
296800b99b8Sopenharmony_ci            break;
297800b99b8Sopenharmony_ci        }
298800b99b8Sopenharmony_ci        std::string line = kmsg;
299800b99b8Sopenharmony_ci        auto pos = line.find(INIT_LOG_PATTERN);
300800b99b8Sopenharmony_ci        if (pos == std::string::npos) {
301800b99b8Sopenharmony_ci            continue;
302800b99b8Sopenharmony_ci        }
303800b99b8Sopenharmony_ci        std::string formattedLog = line.substr(pos + strlen(INIT_LOG_PATTERN));
304800b99b8Sopenharmony_ci        char name[LOG_SIZE] {0};
305800b99b8Sopenharmony_ci        int pid;
306800b99b8Sopenharmony_ci        int uid;
307800b99b8Sopenharmony_ci        int status;
308800b99b8Sopenharmony_ci        int ret = sscanf_s(formattedLog.c_str(), "%[^,], SIGCHLD received, pid:%d uid:%d status:%d.",
309800b99b8Sopenharmony_ci            name, sizeof(name), &pid, &uid, &status);
310800b99b8Sopenharmony_ci        if (ret <= 0) {
311800b99b8Sopenharmony_ci            printf("Failed to parse kmsg:%s", formattedLog.c_str());
312800b99b8Sopenharmony_ci            continue;
313800b99b8Sopenharmony_ci        }
314800b99b8Sopenharmony_ci
315800b99b8Sopenharmony_ci        printf("Kernel:%s", formattedLog.c_str());
316800b99b8Sopenharmony_ci        HiSysEventWrite(HiSysEvent::Domain::STARTUP, KEY_PROCESS_EXIT, HiSysEvent::EventType::BEHAVIOR,
317800b99b8Sopenharmony_ci            KEY_NAME, name, KEY_PID, pid, KEY_UID, uid, KEY_STATUS, status);
318800b99b8Sopenharmony_ci    }
319800b99b8Sopenharmony_ci    close(fd);
320800b99b8Sopenharmony_ci}
321800b99b8Sopenharmony_ci
322800b99b8Sopenharmony_cibool CrashValidator::ValidateLogContent(const CrashEvent& event)
323800b99b8Sopenharmony_ci{
324800b99b8Sopenharmony_ci    // check later
325800b99b8Sopenharmony_ci    return true;
326800b99b8Sopenharmony_ci}
327800b99b8Sopenharmony_ci} // namespace HiviewDFX
328800b99b8Sopenharmony_ci} // namespace OHOS
329800b99b8Sopenharmony_ci#endif
330