已合并
fix: prevent atrace dir aging race #2658
fix: prevent atrace dir aging race #2658
已合并
GuoWenbo创建于 6月6日
共 2 个文件变更+344-17
@@ -288,6 +288,21 @@ STATIC void TraceRecorderListAppend(TraceDirList *dirList, TraceDirNode *newNode
288 (void)AdiagLockRelease(&dirList->lock);288 (void)AdiagLockRelease(&dirList->lock);
289}289}
290 290 
291+STATIC TraceDirNode *TraceRecorderListFind(TraceDirList *dirList, const char *dirPath)
292+{
293+ (void)AdiagLockGet(&dirList->lock);
294+ TraceDirNode *curNode = dirList->head;
295+ while (curNode != NULL) {
296+ if (strcmp(curNode->dirPath, dirPath) == 0) {
297+ (void)AdiagLockRelease(&dirList->lock);
298+ return curNode;
299+ }
300+ curNode = curNode->next;
301+ }
302+ (void)AdiagLockRelease(&dirList->lock);
303+ return NULL;
304+}
305+ 
291STATIC void TraceRecorderSaveNode(const TraceDirInfo *dirInfo, TraceDirNode *dirNew)306STATIC void TraceRecorderSaveNode(const TraceDirInfo *dirInfo, TraceDirNode *dirNew)
292{307{
293 // if exit_event, no need to aging308 // if exit_event, no need to aging
@@ -367,6 +382,15 @@ const TraceDirNode *TraceRecorderGetDirPath(const TraceDirInfo *dirInfo)
367 return NULL;382 return NULL;
368 }383 }
369 384 
385+ if (strncmp(dirInfo->eventName, TRACER_EVENT_EXIT, strlen(TRACER_EVENT_EXIT)) != 0) {
386+ TraceDirList *dirList = (dirInfo->isDevice) ? &g_recorderMgr->deviceDirList : &g_recorderMgr->hostDirList;
387+ TraceDirNode *existNode = TraceRecorderListFind(dirList, dirNew->dirPath);
388+ if (existNode != NULL) {
389+ ADIAG_SAFE_FREE(dirNew);
390+ return existNode;
391+ }
392+ }
393+ 
370 TraceRecorderSaveNode(dirInfo, dirNew);394 TraceRecorderSaveNode(dirInfo, dirNew);
371 return dirNew;395 return dirNew;
372}396}
@@ -386,15 +410,18 @@ TraStatus TraceRecorderGetFd(const TraceDirInfo *dirInfo, const TraceFileInfo *f
386 char filePath[MAX_FULLPATH_LEN + 1U] = { 0 };410 char filePath[MAX_FULLPATH_LEN + 1U] = { 0 };
387 int32_t ret = snprintf_s(filePath, MAX_FULLPATH_LEN + 1U, MAX_FULLPATH_LEN,411 int32_t ret = snprintf_s(filePath, MAX_FULLPATH_LEN + 1U, MAX_FULLPATH_LEN,
388 "%s/%s_tracer_%s%s", dir->dirPath, fileInfo->tracerName, fileInfo->objName, fileInfo->suffix);412 "%s/%s_tracer_%s%s", dir->dirPath, fileInfo->tracerName, fileInfo->objName, fileInfo->suffix);
389- (void)AdiagLockRelease(&g_recorderMgr->lock);
390 if (ret == -1) {413 if (ret == -1) {
391- ADIAG_ERR("snprintf_s file path failed, ret=%d, strerr=%s.", ret, strerror(AdiagGetErrorCode()));414+ int32_t errCode = AdiagGetErrorCode();
415+ (void)AdiagLockRelease(&g_recorderMgr->lock);
416+ ADIAG_ERR("snprintf_s file path failed, ret=%d, strerr=%s.", ret, strerror(errCode));
392 return TRACE_FAILURE;417 return TRACE_FAILURE;
393 }418 }
394 int32_t fileFd = TraceOpen(filePath, (uint32_t)O_CREAT | (uint32_t)O_WRONLY | (uint32_t)O_APPEND,419 int32_t fileFd = TraceOpen(filePath, (uint32_t)O_CREAT | (uint32_t)O_WRONLY | (uint32_t)O_APPEND,
395 TRACE_FILE_MODE);420 TRACE_FILE_MODE);
421+ int32_t errCode = (fileFd < 0) ? AdiagGetErrorCode() : 0;
422+ (void)AdiagLockRelease(&g_recorderMgr->lock);
396 ADIAG_CHK_EXPR_ACTION(fileFd < 0, return TRACE_FAILURE,423 ADIAG_CHK_EXPR_ACTION(fileFd < 0, return TRACE_FAILURE,
397- "open file failed, file=%s, strerr=%s.", filePath, strerror(AdiagGetErrorCode()));424+ "open file failed, file=%s, strerr=%s.", filePath, strerror(errCode));
398 425 
399 *fd = fileFd;426 *fd = fileFd;
400 return TRACE_SUCCESS;427 return TRACE_SUCCESS;
@@ -14,11 +14,105 @@
14#include "trace_attr.h"14#include "trace_attr.h"
15#include "adiag_utils.h"15#include "adiag_utils.h"
16#include <pwd.h>16#include <pwd.h>
17-#include "mmpa_api.h"17+#include "mmpa_api.h"
18-#include "trace_types.h"18+#include "trace_types.h"
19-#include "trace_system_api.h"19+#include "trace_system_api.h"
20- 20+#include <atomic>
21-#define TIMESTAMP_MAX_LENGTH 29U21+#include <cerrno>
22+#include <fcntl.h>
23+#include <sys/stat.h>
24+ 
25+#define TIMESTAMP_MAX_LENGTH 29U
26+ 
27+static std::atomic<uint32_t> g_traceOpenCallIndex(0);
28+static std::atomic<bool> g_firstTraceOpenEntered(false);
29+static std::atomic<bool> g_allowFirstTraceOpen(false);
30+static std::atomic<bool> g_agingThreadDone(false);
31+ 
32+typedef struct {
33+ TraceDirInfo dirInfo;
34+ TraceFileInfo fileInfo;
35+ char dirTime[TIMESTAMP_MAX_LENGTH];
36+ TraStatus ret;
37+ int32_t fd;
38+ int32_t err;
39+} TraceGetFdThreadArg;
40+ 
41+typedef struct {
42+ bool success;
43+} TraceAgingThreadArg;
44+ 
45+int32_t TraceOpenBlockFirstThenOpen(const char *filePath, int32_t flag, uint32_t mode)
46+{
47+ uint32_t callIndex = g_traceOpenCallIndex.fetch_add(1);
48+ if (callIndex == 0U) {
49+ g_firstTraceOpenEntered.store(true);
50+ while (!g_allowFirstTraceOpen.load()) {
51+ usleep(1000);
52+ }
53+ }
54+ 
55+ int32_t fd = open(filePath, flag, mode);
56+ if (fd >= 0) {
57+ (void)fchmod(fd, mode);
58+ }
59+ return fd;
60+}
61+ 
62+void *TraceRecorderGetFdThread(void *arg)
63+{
64+ TraceGetFdThreadArg *threadArg = static_cast<TraceGetFdThreadArg *>(arg);
65+ errno = 0;
66+ threadArg->ret = TraceRecorderGetFd(&threadArg->dirInfo, &threadArg->fileInfo, &threadArg->fd);
67+ threadArg->err = errno;
68+ if (threadArg->fd >= 0) {
69+ close(threadArg->fd);
70+ }
71+ return NULL;
72+}
73+ 
74+void *TraceRecorderCreateAgingDirsThread(void *arg)
75+{
76+ TraceAgingThreadArg *threadArg = static_cast<TraceAgingThreadArg *>(arg);
77+ threadArg->success = true;
78+ for (uint32_t i = 0; i < 10U; i++) {
79+ char timeStr[TIMESTAMP_MAX_LENGTH] = {0};
80+ int32_t ret = snprintf_s(timeStr, TIMESTAMP_MAX_LENGTH, TIMESTAMP_MAX_LENGTH - 1U,
81+ "1970010108000001%04u", i);
82+ if (ret == -1) {
83+ threadArg->success = false;
84+ break;
85+ }
86+ TraceDirInfo dirInfo = { TRACER_SCHEDULE_NAME, getpid(), timeStr, true };
87+ TraceFileInfo fileInfo = { TRACER_SCHEDULE_NAME, "other", TRACE_FILE_TXT_SUFFIX };
88+ int32_t fd = -1;
89+ if (TraceRecorderGetFd(&dirInfo, &fileInfo, &fd) != TRACE_SUCCESS) {
90+ threadArg->success = false;
91+ break;
92+ }
93+ close(fd);
94+ }
95+ g_agingThreadDone.store(true);
96+ return NULL;
97+}
98+ 
99+bool BuildRecorderDirPath(char *path, size_t len, const char *eventName, const char *dirTime)
100+{
101+ int32_t ret = snprintf_s(path, len, len - 1U, "%s/atrace/trace_%d_%d_%s/%s_event_%d_%s",
102+ LLT_TEST_DIR, TraceAttrGetPgid(), TraceAttrGetPid(), TraceAttrGetTime(), eventName, getpid(), dirTime);
103+ return ret != -1;
104+}
105+ 
106+bool BuildRecorderFilePath(char *path, size_t len, const char *eventName, const char *dirTime,
107+ const char *tracerName, const char *objName, const char *suffix)
108+{
109+ char dirPath[MAX_FULLPATH_LEN + 1U] = {0};
110+ if (!BuildRecorderDirPath(dirPath, MAX_FULLPATH_LEN + 1U, eventName, dirTime)) {
111+ return false;
112+ }
113+ int32_t ret = snprintf_s(path, len, len - 1U, "%s/%s_tracer_%s%s", dirPath, tracerName, objName, suffix);
114+ return ret != -1;
115+}
22 116 
23class TraceRecorderUtest: public testing::Test {117class TraceRecorderUtest: public testing::Test {
24protected:118protected:
@@ -247,8 +341,8 @@ TEST_F(TraceRecorderUtest, TestSafeGetBinFd)
247 EXPECT_EQ(TRACE_SUCCESS, ret);341 EXPECT_EQ(TRACE_SUCCESS, ret);
248}342}
249 343 
250-TEST_F(TraceRecorderUtest, TraceRecorderGetFd_Failed)344+TEST_F(TraceRecorderUtest, TraceRecorderGetFd_Failed)
251-{345+{
252 char timeStr[TIMESTAMP_MAX_LENGTH] = {0};346 char timeStr[TIMESTAMP_MAX_LENGTH] = {0};
253 auto ret = TimestampToFileStr(std::time(0), timeStr, TIMESTAMP_MAX_LENGTH);347 auto ret = TimestampToFileStr(std::time(0), timeStr, TIMESTAMP_MAX_LENGTH);
254 EXPECT_EQ(TRACE_SUCCESS, ret);348 EXPECT_EQ(TRACE_SUCCESS, ret);
@@ -258,12 +352,218 @@ TEST_F(TraceRecorderUtest, TraceRecorderGetFd_Failed)
258 int32_t fd = -1;352 int32_t fd = -1;
259 MOCKER(TraceRecorderGetDirPath).stubs().will(returnValue((const TraceDirNode *)0));353 MOCKER(TraceRecorderGetDirPath).stubs().will(returnValue((const TraceDirNode *)0));
260 ret = TraceRecorderGetFd(&dirInfo, &info, &fd);354 ret = TraceRecorderGetFd(&dirInfo, &info, &fd);
261- EXPECT_EQ(TRACE_FAILURE, ret);355+ EXPECT_EQ(TRACE_FAILURE, ret);
262-}356+}
263- 357+ 
264-TEST_F(TraceRecorderUtest, TestTraceRecorderSafeGetFd_Failed)358+TEST_F(TraceRecorderUtest, TraceRecorderGetFd_SameDirAgingKeepsWritable)
265-{359+{
266- auto ret = TraceRecorderSafeGetFd(NULL, NULL, NULL);360+ TraceRecorderExit();
361+ setenv("ASCEND_WORK_PATH", LLT_TEST_DIR, 1);
362+ setenv("ASCEND_TRACE_RECORD_NUM", "10", 1);
363+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderInit());
364+ 
365+ char timeStr[TIMESTAMP_MAX_LENGTH] = {0};
366+ auto ret = TimestampToFileStr(std::time(0), timeStr, TIMESTAMP_MAX_LENGTH);
367+ EXPECT_EQ(TRACE_SUCCESS, ret);
368+ 
369+ TraceDirInfo dirInfo = { TRACER_SCHEDULE_NAME, getpid(), timeStr, true };
370+ TraceFileInfo fileInfo = { TRACER_SCHEDULE_NAME, "ts_0", TRACE_FILE_TXT_SUFFIX };
371+ for (uint32_t i = 0; i < 11U; i++) {
372+ int32_t fd = -1;
373+ ret = TraceRecorderGetFd(&dirInfo, &fileInfo, &fd);
374+ EXPECT_EQ(TRACE_SUCCESS, ret);
375+ close(fd);
376+ }
377+ 
378+ char filePath[MAX_FULLPATH_LEN + 1U] = {0};
379+ ASSERT_TRUE(BuildRecorderFilePath(filePath, MAX_FULLPATH_LEN + 1U, TRACER_SCHEDULE_NAME, timeStr,
380+ TRACER_SCHEDULE_NAME, "ts_0", TRACE_FILE_TXT_SUFFIX));
381+ EXPECT_EQ(0, access(filePath, F_OK));
382+ 
383+ unsetenv("ASCEND_TRACE_RECORD_NUM");
384+ unsetenv("ASCEND_WORK_PATH");
385+}
386+ 
387+TEST_F(TraceRecorderUtest, TraceRecorderGetFd_ConcurrentDirAgingKeepsFirstOpen)
388+{
389+ TraceRecorderExit();
390+ setenv("ASCEND_WORK_PATH", LLT_TEST_DIR, 1);
391+ setenv("ASCEND_TRACE_RECORD_NUM", "10", 1);
392+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderInit());
393+ 
394+ g_traceOpenCallIndex.store(0);
395+ g_firstTraceOpenEntered.store(false);
396+ g_allowFirstTraceOpen.store(false);
397+ g_agingThreadDone.store(false);
398+ MOCKER(TraceOpen).stubs().will(invoke(TraceOpenBlockFirstThenOpen));
399+ 
400+ TraceGetFdThreadArg firstArg = {};
401+ int32_t ret = snprintf_s(firstArg.dirTime, TIMESTAMP_MAX_LENGTH, TIMESTAMP_MAX_LENGTH - 1U,
402+ "19700101080000000001");
403+ EXPECT_NE(-1, ret);
404+ firstArg.dirInfo = { TRACER_SCHEDULE_NAME, getpid(), firstArg.dirTime, true };
405+ firstArg.fileInfo = { TRACER_SCHEDULE_NAME, "first", TRACE_FILE_TXT_SUFFIX };
406+ firstArg.fd = -1;
407+ firstArg.ret = TRACE_SUCCESS;
408+ firstArg.err = 0;
409+ 
410+ pthread_t threadId = 0;
411+ EXPECT_EQ(0, pthread_create(&threadId, NULL, TraceRecorderGetFdThread, &firstArg));
412+ for (uint32_t i = 0; i < 5000U && !g_firstTraceOpenEntered.load(); i++) {
413+ usleep(1000);
414+ }
415+ ASSERT_TRUE(g_firstTraceOpenEntered.load());
416+ 
417+ TraceAgingThreadArg agingArg = { true };
418+ pthread_t agingThreadId = 0;
419+ EXPECT_EQ(0, pthread_create(&agingThreadId, NULL, TraceRecorderCreateAgingDirsThread, &agingArg));
420+ usleep(100000);
421+ EXPECT_FALSE(g_agingThreadDone.load());
422+ 
423+ g_allowFirstTraceOpen.store(true);
424+ EXPECT_EQ(0, pthread_join(threadId, NULL));
425+ EXPECT_EQ(0, pthread_join(agingThreadId, NULL));
426+ EXPECT_EQ(TRACE_SUCCESS, firstArg.ret);
427+ EXPECT_GE(firstArg.fd, 0);
428+ EXPECT_TRUE(agingArg.success);
429+ 
430+ GlobalMockObject::verify();
431+ unsetenv("ASCEND_TRACE_RECORD_NUM");
432+ unsetenv("ASCEND_WORK_PATH");
433+}
434+ 
435+TEST_F(TraceRecorderUtest, TraceRecorderGetFd_WriteCreatesExpectedFile)
436+{
437+ TraceRecorderExit();
438+ setenv("ASCEND_WORK_PATH", LLT_TEST_DIR, 1);
439+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderInit());
440+ 
441+ const char *dirTime = "19700101080002000001";
442+ TraceDirInfo dirInfo = { TRACER_SCHEDULE_NAME, getpid(), dirTime, true };
443+ TraceFileInfo fileInfo = { TRACER_SCHEDULE_NAME, "normal", TRACE_FILE_TXT_SUFFIX };
444+ int32_t fd = -1;
445+ auto ret = TraceRecorderGetFd(&dirInfo, &fileInfo, &fd);
446+ EXPECT_EQ(TRACE_SUCCESS, ret);
447+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderWrite(fd, "abc", 3U));
448+ close(fd);
449+ 
450+ char filePath[MAX_FULLPATH_LEN + 1U] = {0};
451+ ASSERT_TRUE(BuildRecorderFilePath(filePath, MAX_FULLPATH_LEN + 1U, TRACER_SCHEDULE_NAME, dirTime,
452+ TRACER_SCHEDULE_NAME, "normal", TRACE_FILE_TXT_SUFFIX));
453+ EXPECT_EQ(0, access(filePath, F_OK));
454+ 
455+ unsetenv("ASCEND_WORK_PATH");
456+}
457+ 
458+TEST_F(TraceRecorderUtest, TraceRecorderGetFd_SameDirWithinLimitKeepsWritable)
459+{
460+ TraceRecorderExit();
461+ setenv("ASCEND_WORK_PATH", LLT_TEST_DIR, 1);
462+ setenv("ASCEND_TRACE_RECORD_NUM", "10", 1);
463+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderInit());
464+ 
465+ const char *dirTime = "19700101080002000002";
466+ TraceDirInfo dirInfo = { TRACER_SCHEDULE_NAME, getpid(), dirTime, true };
467+ TraceFileInfo fileInfo = { TRACER_SCHEDULE_NAME, "repeat", TRACE_FILE_TXT_SUFFIX };
468+ for (uint32_t i = 0; i < 2U; i++) {
469+ int32_t fd = -1;
470+ auto ret = TraceRecorderGetFd(&dirInfo, &fileInfo, &fd);
471+ EXPECT_EQ(TRACE_SUCCESS, ret);
472+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderWrite(fd, "x", 1U));
473+ close(fd);
474+ }
475+ 
476+ char filePath[MAX_FULLPATH_LEN + 1U] = {0};
477+ ASSERT_TRUE(BuildRecorderFilePath(filePath, MAX_FULLPATH_LEN + 1U, TRACER_SCHEDULE_NAME, dirTime,
478+ TRACER_SCHEDULE_NAME, "repeat", TRACE_FILE_TXT_SUFFIX));
479+ EXPECT_EQ(0, access(filePath, F_OK));
480+ 
481+ unsetenv("ASCEND_TRACE_RECORD_NUM");
482+ unsetenv("ASCEND_WORK_PATH");
483+}
484+ 
485+TEST_F(TraceRecorderUtest, TraceRecorderGetFd_UniqueDirAgingRemovesOldestOnly)
486+{
487+ TraceRecorderExit();
488+ setenv("ASCEND_WORK_PATH", LLT_TEST_DIR, 1);
489+ setenv("ASCEND_TRACE_RECORD_NUM", "10", 1);
490+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderInit());
491+ 
492+ char dirPaths[11][MAX_FULLPATH_LEN + 1U] = {};
493+ for (uint32_t i = 0; i < 11U; i++) {
494+ char dirTime[TIMESTAMP_MAX_LENGTH] = {0};
495+ int32_t ret = snprintf_s(dirTime, TIMESTAMP_MAX_LENGTH, TIMESTAMP_MAX_LENGTH - 1U,
496+ "1970010108000201%04u", i);
497+ EXPECT_NE(-1, ret);
498+ ASSERT_TRUE(BuildRecorderDirPath(dirPaths[i], MAX_FULLPATH_LEN + 1U, TRACER_SCHEDULE_NAME, dirTime));
499+ 
500+ TraceDirInfo dirInfo = { TRACER_SCHEDULE_NAME, getpid(), dirTime, true };
501+ TraceFileInfo fileInfo = { TRACER_SCHEDULE_NAME, "unique", TRACE_FILE_TXT_SUFFIX };
502+ int32_t fd = -1;
503+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderGetFd(&dirInfo, &fileInfo, &fd));
504+ close(fd);
505+ }
506+ 
507+ EXPECT_NE(0, access(dirPaths[0], F_OK));
508+ for (uint32_t i = 1; i < 11U; i++) {
509+ EXPECT_EQ(0, access(dirPaths[i], F_OK));
510+ }
511+ 
512+ unsetenv("ASCEND_TRACE_RECORD_NUM");
513+ unsetenv("ASCEND_WORK_PATH");
514+}
515+ 
516+TEST_F(TraceRecorderUtest, TraceRecorderGetFd_ReusedOldDirDoesNotRefreshAgingOrder)
517+{
518+ TraceRecorderExit();
519+ setenv("ASCEND_WORK_PATH", LLT_TEST_DIR, 1);
520+ setenv("ASCEND_TRACE_RECORD_NUM", "10", 1);
521+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderInit());
522+ 
523+ char dirPaths[11][MAX_FULLPATH_LEN + 1U] = {};
524+ char dirTimes[11][TIMESTAMP_MAX_LENGTH] = {};
525+ for (uint32_t i = 0; i < 10U; i++) {
526+ int32_t ret = snprintf_s(dirTimes[i], TIMESTAMP_MAX_LENGTH, TIMESTAMP_MAX_LENGTH - 1U,
527+ "1970010108000301%04u", i);
528+ EXPECT_NE(-1, ret);
529+ ASSERT_TRUE(BuildRecorderDirPath(dirPaths[i], MAX_FULLPATH_LEN + 1U, TRACER_SCHEDULE_NAME, dirTimes[i]));
530+ 
531+ TraceDirInfo dirInfo = { TRACER_SCHEDULE_NAME, getpid(), dirTimes[i], true };
532+ TraceFileInfo fileInfo = { TRACER_SCHEDULE_NAME, "timestamp", TRACE_FILE_TXT_SUFFIX };
533+ int32_t fd = -1;
534+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderGetFd(&dirInfo, &fileInfo, &fd));
535+ close(fd);
536+ }
537+ 
538+ TraceDirInfo reusedDirInfo = { TRACER_SCHEDULE_NAME, getpid(), dirTimes[0], true };
539+ TraceFileInfo reusedFileInfo = { TRACER_SCHEDULE_NAME, "reuse", TRACE_FILE_TXT_SUFFIX };
540+ int32_t reusedFd = -1;
541+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderGetFd(&reusedDirInfo, &reusedFileInfo, &reusedFd));
542+ close(reusedFd);
543+ 
544+ int32_t ret = snprintf_s(dirTimes[10], TIMESTAMP_MAX_LENGTH, TIMESTAMP_MAX_LENGTH - 1U,
545+ "1970010108000301%04u", 10U);
546+ EXPECT_NE(-1, ret);
547+ ASSERT_TRUE(BuildRecorderDirPath(dirPaths[10], MAX_FULLPATH_LEN + 1U, TRACER_SCHEDULE_NAME, dirTimes[10]));
548+ 
549+ TraceDirInfo newDirInfo = { TRACER_SCHEDULE_NAME, getpid(), dirTimes[10], true };
550+ TraceFileInfo newFileInfo = { TRACER_SCHEDULE_NAME, "timestamp", TRACE_FILE_TXT_SUFFIX };
551+ int32_t newFd = -1;
552+ EXPECT_EQ(TRACE_SUCCESS, TraceRecorderGetFd(&newDirInfo, &newFileInfo, &newFd));
553+ close(newFd);
554+ 
555+ EXPECT_NE(0, access(dirPaths[0], F_OK));
556+ for (uint32_t i = 1; i < 11U; i++) {
557+ EXPECT_EQ(0, access(dirPaths[i], F_OK));
558+ }
559+ 
560+ unsetenv("ASCEND_TRACE_RECORD_NUM");
561+ unsetenv("ASCEND_WORK_PATH");
562+}
563+ 
564+TEST_F(TraceRecorderUtest, TestTraceRecorderSafeGetFd_Failed)
565+{
566+ auto ret = TraceRecorderSafeGetFd(NULL, NULL, NULL);
267 EXPECT_EQ(TRACE_INVALID_PARAM, ret);567 EXPECT_EQ(TRACE_INVALID_PARAM, ret);
268 568 
269 char timeStr[TIMESTAMP_MAX_LENGTH] = {0};569 char timeStr[TIMESTAMP_MAX_LENGTH] = {0};
@@ -363,4 +663,4 @@ TEST_F(TraceRecorderUtest, TestTraceRecorderSafeGetDirPath_Failed)
363 663 
364 MOCKER(vsnprintf_s).stubs().will(returnValue(-1));664 MOCKER(vsnprintf_s).stubs().will(returnValue(-1));
365 EXPECT_EQ(TRACE_FAILURE, TraceRecorderSafeGetDirPath(&dirInfo, path, 1024));665 EXPECT_EQ(TRACE_FAILURE, TraceRecorderSafeGetDirPath(&dirInfo, path, 1024));
366-}666+}