1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "temp_file_manager.h"
17
18 #include <bitset>
19 #include <chrono>
20 #include <cmath>
21 #include <fcntl.h>
22 #include <fstream>
23 #include <map>
24 #include <memory>
25 #include <regex>
26 #include <sys/inotify.h>
27 #include <sys/stat.h>
28 #include <sys/timerfd.h>
29 #include <unistd.h>
30
31 #include "dfx_define.h"
32 #include "dfx_log.h"
33 #include "dfx_socket_request.h"
34 #include "dfx_trace.h"
35 #include "directory_ex.h"
36 #include "file_ex.h"
37
38 #ifndef HISYSEVENT_DISABLE
39 #include "hisysevent.h"
40 #endif
41
42 namespace OHOS {
43 namespace HiviewDFX {
44
45 namespace {
46 constexpr const char *const TEMP_FILE_MANAGER_TAG = "TEMP_FILE_MANAGER";
47 constexpr uint64_t SECONDS_TO_MILLISECONDS = 1000;
48
GetTargetFileConfig(const std::function<bool (const SingleFileConfig &)> & filter)49 const SingleFileConfig* GetTargetFileConfig(const std::function<bool(const SingleFileConfig&)>& filter)
50 {
51 const auto& fileConfigs = FaultLoggerConfig::GetInstance().GetTempFileConfig().singleFileConfigs;
52 auto iter = std::find_if(fileConfigs.begin(), fileConfigs.end(), filter);
53 return iter == fileConfigs.end() ? nullptr : iter.base();
54 }
55
GetCurrentTime()56 uint64_t GetCurrentTime()
57 {
58 using namespace std::chrono;
59 return static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
60 }
61
GetFileSize(const std::string & filePath)62 uint64_t GetFileSize(const std::string& filePath)
63 {
64 struct stat64 statBuf{};
65 if (stat64(filePath.c_str(), &statBuf) == 0) {
66 return static_cast<uint64_t>(statBuf.st_size);
67 }
68 return 0;
69 }
70
GetTimeFromFileName(const std::string & fileName)71 uint64_t GetTimeFromFileName(const std::string& fileName)
72 {
73 constexpr int timeStrLen = 13;
74 constexpr char timeStrSplit = '-';
75 constexpr int decimal = 10;
76 auto timeStr = fileName.substr(fileName.find_last_of(timeStrSplit) + 1, timeStrLen);
77 errno = 0;
78 uint64_t num = strtoull(timeStr.c_str(), nullptr, decimal);
79 if (errno == ERANGE) {
80 DFXLOGE("%{public}s :: invalid timeStr for file: %{public}s", TEMP_FILE_MANAGER_TAG, timeStr.c_str());
81 return 0;
82 }
83 return num;
84 }
85
CreateFileDir(const std::string & filePath)86 bool CreateFileDir(const std::string& filePath)
87 {
88 if (access(filePath.c_str(), F_OK) == 0 || OHOS::ForceCreateDirectory(filePath)) {
89 return true;
90 }
91 DFXLOGE("%{public}s :: failed to create dirs: %{public}s.", TEMP_FILE_MANAGER_TAG, filePath.c_str());
92 return false;
93 }
94
RemoveTempFile(const std::string & filePath)95 bool RemoveTempFile(const std::string& filePath)
96 {
97 if (access(filePath.c_str(), F_OK) != 0) {
98 return true;
99 }
100 if (!OHOS::RemoveFile(filePath)) {
101 DFXLOGE("%{public}s :: failed to remove file: %{public}s.", TEMP_FILE_MANAGER_TAG, filePath.c_str());
102 return false;
103 }
104 DFXLOGI("%{public}s :: success to remove file: %{public}s.", TEMP_FILE_MANAGER_TAG, filePath.c_str());
105 return true;
106 }
107
RemoveTimeOutFileIfNeed(const SingleFileConfig & fileConfig,std::list<std::string> & tempFiles)108 void RemoveTimeOutFileIfNeed(const SingleFileConfig& fileConfig, std::list<std::string>& tempFiles)
109 {
110 if (fileConfig.fileExistTime < 0 || fileConfig.keepFileCount < 0 ||
111 tempFiles.size() <= static_cast<size_t>(fileConfig.keepFileCount)) {
112 return;
113 }
114 auto currentTime = GetCurrentTime();
115 tempFiles.erase(std::remove_if(tempFiles.begin(), tempFiles.end(),
116 [currentTime, &fileConfig](const std::string& tempFile) {
117 auto fileCreateTime = GetTimeFromFileName(tempFile);
118 if (fileCreateTime > currentTime ||
119 (fileCreateTime + fileConfig.fileExistTime * SECONDS_TO_MILLISECONDS < currentTime)) {
120 return RemoveTempFile(tempFile);
121 }
122 return false;
123 }), tempFiles.end());
124 }
125
ForceRemoveFileIfNeed(const SingleFileConfig & fileConfig,std::list<std::string> & tempFiles)126 void ForceRemoveFileIfNeed(const SingleFileConfig& fileConfig, std::list<std::string>& tempFiles)
127 {
128 if (fileConfig.maxFileCount < 0 || tempFiles.size() <= static_cast<size_t>(fileConfig.maxFileCount)) {
129 return;
130 }
131 if (fileConfig.keepFileCount != 0) {
132 tempFiles.sort([](std::string& lhs, const std::string& rhs) -> int {
133 return GetTimeFromFileName(lhs) < GetTimeFromFileName(rhs);
134 });
135 }
136 auto deleteNum = fileConfig.keepFileCount < 0 ? 1 : tempFiles.size() - fileConfig.keepFileCount;
137 tempFiles.erase(std::remove_if(tempFiles.begin(), tempFiles.end(),
138 [&deleteNum](const std::string& tempFile) {
139 if (deleteNum > 0 && RemoveTempFile(tempFile)) {
140 deleteNum--;
141 return true;
142 }
143 return false;
144 }), tempFiles.end());
145 }
146
147 /**
148 * Check and handle the size of a temporary file with large file support.
149 *
150 * @param fileConfig Configuration parameters for the file:
151 * - maxSingleFileSize: Maximum allowed file size (0 indicates unlimited).
152 * - overFileSizeAction: Action to take when file size exceeds the limit.
153 * @param filePath Path to the file to be checked.
154 * @return The final size of the file after processing (in bytes):
155 * - Normal file: Original size.
156 * - Deleted file: 0.
157 * - Truncated file: the maxSingleFileSize of fileConfig.
158 */
CheckTempFileSize(const SingleFileConfig & fileConfig,const std::string & filePath)159 uint64_t CheckTempFileSize(const SingleFileConfig& fileConfig, const std::string& filePath)
160 {
161 uint64_t originFileSize = GetFileSize(filePath);
162 if (originFileSize > 0 &&
163 (originFileSize <= fileConfig.maxSingleFileSize || fileConfig.maxSingleFileSize == 0)) {
164 return originFileSize;
165 }
166 DFXLOGW("%{public}s :: invalid file size %{public}" PRIu64 " of: %{public}s.",
167 TEMP_FILE_MANAGER_TAG, originFileSize, filePath.c_str());
168 if (fileConfig.overFileSizeAction == OverFileSizeAction::DELETE || originFileSize == 0) {
169 RemoveTempFile(filePath);
170 return 0;
171 }
172 truncate64(filePath.c_str(), static_cast<off64_t>(fileConfig.maxSingleFileSize));
173 return fileConfig.maxSingleFileSize;
174 }
175
CheckTempFileSize(const SingleFileConfig & tempFileConfig,std::list<std::string> & tempFiles)176 uint64_t CheckTempFileSize(const SingleFileConfig& tempFileConfig, std::list<std::string>& tempFiles)
177 {
178 uint64_t totalFileSize = 0;
179 tempFiles.remove_if([&](const std::string& tempFile) {
180 auto fileSize = CheckTempFileSize(tempFileConfig, tempFile);
181 totalFileSize += fileSize;
182 return fileSize == 0;
183 });
184 return totalFileSize;
185 }
186
CheckTempFileSize(std::map<const SingleFileConfig *,std::list<std::string>> & tempFilesMap)187 uint64_t CheckTempFileSize(std::map<const SingleFileConfig*, std::list<std::string>>& tempFilesMap)
188 {
189 uint64_t fileSize = 0;
190 for (auto& pair : tempFilesMap) {
191 if (pair.first == nullptr) {
192 pair.second.remove_if(RemoveTempFile);
193 } else {
194 fileSize += CheckTempFileSize(*pair.first, pair.second);
195 }
196 }
197 return fileSize;
198 }
199
GetTempFiles(const SingleFileConfig & tempFileConfig,std::list<std::string> & tempFiles)200 void GetTempFiles(const SingleFileConfig& tempFileConfig, std::list<std::string>& tempFiles)
201 {
202 std::vector<std::string> files;
203 const auto& tempFilePath = FaultLoggerConfig::GetInstance().GetTempFileConfig().tempFilePath;
204 OHOS::GetDirFiles(tempFilePath, files);
205 for (const auto& file : files) {
206 if (file.find(tempFileConfig.fileNamePrefix, tempFilePath.size()) != std::string::npos) {
207 tempFiles.emplace_back(file);
208 }
209 }
210 }
211
GetTempFiles(std::map<const SingleFileConfig *,std::list<std::string>> & tempFilesMap)212 void GetTempFiles(std::map<const SingleFileConfig*, std::list<std::string>>& tempFilesMap)
213 {
214 std::vector<std::string> files;
215 const auto& tempFilePath = FaultLoggerConfig::GetInstance().GetTempFileConfig().tempFilePath;
216 OHOS::GetDirFiles(tempFilePath, files);
217 for (const auto& file : files) {
218 auto fileConfig = GetTargetFileConfig([&file, &tempFilePath](const SingleFileConfig& fileConfig) {
219 return file.find(fileConfig.fileNamePrefix, tempFilePath.size()) != std::string::npos;
220 });
221 tempFilesMap[fileConfig].emplace_back(file);
222 }
223 }
224 }
225
TempFileManager(EpollManager & epollManager)226 TempFileManager::TempFileManager(EpollManager& epollManager) : epollManager_(epollManager) {}
227
GetTargetFileCount(int32_t type)228 int32_t& TempFileManager::GetTargetFileCount(int32_t type)
229 {
230 auto iter = std::find_if(fileCounts_.begin(), fileCounts_.end(),
231 [type] (const std::pair<int32_t, int32_t>& pair) {
232 return pair.first == type;
233 });
234 if (iter == fileCounts_.end()) {
235 fileCounts_.emplace_back(type, 0);
236 return fileCounts_.back().second;
237 }
238 return iter->second;
239 }
240
InitTempFileWatcher()241 bool TempFileManager::InitTempFileWatcher()
242 {
243 auto& config = FaultLoggerConfig::GetInstance().GetTempFileConfig();
244 auto tempFileWatcher = TempFileWatcher::CreateInstance(*this);
245 if (tempFileWatcher == nullptr) {
246 return false;
247 }
248 constexpr uint32_t watchEvent = IN_CLOSE_WRITE | IN_MOVE | IN_CREATE | IN_DELETE | IN_DELETE_SELF;
249 if (!tempFileWatcher->AddWatchEvent(config.tempFilePath.c_str(), watchEvent)) {
250 return false;
251 }
252 return epollManager_.AddListener(std::move(tempFileWatcher));
253 }
254
ClearBigFilesOnStart(bool isSizeOverLimit,std::list<std::string> & files)255 void TempFileManager::ClearBigFilesOnStart(bool isSizeOverLimit, std::list<std::string>& files)
256 {
257 auto fileClearTime = FaultLoggerConfig::GetInstance().GetTempFileConfig().fileClearTimeAfterBoot;
258 if (isSizeOverLimit || fileClearTime == 0) {
259 std::for_each(files.begin(), files.end(), RemoveTempFile);
260 files.clear();
261 } else {
262 auto tempFileRemover = DelayTask::CreateInstance([files] {
263 std::for_each(files.begin(), files.end(), RemoveTempFile);
264 }, fileClearTime);
265 epollManager_.AddListener(std::move(tempFileRemover));
266 }
267 }
268
ScanTempFilesOnStart()269 void TempFileManager::ScanTempFilesOnStart()
270 {
271 std::map<const SingleFileConfig*, std::list<std::string>> tempFilesMap;
272 GetTempFiles(tempFilesMap);
273 uint64_t filesSize = CheckTempFileSize(tempFilesMap);
274 bool isOverLimit = filesSize > FaultLoggerConfig::GetInstance().GetTempFileConfig().maxTempFilesSize;
275 for (auto& pair : tempFilesMap) {
276 if (!pair.first) {
277 continue;
278 }
279 int32_t fileType = pair.first->type;
280 if (fileType <= FaultLoggerType::JS_HEAP_LEAK_LIST && fileType >= FaultLoggerType::JS_HEAP_SNAPSHOT) {
281 ClearBigFilesOnStart(isOverLimit, pair.second);
282 }
283 ForceRemoveFileIfNeed(*pair.first, pair.second);
284 GetTargetFileCount(fileType) = static_cast<int32_t>(pair.second.size());
285 }
286 }
287
Init()288 bool TempFileManager::Init()
289 {
290 auto& tempFilePath = FaultLoggerConfig::GetInstance().GetTempFileConfig().tempFilePath;
291 if (tempFilePath.empty() || !CreateFileDir(tempFilePath)) {
292 DFXLOGE("%{public}s :: invalid temp file path %{public}s", TEMP_FILE_MANAGER_TAG, tempFilePath.c_str());
293 return false;
294 }
295 ScanTempFilesOnStart();
296 return InitTempFileWatcher();
297 }
298
CreateFileDescriptor(int32_t type,int32_t pid,int32_t tid,uint64_t time)299 int32_t TempFileManager::CreateFileDescriptor(int32_t type, int32_t pid, int32_t tid, uint64_t time)
300 {
301 const auto fileConfig = GetTargetFileConfig([type](const SingleFileConfig& fileConfig) {
302 return fileConfig.type == type;
303 });
304 if (fileConfig == nullptr) {
305 DFXLOGW("%{public}s :: failed to create fileDescriptor because of unknown file type for %{public}d",
306 TEMP_FILE_MANAGER_TAG, type);
307 return -1;
308 }
309 std::string ss = FaultLoggerConfig::GetInstance().GetTempFileConfig().tempFilePath + "/" +
310 fileConfig->fileNamePrefix + "-" + std::to_string(pid);
311 if (type == FaultLoggerType::JS_HEAP_SNAPSHOT || type == FaultLoggerType::JS_RAW_SNAPSHOT) {
312 ss += "-" + std::to_string(tid);
313 }
314 ss += "-" + std::to_string(time == 0 ? std::chrono::duration_cast<std::chrono::milliseconds>\
315 (std::chrono::system_clock::now().time_since_epoch()).count() : time);
316 if (type == FaultLoggerType::JS_RAW_SNAPSHOT) {
317 ss += ".rawheap";
318 }
319 DFXLOGI("%{public}s :: create file for path(%{public}s).", TEMP_FILE_MANAGER_TAG, ss.c_str());
320 int32_t fd = OHOS_TEMP_FAILURE_RETRY(open(ss.c_str(), O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP));
321 if (fd < 0) {
322 int openErrno = errno;
323 const auto& dirPath = FaultLoggerConfig::GetInstance().GetTempFileConfig().tempFilePath;
324 if (access(dirPath.c_str(), F_OK) != 0) {
325 DFXLOGE("%{public}s :: Failed to create log file, errno(%{public}d). %{public}s does not exist!!!",
326 TEMP_FILE_MANAGER_TAG, openErrno, dirPath.c_str());
327 } else {
328 DFXLOGE("%{public}s :: Failed to create log file, errno(%{public}d)", TEMP_FILE_MANAGER_TAG, openErrno);
329 }
330 }
331 return fd;
332 }
333
334 #ifndef is_ohos_lite
335 std::list<std::pair<int32_t, int64_t>> TempFileManager::crashFileRecords_{};
336
ClearTimeOutRecords()337 void TempFileManager::ClearTimeOutRecords()
338 {
339 #ifdef FAULTLOGGERD_TEST
340 constexpr int validTime = 1;
341 #else
342 constexpr int validTime = 8;
343 #endif
344 auto currentTime = time(nullptr);
345 crashFileRecords_.remove_if([currentTime](const std::pair<int32_t, int32_t>& pair) {
346 return pair.second + validTime <= currentTime;
347 });
348 }
349
CheckCrashFileRecord(int32_t pid)350 bool TempFileManager::CheckCrashFileRecord(int32_t pid)
351 {
352 DFX_TRACE_SCOPED("CheckCrashFileRecord");
353 ClearTimeOutRecords();
354 auto iter = std::find_if(crashFileRecords_.begin(), crashFileRecords_.end(),
355 [pid](const auto& record) {
356 return record.first == pid;
357 });
358 return iter != crashFileRecords_.end();
359 }
360
RecordFileCreation(int32_t type,int32_t pid)361 void TempFileManager::RecordFileCreation(int32_t type, int32_t pid)
362 {
363 ClearTimeOutRecords();
364 if (type != FaultLoggerType::CPP_CRASH) {
365 return;
366 }
367 auto iter = std::find_if(crashFileRecords_.begin(), crashFileRecords_.end(),
368 [pid](const auto& record) {
369 return record.first == pid;
370 });
371 if (iter != crashFileRecords_.end()) {
372 iter->second = time(nullptr);
373 } else {
374 crashFileRecords_.emplace_back(pid, time(nullptr));
375 }
376 }
377 #endif
378
CreateInstance(TempFileManager & tempFileManager)379 std::unique_ptr<TempFileManager::TempFileWatcher> TempFileManager::TempFileWatcher::CreateInstance(
380 TempFileManager& tempFileManager)
381 {
382 SmartFd watchFd{inotify_init()};
383 if (!watchFd) {
384 DFXLOGE("%{public}s :: failed to init inotify fd: %{public}d.", TEMP_FILE_MANAGER_TAG, watchFd.GetFd());
385 return nullptr;
386 }
387 return std::unique_ptr<TempFileManager::TempFileWatcher>(new (std::nothrow)TempFileWatcher(tempFileManager,
388 std::move(watchFd)));
389 }
390
TempFileWatcher(TempFileManager & tempFileManager,SmartFd fd)391 TempFileManager::TempFileWatcher::TempFileWatcher(TempFileManager& tempFileManager, SmartFd fd)
392 : EpollListener(std::move(fd), true), tempFileManager_(tempFileManager) {}
393
AddWatchEvent(const char * watchPath,uint32_t watchEvent)394 bool TempFileManager::TempFileWatcher::AddWatchEvent(const char* watchPath, uint32_t watchEvent)
395 {
396 if (watchPath == nullptr) {
397 return false;
398 }
399 if (inotify_add_watch(GetFd(), watchPath, watchEvent) < 0) {
400 DFXLOGE("%{public}s :: failed to add watch for file: %{public}s.", TEMP_FILE_MANAGER_TAG, watchPath);
401 return false;
402 }
403 return true;
404 }
405
OnEventPoll()406 void TempFileManager::TempFileWatcher::OnEventPoll()
407 {
408 constexpr uint32_t eventLen = static_cast<uint32_t>(sizeof(inotify_event));
409 constexpr uint32_t eventLenSize = 32;
410 constexpr uint32_t buffLen = eventLenSize * eventLen;
411 constexpr uint32_t bound = buffLen - eventLen;
412 char eventBuf[buffLen] = {0};
413 auto readLen = static_cast<size_t>(OHOS_TEMP_FAILURE_RETRY(read(GetFd(), eventBuf, sizeof(eventBuf))));
414 size_t eventPos = 0;
415 while (readLen >= eventLen && eventPos < bound) {
416 auto *event = reinterpret_cast<inotify_event *>(eventBuf + eventPos);
417 if (event->mask & IN_DELETE_SELF) {
418 HandleDirRemoved();
419 return;
420 }
421 if (event->len > 0) {
422 std::string fileName(event->name);
423 auto fileConfig = GetTargetFileConfig([&fileName](const SingleFileConfig& fileConfig) {
424 return fileName.find(fileConfig.fileNamePrefix) != std::string::npos;
425 });
426 std::string filePath = FaultLoggerConfig::GetInstance().GetTempFileConfig().tempFilePath + "/" + fileName;
427 if (fileConfig == nullptr) {
428 RemoveTempFile(filePath);
429 } else {
430 HandleEvent(event->mask, filePath, *fileConfig);
431 }
432 }
433 auto eventSize = (eventLen + event->len);
434 readLen -= eventSize;
435 eventPos += eventSize;
436 }
437 }
438
HandleEvent(uint32_t eventMask,const std::string & filePath,const SingleFileConfig & fileConfig)439 void TempFileManager::TempFileWatcher::HandleEvent(uint32_t eventMask, const std::string& filePath,
440 const SingleFileConfig& fileConfig)
441 {
442 if (eventMask & IN_CREATE) {
443 HandleFileCreate(filePath, fileConfig);
444 }
445 if (eventMask & (IN_MOVED_FROM | IN_DELETE)) {
446 HandleFileDeleteOrMove(filePath, fileConfig);
447 }
448 if (eventMask & IN_CLOSE_WRITE) {
449 HandleFileWrite(filePath, fileConfig);
450 }
451 if (eventMask & IN_MOVED_TO) {
452 HandleFileCreate(filePath, fileConfig);
453 HandleFileWrite(filePath, fileConfig);
454 }
455 }
456
HandleFileCreate(const std::string & filePath,const SingleFileConfig & fileConfig)457 void TempFileManager::TempFileWatcher::HandleFileCreate(const std::string& filePath, const SingleFileConfig& fileConfig)
458 {
459 int32_t currentFileCount = ++(tempFileManager_.GetTargetFileCount(fileConfig.type));
460 DFXLOGD("%{public}s :: file %{public}s is created, currentFileCount: %{public}d, keepFileCount: %{public}d, "
461 "maxFileCount: %{public}d, existTime %{public}d, overTimeDeleteType %{public}d",
462 TEMP_FILE_MANAGER_TAG, filePath.c_str(), currentFileCount, fileConfig.keepFileCount,
463 fileConfig.maxFileCount, fileConfig.fileExistTime, fileConfig.overTimeFileDeleteType);
464 if (fileConfig.overTimeFileDeleteType == OverTimeFileDeleteType::ACTIVE) {
465 auto tempFileRemover = DelayTask::CreateInstance([filePath] {
466 RemoveTempFile(filePath);
467 }, fileConfig.fileExistTime);
468 tempFileManager_.epollManager_.AddListener(std::move(tempFileRemover));
469 }
470 if ((fileConfig.keepFileCount >= 0 && currentFileCount > fileConfig.keepFileCount) ||
471 (fileConfig.maxFileCount >= 0 && currentFileCount > fileConfig.maxFileCount)) {
472 std::list<std::string> files;
473 GetTempFiles(fileConfig, files);
474 RemoveTimeOutFileIfNeed(fileConfig, files);
475 ForceRemoveFileIfNeed(fileConfig, files);
476 }
477 }
478
HandleFileDeleteOrMove(const std::string & filePath,const SingleFileConfig & fileConfig)479 void TempFileManager::TempFileWatcher::HandleFileDeleteOrMove(const std::string& filePath,
480 const SingleFileConfig& fileConfig)
481 {
482 int32_t& currentFileCount = tempFileManager_.GetTargetFileCount(fileConfig.type);
483 if (currentFileCount > 0) {
484 currentFileCount--;
485 }
486 DFXLOGD("%{public}s :: file %{public}s is deleted or moved, currentFileCount: %{public}d",
487 TEMP_FILE_MANAGER_TAG, filePath.c_str(), currentFileCount);
488 }
489
HandleFileWrite(const std::string & filePath,const SingleFileConfig & fileConfig)490 void TempFileManager::TempFileWatcher::HandleFileWrite(const std::string& filePath, const SingleFileConfig& fileConfig)
491 {
492 if (access(filePath.c_str(), F_OK) == 0) {
493 CheckTempFileSize(fileConfig, filePath);
494 }
495 }
496
HandleDirRemoved()497 void TempFileManager::TempFileWatcher::HandleDirRemoved()
498 {
499 std::string summary = "The temp file directory: " +
500 FaultLoggerConfig::GetInstance().GetTempFileConfig().tempFilePath + " was removed unexpectedly";
501 DFXLOGE("%{public}s :: %{public}s", TEMP_FILE_MANAGER_TAG, summary.c_str());
502 #ifndef HISYSEVENT_DISABLE
503 auto now = std::chrono::system_clock::now();
504 auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count();
505 HiSysEventWrite(OHOS::HiviewDFX::HiSysEvent::Domain::RELIABILITY, "CPP_CRASH_NO_LOG",
506 OHOS::HiviewDFX::HiSysEvent::EventType::FAULT,
507 "HAPPEN_TIME", timestamp,
508 "SUMMARY", summary);
509 #endif
510 tempFileManager_.epollManager_.RemoveListener(GetFd());
511 }
512 }
513 }
514