LCOV - code coverage report
Current view: top level - atrace/utrace/stacktrace - stacktrace_safe_recorder.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.6 % 306 268
Test Date: 2026-07-28 10:53:44 Functions: 80.0 % 20 16

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "stacktrace_safe_recorder.h"
      12              : #include <errno.h>
      13              : #include "securec.h"
      14              : #include "stacktrace_logger.h"
      15              : #include "stacktrace_file_struct.h"
      16              : #include "trace_recorder.h"
      17              : #include "trace_system_api.h"
      18              : #include "trace_types.h"
      19              : #include "adiag_utils.h"
      20              : #include "adiag_print.h"
      21              : 
      22              : #define PROCESS_SECTION                     "[process]\n"
      23              : #define STACK_SECTION                       "[stack]\n"
      24              : #define MAPS_SECTION                        "[maps]\n"
      25              : #define MEMORY_SECTION                      "[system memory]\n"
      26              : #define STATUS_SECTION                      "[process status]\n"
      27              : #define LIMITS_SECTION                      "[process limits]\n"
      28              : 
      29              : #define PROC_MEMINFO_PATH                   "/proc/meminfo"
      30              : 
      31              : STATIC TraceStackInfo g_stackInfo = { 0 };
      32              : STATIC struct StackcoreBuffer g_stackBuff = { 0 };
      33              : 
      34              : /**
      35              :  * @brief       read a line data from file
      36              :  * @param [in]  fd:         file descriptor
      37              :  * @param [in]  data:       write data
      38              :  * @param [in]  len:        data buffer length
      39              :  * @return      >0  success; -1  failed
      40              :  */
      41        39571 : ssize_t TraceSafeReadLine(int32_t fd, char *data, uint32_t len)
      42              : {
      43        39571 :     if (fd < 0 || data == NULL || len == 0) {
      44           20 :         return -1;
      45              :     }
      46              : 
      47        39551 :     ssize_t n = 1;
      48        39551 :     char c = (char)EOF;
      49        39551 :     char *ptr = data;
      50      3045930 :     while (n < (ssize_t)len) {
      51      3045815 :         ssize_t rc = read(fd, &c, 1);
      52      3045815 :         if (rc == 1) {
      53      3045204 :             *ptr = c;
      54      3045204 :             ptr++;
      55      3045204 :             if (c == '\n') {
      56        38845 :                 break;
      57              :             }
      58          611 :         } else if (rc == 0) {
      59          571 :             *ptr = '\0';
      60          571 :             return (n - 1);
      61              :         } else {
      62           40 :             if (errno == EINTR) {
      63           20 :                 continue;
      64              :             }
      65           20 :             return -1;
      66              :         }
      67      3006359 :         n++;
      68              :     }
      69        38960 :     *ptr = '\0';
      70        38960 :     return n;
      71              : }
      72              : 
      73              : /**
      74              :  * @brief       safe write data to file
      75              :  * @param [in]  fd:         file descriptor
      76              :  * @param [in]  data:       write data
      77              :  * @param [in]  len:        data buffer length
      78              :  * @return      TraStatus
      79              :  */
      80        29339 : STATIC TraStatus TraceSafeWrite(int32_t fd, const char *data, size_t len)
      81              : {
      82        29339 :     if ((fd < 0) || (data == NULL) || (len == 0)) {
      83           80 :         return TRACE_INVALID_PARAM;
      84              :     }
      85              : 
      86        29259 :     size_t reserved = len;
      87              :     do {
      88        29279 :         ssize_t wrLen = write(fd, data + (len - reserved), reserved);
      89        29279 :         if (wrLen < 0 && errno == EINTR) {
      90           20 :             wrLen = 0;
      91        29259 :         } else if (wrLen < 0) {
      92           40 :             return TRACE_FAILURE;
      93              :         } else {
      94              :             ;
      95              :         }
      96        29239 :         reserved -= (size_t)wrLen;
      97        29239 :     } while (reserved != 0);
      98        29219 :     return TRACE_SUCCESS;
      99              : }
     100              : 
     101            0 : const char* TraceSafeGetFilePath(void)
     102              : {
     103            0 :     return TraceRecorderSafeGetFilePath();
     104              : }
     105              : 
     106              : /**
     107              :  * @brief       get fd to write stackcore file
     108              :                 use for signal_callback_func, only call reentrant function
     109              :  * @param [in]  info:           info, for dir name and file name
     110              :  * @param [in]  suffix:         file suffix
     111              :  * @param [out] fd:             file handle
     112              :  * @return      TraStatus
     113              :  */
     114          215 : TraStatus TraceSafeGetFd(const TraceStackRecorderInfo *info, const char *suffix, int32_t *fd)
     115              : {
     116          215 :     if ((info == NULL) || (fd == NULL)) {
     117           20 :         return TRACE_INVALID_PARAM;
     118              :     }
     119              : 
     120          195 :     char timeString[TIMESTAMP_MAX_LENGTH] = { 0 };
     121          195 :     uint64_t fileTime = GetRealTime();
     122          195 :     TraStatus ret = TimestampToFileStr(fileTime, timeString, TIMESTAMP_MAX_LENGTH);
     123          195 :     if (ret != TRACE_SUCCESS) {
     124           20 :         return ret;
     125              :     }
     126          175 :     char objName[MAX_FILEPATH_LEN] = { 0 };
     127          175 :     int32_t err = snprintf_s(objName, MAX_FILEPATH_LEN, MAX_FILEPATH_LEN - 1U,
     128          175 :         "%d_%d_%s_%s", info->signo, info->tid, program_invocation_short_name, timeString);
     129          175 :     if (err == -1) {
     130            0 :         return TRACE_FAILURE;
     131              :     }
     132              : 
     133              :     // get dir time by crash time
     134          175 :     ret = TimestampToFileStr(info->crashTime, timeString, TIMESTAMP_MAX_LENGTH);
     135          175 :     if (ret != TRACE_SUCCESS) {
     136           20 :         return ret;
     137              :     }
     138              : 
     139          155 :     g_stackBuff.head.magic = STACK_HEAD_MAGIC;
     140          155 :     g_stackBuff.head.version = STACK_HEAD_VERSION;
     141          155 :     TraceDirInfo dirInfo = { TRACER_STACKCORE_NAME, info->pid, timeString, false };
     142          155 :     TraceFileInfo fileInfo = { TRACER_STACKCORE_NAME, objName, suffix };
     143          155 :     return TraceRecorderSafeGetFd(&dirInfo, &fileInfo, fd);
     144              : }
     145              : 
     146          195 : TraceStackInfo *TraceSafeGetStackBuffer(void)
     147              : {
     148          195 :     return &g_stackInfo;
     149              : }
     150              : 
     151              : /**
     152              :  * @brief       write "system memory" info
     153              :  * @param [in]  fd:     handle of stack core file
     154              :  * @return      TraStatus
     155              :  */
     156          255 : STATIC TraStatus TraceSafeWriteMemoryInfo(int32_t fd)
     157              : {
     158              :     // write title [system memory]
     159          255 :     TraStatus ret = TraceSafeWrite(fd, MEMORY_SECTION, strlen(MEMORY_SECTION));
     160          255 :     if (ret != TRACE_SUCCESS) {
     161           40 :         LOGE("write memory title failed, ret=%d, errno=%d", ret, errno);
     162           40 :         return ret;
     163              :     }
     164              : 
     165              :     // write memory info
     166          215 :     int32_t memFd = open(PROC_MEMINFO_PATH, O_RDONLY);
     167          215 :     if (memFd < 0) {
     168           20 :         LOGE("memory info file open failed, errno=%d", errno);
     169           20 :         return TRACE_FAILURE;
     170              :     }
     171              : 
     172          195 :     char info[CORE_BUFFER_LEN] = { 0 };
     173         9120 :     while (TraceSafeReadLine(memFd, info, CORE_BUFFER_LEN) > 0) {
     174         8945 :         ret = TraceSafeWrite(fd, info, strlen(info));
     175         8945 :         if (ret != TRACE_SUCCESS) {
     176           20 :             LOGE("write memory info to file failed, ret=%d, errno=%d", ret, errno);
     177           20 :             TraceClose(&memFd);
     178           20 :             return ret;
     179              :         }
     180              :     }
     181          175 :     TraceClose(&memFd);
     182          175 :     (void)TraceSafeWrite(fd, "\n", 1);
     183          175 :     return TRACE_SUCCESS;
     184              : }
     185              : 
     186              : /**
     187              :  * @brief       write "process status" info
     188              :  * @param [in]  fd:     handle of stack core file
     189              :  * @param [in]  pid:    process id
     190              :  * @return      TraStatus
     191              :  */
     192          275 : STATIC TraStatus TraceSafeWriteStatusInfo(int32_t fd, int32_t pid)
     193              : {
     194              :     // write title [process status]
     195          275 :     TraStatus ret = TraceSafeWrite(fd, STATUS_SECTION, strlen(STATUS_SECTION));
     196          275 :     if (ret != TRACE_SUCCESS) {
     197           40 :         LOGE("write status title failed, ret=%d, errno=%d", ret, errno);
     198           40 :         return ret;
     199              :     }
     200          235 :     char path[CORE_BUFFER_LEN] = { 0 };
     201          235 :     int32_t err = snprintf_s(path, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, "/proc/%d/status", pid);
     202          235 :     if (err == -1) {
     203           20 :         LOGE("snprintf_s status path failed");
     204           20 :         return TRACE_FAILURE;
     205              :     }
     206              :     // write status info
     207          215 :     int32_t statFd = open(path, O_RDONLY);
     208          215 :     if (statFd < 0) {
     209           80 :         LOGE("status file open failed, errno=%d", errno);
     210           80 :         return TRACE_FAILURE;
     211              :     }
     212              : 
     213          135 :     char info[CORE_BUFFER_LEN] = { 0 };
     214         6690 :     while (TraceSafeReadLine(statFd, info, CORE_BUFFER_LEN) > 0) {
     215         6575 :         ret = TraceSafeWrite(fd, info, strlen(info));
     216         6575 :         if (ret != TRACE_SUCCESS) {
     217           20 :             LOGE("write status info to file failed, ret=%d, errno=%d", ret, errno);
     218           20 :             TraceClose(&statFd);
     219           20 :             return ret;
     220              :         }
     221              :     }
     222          115 :     TraceClose(&statFd);
     223          115 :     (void)TraceSafeWrite(fd, "\n", 1);
     224          115 :     return TRACE_SUCCESS;
     225              : }
     226              : 
     227              : 
     228              : /**
     229              :  * @brief       write "process limits" info
     230              :  * @param [in]  fd:     handle of stack core file
     231              :  * @param [in]  pid:    process id
     232              :  * @return      TraStatus
     233              :  */
     234          275 : STATIC TraStatus TraceSafeWriteLimitsInfo(int32_t fd, int32_t pid)
     235              : {
     236              :     // write title [process limits]
     237          275 :     TraStatus ret = TraceSafeWrite(fd, LIMITS_SECTION, strlen(LIMITS_SECTION));
     238          275 :     if (ret != TRACE_SUCCESS) {
     239           40 :         LOGE("write limits title failed, ret=%d, errno=%d", ret, errno);
     240           40 :         return ret;
     241              :     }
     242          235 :     char path[CORE_BUFFER_LEN] = { 0 };
     243          235 :     int32_t err = snprintf_s(path, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, "/proc/%d/limits", pid);
     244          235 :     if (err == -1) {
     245           20 :         LOGE("snprintf_s limits path failed");
     246           20 :         return TRACE_FAILURE;
     247              :     }
     248              :     // write limits info
     249          215 :     int32_t limitsFd = open(path, O_RDONLY);
     250          215 :     if (limitsFd < 0) {
     251           80 :         LOGE("limits file open failed, errno=%d", errno);
     252           80 :         return TRACE_FAILURE;
     253              :     }
     254              : 
     255          135 :     char info[CORE_BUFFER_LEN] = { 0 };
     256         2090 :     while (TraceSafeReadLine(limitsFd, info, CORE_BUFFER_LEN) > 0) {
     257         1975 :         ret = TraceSafeWrite(fd, info, strlen(info));
     258         1975 :         if (ret != TRACE_SUCCESS) {
     259           20 :             LOGE("write limits info to file failed, ret=%d, errno=%d", ret, errno);
     260           20 :             TraceClose(&limitsFd);
     261           20 :             return ret;
     262              :         }
     263              :     }
     264          115 :     TraceClose(&limitsFd);
     265          115 :     (void)TraceSafeWrite(fd, "\n", 1);
     266          115 :     return TRACE_SUCCESS;
     267              : }
     268              : 
     269              : /**
     270              :  * @brief       write "maps" info
     271              :  * @param [in]  fd:     handle of stack core file
     272              :  * @param [in]  pid:    process id
     273              :  * @return      TraStatus
     274              :  */
     275          275 : STATIC TraStatus TraceSafeWriteMapsInfo(int32_t fd, int32_t pid)
     276              : {
     277              :     // write title [maps]
     278          275 :     TraStatus ret = TraceSafeWrite(fd, MAPS_SECTION, strlen(MAPS_SECTION));
     279          275 :     if (ret != TRACE_SUCCESS) {
     280           40 :         LOGE("write maps title failed, ret=%d, errno=%d", ret, errno);
     281           40 :         return ret;
     282              :     }
     283              : 
     284          235 :     char path[CORE_BUFFER_LEN] = { 0 };
     285          235 :     int32_t err = snprintf_s(path, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, "/proc/%d/maps", pid);
     286          235 :     if (err == -1) {
     287           20 :         LOGE("snprintf_s maps path failed");
     288           20 :         return TRACE_FAILURE;
     289              :     }
     290              :     // write maps info
     291          215 :     int32_t mapFd = open(path, O_RDONLY);
     292          215 :     if (mapFd < 0) {
     293           80 :         LOGE("self map open failed, errno=%d", errno);
     294           80 :         return TRACE_FAILURE;
     295              :     }
     296              : 
     297          135 :     char info[CORE_BUFFER_LEN] = { 0 };
     298         9274 :     while (TraceSafeReadLine(mapFd, info, CORE_BUFFER_LEN) > 0) {
     299         9179 :         ret = TraceSafeWrite(fd, info, strlen(info));
     300         9179 :         if (ret != TRACE_SUCCESS) {
     301           40 :             LOGE("write maps info to file failed, ret=%d, errno=%d", ret, errno);
     302           40 :             TraceClose(&mapFd);
     303           40 :             return ret;
     304              :         }
     305              :     }
     306           95 :     TraceClose(&mapFd);
     307           95 :     (void)TraceSafeWrite(fd, "\n", 1);
     308           95 :     return TRACE_SUCCESS;
     309              : }
     310              : 
     311              : /**
     312              :  * @brief       write "system memory" info
     313              :  * @param [in]  fd:     handle of stack core file
     314              :  * @param [in]  pid:    process id
     315              :  * @return      TraStatus
     316              :  */
     317          215 : TraStatus TraceSafeWriteSystemInfo(int32_t fd, int32_t pid)
     318              : {
     319          215 :     TraStatus ret = TraceSafeWriteMapsInfo(fd, pid);
     320          215 :     if (ret != TRACE_SUCCESS) {
     321          120 :         LOGW("can not write maps info to file, ret=%d.", ret);
     322              :     }
     323              : 
     324          215 :     ret = TraceSafeWriteMemoryInfo(fd);
     325          215 :     if (ret != TRACE_SUCCESS) {
     326           40 :         LOGW("can not write memory info to file, ret=%d.", ret);
     327              :     }
     328              : 
     329          215 :     ret = TraceSafeWriteStatusInfo(fd, pid);
     330          215 :     if (ret != TRACE_SUCCESS) {
     331          100 :         LOGW("can not write process info to file, ret=%d.", ret);
     332              :     }
     333              : 
     334          215 :     ret = TraceSafeWriteLimitsInfo(fd, pid);
     335          215 :     if (ret != TRACE_SUCCESS) {
     336          100 :         LOGW("can not write limits info to file, ret=%d.", ret);
     337              :     }
     338              : 
     339          215 :     return TRACE_SUCCESS;
     340              : }
     341              : 
     342              : /**
     343              :  * @brief       write "stack" info
     344              :  * @param [in]  fd:     handle of stack core file
     345              :  * @param [in]  info:   stack info
     346              :  * @return      TraStatus
     347              :  */
     348          275 : TraStatus TraceSafeWriteStackInfo(int32_t fd, const TraceStackInfo *info)
     349              : {
     350          275 :     if (info == NULL) {
     351           20 :         return TRACE_INVALID_PARAM;
     352              :     }
     353              : 
     354              :     // write title [stack]
     355          255 :     TraStatus ret = TRACE_FAILURE;
     356          255 :     if (info->threadIdx == 0) {
     357          255 :         ret = TraceSafeWrite(fd, STACK_SECTION, strlen(STACK_SECTION));
     358          255 :         if (ret != TRACE_SUCCESS) {
     359           20 :             LOGE("write stack title failed, errno=%d", errno);
     360           20 :             return ret;
     361              :         }
     362              :     }
     363              : 
     364              :     // write stack info
     365          235 :     char buf[CORE_BUFFER_LEN] = { 0 };
     366          235 :     (void)snprintf_s(buf, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, "Thread %u (%d, %s)\n",
     367          235 :         info->threadIdx + 1U, info->threadTid, info->threadName);
     368          235 :     (void)TraceSafeWrite(fd, buf, strlen(buf));
     369              : 
     370          235 :     int32_t layer = info->layer;
     371          235 :     if (layer < 0) {
     372           60 :         (void)TraceSafeWrite(fd, info->errLog, strlen(info->errLog));
     373           60 :         (void)TraceSafeWrite(fd, "\n", 1);
     374           60 :         return TRACE_FAILURE;
     375              :     }
     376          175 :     if (layer >= MAX_STACK_LAYER) {
     377           20 :         LOGE("layer %d exceed the upper limit: %d", layer, MAX_STACK_LAYER);
     378           20 :         return TRACE_FAILURE;
     379              :     }
     380          485 :     for (int32_t i = 0; i <= layer; i++) {
     381          350 :         ret = TraceSafeWrite(fd, info->frame[i].info, strlen(info->frame[i].info));
     382          350 :         if (ret != TRACE_SUCCESS) {
     383           20 :             LOGE("write stack layer %d failed, ret=%d", i, ret);
     384           20 :             return ret;
     385              :         }
     386              :     }
     387          135 :     (void)TraceSafeWrite(fd, "\n", 1);
     388          135 :     return TRACE_SUCCESS;
     389              : }
     390              : 
     391              : /**
     392              :  * @brief       write "process" info
     393              :  * @param [in]  fd:     handle of stack_core file
     394              :  * @param [in]  info:   process info
     395              :  * @return      TraStatus
     396              :  */
     397          215 : TraStatus TraceSafeWriteProcessInfo(int32_t fd, const TraceStackProcessInfo *info)
     398              : {
     399          215 :     if (info == NULL) {
     400           20 :         return TRACE_INVALID_PARAM;
     401              :     }
     402              :     // write title [process]
     403          195 :     TraStatus ret = TraceSafeWrite(fd, PROCESS_SECTION, strlen(PROCESS_SECTION));
     404          195 :     if (ret != TRACE_SUCCESS) {
     405           20 :         LOGE("write process title failed, errno=%d", errno);
     406           20 :         return ret;
     407              :     }
     408              : 
     409              :     // write process info
     410          175 :     char data[CORE_BUFFER_LEN] = { 0 };
     411          175 :     int32_t err = snprintf_s(data, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, 
     412              :         "crash reason:%d\ncrash pid:%d\ncrash tid:%d\ncrash stack base:0x%016lx\ncrash stack top:0x%016lx\n\n",
     413          175 :         info->signo, info->pid, info->tid, info->baseAddr, info->topAddr);
     414          175 :     if (err == -1) {
     415            0 :         LOGE("snprintf_s process info failed");
     416            0 :         return TRACE_FAILURE;
     417              :     }
     418          175 :     ret = TraceSafeWrite(fd, data, strlen(data));
     419          175 :     if (ret != TRACE_SUCCESS) {
     420           20 :         LOGE("write process info failed, info : %s", strerror(AdiagGetErrorCode()));
     421           20 :         return ret;
     422              :     }
     423          155 :     return TRACE_SUCCESS;
     424              : }
     425              : 
     426           20 : TraStatus TraceSaveProcessReg(uintptr_t *regs, uint32_t regSize)
     427              : {
     428           20 :     errno_t err = memcpy_s(g_stackBuff.process.regs, sizeof(uintptr_t) * TRACE_CORE_REG_NUM, regs, regSize);
     429           20 :     if (err != EOK) {
     430           20 :         LOGE("memcpy failed, err = %d, errno = %d.", (int32_t)err, errno);
     431           20 :         return TRACE_FAILURE;
     432              :     }
     433            0 :     return TRACE_SUCCESS;
     434              : }
     435              : 
     436            0 : STATIC TraStatus TraceSaveProcessTask(int32_t pid)
     437              : {
     438            0 :     char path[CORE_BUFFER_LEN] = { 0 };
     439            0 :     int32_t err = snprintf_s(path, CORE_BUFFER_LEN, CORE_BUFFER_LEN - 1U, "/proc/%d/cmdline", pid);
     440            0 :     if (err == -1) {
     441            0 :         LOGE("snprintf_s cmdline path failed");
     442            0 :         return TRACE_FAILURE;
     443              :     }
     444              : 
     445            0 :     int32_t cmdFd = open(path, O_RDONLY);
     446            0 :     if (cmdFd < 0) {
     447            0 :         LOGE("cmdline file open failed, errno=%d", errno);
     448            0 :         return TRACE_FAILURE;
     449              :     }
     450              : 
     451            0 :     if (TraceSafeReadLine(cmdFd, g_stackBuff.process.task, (uint32_t)sizeof(g_stackBuff.process.task)) <= 0) {
     452            0 :         LOGE("read task info failed, errno=%d", errno);
     453            0 :         TraceClose(&cmdFd);
     454            0 :         return TRACE_FAILURE;
     455              :     }
     456            0 :     TraceClose(&cmdFd);
     457            0 :     return TRACE_SUCCESS;
     458              : }
     459              : 
     460              : /**
     461              :  * @brief       save process info
     462              :  * @param [in]  info:   stack info
     463              :  * @return      TraStatus
     464              :  */
     465            0 : TraStatus TraceSaveProcessInfo(const TraceStackProcessInfo *info)
     466              : {
     467            0 :     g_stackBuff.process.pid = info->pid;
     468            0 :     g_stackBuff.process.crashTid = info->tid;
     469            0 :     g_stackBuff.process.signo = info->signo;
     470            0 :     g_stackBuff.process.crashTime = info->crashTime;
     471            0 :     g_stackBuff.process.baseAddr = info->baseAddr;
     472            0 :     g_stackBuff.process.topAddr = info->topAddr;
     473            0 :     return TraceSaveProcessTask(info->pid);
     474              : }
     475              : 
     476              : /**
     477              :  * @brief       save stack info
     478              :  * @param [in]  info:   stack info
     479              :  * @return      TraStatus
     480              :  */
     481          120 : TraStatus TraceSaveStackInfo(const TraceStackInfo *info)
     482              : {
     483          120 :     if (info == NULL) {
     484           20 :         return TRACE_INVALID_PARAM;
     485              :     }
     486          100 :     if (info->threadIdx >= MAX_THREAD_NUM) {
     487           20 :         return TRACE_INVALID_PARAM;
     488              :     }
     489              : 
     490           80 :     ScThreadInfo *thread = &g_stackBuff.thread[info->threadIdx];
     491           80 :     thread->tid = info->threadTid;
     492           80 :     thread->layer = info->layer;
     493           80 :     errno_t err = strncpy_s(thread->name, THREAD_NAME_LEN, info->threadName, strlen(info->threadName));
     494           80 :     if (err != EOK) {
     495           20 :         LOGE("strcpy thread name failed");
     496           20 :         return TRACE_FAILURE;
     497              :     }
     498              : 
     499           60 :     int32_t layer = info->layer;
     500           60 :     if (layer < 0) {
     501           20 :         return TRACE_FAILURE;
     502              :     }
     503           40 :     if (layer >= MAX_STACK_LAYER) {
     504           20 :         LOGE("layer %d exceed the upper limit: %d", layer, MAX_STACK_LAYER);
     505           20 :         return TRACE_FAILURE;
     506              :     }
     507              : 
     508           20 :     err = memcpy_s(thread->frames, sizeof(ScdFrames) * (size_t)MAX_STACK_LAYER,
     509           20 :         info->frame, sizeof(TraceFrameInfo) * (size_t)MAX_STACK_LAYER);
     510           20 :     if (err != EOK) {
     511           20 :         LOGE("memcpy thread frames failed");
     512           20 :         return TRACE_FAILURE;
     513              :     }
     514              : 
     515            0 :     return TRACE_SUCCESS;
     516              : }
     517              : 
     518            0 : TraStatus TraceSafeWriteBuff(int32_t fd)
     519              : {
     520            0 :     TraStatus ret = TraceSafeWrite(fd, (const char *)&g_stackBuff, sizeof(g_stackBuff));
     521            0 :     (void)memset_s(&g_stackBuff, sizeof(struct StackcoreBuffer), 0, sizeof(struct StackcoreBuffer));
     522            0 :     if (ret != TRACE_SUCCESS) {
     523            0 :         LOGE("write buffer to file failed, info : %s", strerror(AdiagGetErrorCode()));
     524            0 :         return ret;
     525              :     }
     526            0 :     return TRACE_SUCCESS;
     527              : }
     528              : 
     529          151 : TraStatus TraceSafeMkdirPath(const TraceStackRecorderInfo *info)
     530              : {
     531          151 :     if (info == NULL) {
     532           20 :         return TRACE_INVALID_PARAM;
     533              :     }
     534              : 
     535              :     // get dir time by crash time
     536          131 :     char timeString[TIMESTAMP_MAX_LENGTH] = { 0 };
     537          131 :     TraStatus ret = TimestampToFileStr(info->crashTime, timeString, TIMESTAMP_MAX_LENGTH);
     538          131 :     if (ret != TRACE_SUCCESS) {
     539           20 :         LOGE("get dir time failed, ret=%d", ret);
     540           20 :         return ret;
     541              :     }
     542              : 
     543          111 :     TraceDirInfo dirInfo = { TRACER_STACKCORE_NAME, info->pid, timeString, false };
     544          111 :     return TraceRecorderSafeMkdirPath(&dirInfo);
     545              : }
     546              : 
     547          260 : TraStatus TraceSafeGetDirPath(const TraceStackRecorderInfo *info, char *path, size_t len)
     548              : {
     549          260 :     if ((info == NULL) || (path == NULL) || (len == 0)) {
     550           60 :         return TRACE_INVALID_PARAM;
     551              :     }
     552              : 
     553              :     // get dir time by crash time
     554          200 :     char timeString[TIMESTAMP_MAX_LENGTH] = { 0 };
     555          200 :     TraStatus ret = TimestampToFileStr(info->crashTime, timeString, TIMESTAMP_MAX_LENGTH);
     556          200 :     if (ret != TRACE_SUCCESS) {
     557           20 :         LOGE("get dir time failed, ret=%d", ret);
     558           20 :         return ret;
     559              :     }
     560              : 
     561          180 :     TraceDirInfo dirInfo = { TRACER_STACKCORE_NAME, info->pid, timeString, false };
     562          180 :     return TraceRecorderSafeGetDirPath(&dirInfo, path, len);
     563              : }
     564              : 
     565          260 : TraStatus TraceSafeGetFileName(const TraceStackRecorderInfo *info, char *name, size_t len)
     566              : {
     567          260 :     if ((info == NULL) || (name == NULL) || (len == 0)) {
     568           60 :         return TRACE_INVALID_PARAM;
     569              :     }
     570          200 :     char timeString[TIMESTAMP_MAX_LENGTH] = { 0 };
     571          200 :     uint64_t fileTime = GetRealTime();
     572          200 :     TraStatus ret = TimestampToFileStr(fileTime, timeString, TIMESTAMP_MAX_LENGTH);
     573          200 :     if (ret != TRACE_SUCCESS) {
     574           20 :         LOGE("get dir time failed, ret=%d", ret);
     575           20 :         return ret;
     576              :     }
     577              : 
     578          180 :     int32_t err = snprintf_s(name, len, len - 1U, "%s_tracer_%d_%d_%s_%s",
     579          180 :         TRACER_STACKCORE_NAME, info->signo, info->tid, program_invocation_short_name, timeString);
     580          180 :     if (err == -1) {
     581           20 :         LOGE("snprintf_s file name failed, info : %s, signo=%d, tid=%d, name=%s",
     582              :             strerror(AdiagGetErrorCode()), info->signo, info->tid, program_invocation_short_name);
     583           20 :         return TRACE_FAILURE;
     584              :     }
     585          160 :     return TRACE_SUCCESS;
     586              : }
        

Generated by: LCOV version 2.0-1