LCOV - code coverage report
Current view: top level - atrace/utrace/tracer - tracer_mgr_operate_atrace.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.9 % 232 197
Test Date: 2026-08-31 10:07:06 Functions: 100.0 % 13 13

            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              : #include "tracer_mgr_operate.h"
      11              : #include "tracer_mgr_operate_inner.h"
      12              : #include "adiag_print.h"
      13              : #include "adiag_utils.h"
      14              : #include "trace_recorder.h"
      15              : #include "trace_system_api.h"
      16              : /**
      17              :  * @brief      save msg to file with txt file
      18              :  * @param [in] newRb:           ringbuffer
      19              :  * @param [in] timeStr:         time stamp of file name
      20              :  * @param [in] objName:         object name
      21              :  * @return     NA
      22              :  */
      23          361 : void TracerScheduleSaveObjData(struct RbLog* newRb, const char* timeStr, const char* eventName, const char* objName)
      24              : {
      25          361 :     TraceFileInfo fileInfo = {TRACER_SCHEDULE_NAME, objName, TRACE_FILE_TXT_SUFFIX};
      26          361 :     TraceDirInfo dirInfo = {eventName, TraceGetPid(), timeStr, false};
      27          361 :     int32_t fd = -1;
      28          361 :     char* txt = NULL;
      29          361 :     char timestamp[TIMESTAMP_MAX_LENGTH] = {0};
      30          361 :     TraStatus ret = TRACE_SUCCESS;
      31              :     do {
      32        23132 :         ret = TraceRbLogReadRbMsg(newRb, (char*)&timestamp, TIMESTAMP_MAX_LENGTH, &txt);
      33        23132 :         if (ret == TRACE_RING_BUFFER_EMPTY) {
      34          337 :             break;
      35              :         }
      36        22795 :         if (ret != TRACE_SUCCESS) {
      37            0 :             ADIAG_ERR("read log msg failed, ret : %d", ret);
      38            0 :             break;
      39              :         }
      40              : 
      41        22795 :         if ((fd == -1) && (TraceRecorderGetFd(&dirInfo, &fileInfo, &fd) != TRACE_SUCCESS)) {
      42           24 :             ADIAG_ERR("get file fd failed, object name=%s.", objName);
      43           24 :             break;
      44              :         }
      45        22771 :         uint32_t txtLen = (uint32_t)strlen(txt);
      46        22771 :         (void)TraceRecorderWrite(fd, timestamp, (uint32_t)strlen(timestamp));
      47        22771 :         (void)TraceRecorderWrite(fd, txt, txtLen);
      48        22771 :         if ((txtLen > 0) && (txt[txtLen - 1U] != '\n')) {
      49        22771 :             (void)TraceRecorderWrite(fd, "\n", 1);
      50              :         }
      51        22771 :     } while (ret == TRACE_SUCCESS);
      52          361 :     TraceClose(&fd);
      53          361 : }
      54              : 
      55           23 : STATIC TraStatus TracerScheduleSaveTraceCtrl(const RbLog* rb, int32_t fd, const char* objName)
      56              : {
      57           23 :     TraceCtrlHead traceCtrl = {0};
      58           23 :     traceCtrl.magic = TRACE_MAGIC;
      59           23 :     traceCtrl.version = TRACE_VERSION;
      60           23 :     traceCtrl.pos = TRACE_POS_HOST;
      61           23 :     traceCtrl.traceType = TRACE_TYPE_BIN;
      62           23 :     traceCtrl.dataSize = rb->head.msgSize * TracerRbLogGetMsgNum(rb);
      63           23 :     traceCtrl.realTime = rb->head.realTime;
      64           23 :     traceCtrl.minutesWest = rb->head.minutesWest;
      65           23 :     traceCtrl.structSize = (uint32_t)sizeof(TraceStructSegmentHead);
      66           23 :     traceCtrl.cpuFreq = rb->head.cpuFreq;
      67          253 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
      68          230 :         if ((rb->entry[i].list == NULL) || (ListEmpty(&((struct AdiagList*)rb->entry[i].list)->list))) {
      69          207 :             continue;
      70              :         }
      71           23 :         traceCtrl.structSize += (uint32_t)sizeof(TraceStructHead) +
      72           23 :                                 ((struct AdiagList*)rb->entry[i].list)->cnt * (uint32_t)sizeof(TraceStructField);
      73              :     }
      74           23 :     if (TraceRecorderWrite(fd, (char*)&traceCtrl, (uint32_t)sizeof(TraceCtrlHead)) != TRACE_SUCCESS) {
      75            0 :         ADIAG_ERR("write log ctrl failed, object name=%s.", objName);
      76            0 :         return TRACE_FAILURE;
      77              :     }
      78           23 :     return TRACE_SUCCESS;
      79              : }
      80              : 
      81           23 : STATIC TraStatus TracerScheduleSaveStructSegment(const RbLog* rb, int32_t fd, const char* objName)
      82              : {
      83           23 :     TraceStructSegmentHead structSegmentHead = {0};
      84          253 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
      85          230 :         if ((rb->entry[i].list == NULL) || (ListEmpty(&((struct AdiagList*)rb->entry[i].list)->list))) {
      86          207 :             continue;
      87              :         }
      88           23 :         structSegmentHead.structCount++;
      89              :     }
      90           23 :     if (TraceRecorderWrite(fd, (char*)&structSegmentHead, (uint32_t)sizeof(TraceStructSegmentHead)) != TRACE_SUCCESS) {
      91            0 :         ADIAG_ERR("write struct segment head failed, object name=%s.", objName);
      92            0 :         return TRACE_FAILURE;
      93              :     }
      94              : 
      95          253 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
      96          230 :         struct AdiagList* traList = (struct AdiagList*)(rb->entry[i].list);
      97          230 :         if ((traList == NULL) || (ListEmpty(&traList->list))) {
      98          207 :             continue;
      99              :         }
     100           23 :         TraceStructHead structHead = {0};
     101           23 :         structHead.structType = (uint8_t)i;
     102           23 :         structHead.itemNum = ((struct AdiagList*)rb->entry[i].list)->cnt;
     103           23 :         errno_t err = strcpy_s(structHead.structName, TRACE_NAME_LENGTH, rb->entry[i].name);
     104           23 :         if (err != EOK) {
     105            0 :             ADIAG_ERR("copy struct name failed, object name=%s, struct name=%s.", objName, rb->entry[i].name);
     106              :         }
     107           23 :         if (TraceRecorderWrite(fd, (char*)&structHead, (uint32_t)sizeof(TraceStructHead)) != TRACE_SUCCESS) {
     108            0 :             ADIAG_ERR(
     109              :                 "write struct head failed, entry name=%s, struct name=%s.", rb->entry[i].name, structHead.structName);
     110            0 :             continue;
     111              :         }
     112              : 
     113           23 :         struct AdiagListNode* node = NULL;
     114           23 :         struct ListHead* pos = NULL;
     115              : 
     116          253 :         LIST_FOR_EACH(pos, &traList->list)
     117              :         {
     118          230 :             node = LIST_ENTRY(pos, struct AdiagListNode, list);
     119          460 :             if ((node == NULL) ||
     120          230 :                 (TraceRecorderWrite(fd, node->data, (uint32_t)sizeof(TraceStructField)) != TRACE_SUCCESS)) {
     121            0 :                 ADIAG_ERR("get trace struct field failed, object name=%s, struct name=%s.", objName, rb->entry[i].name);
     122            0 :                 return TRACE_FAILURE;
     123              :             }
     124              :         }
     125              :     }
     126           23 :     return TRACE_SUCCESS;
     127              : }
     128              : 
     129           23 : STATIC TraStatus TracerScheduleSaveDataHead(const RbLog* rb, int32_t fd, const char* objName)
     130              : {
     131           23 :     TraceStructDataHead dataHead = {0};
     132           23 :     dataHead.msgSize = rb->head.msgSize;
     133           23 :     dataHead.msgTxtSize = rb->head.msgTxtSize;
     134           23 :     dataHead.msgNum = TracerRbLogGetMsgNum(rb);
     135           23 :     if (TraceRecorderWrite(fd, (char*)&dataHead, (uint32_t)sizeof(TraceStructDataHead)) != TRACE_SUCCESS) {
     136            0 :         ADIAG_ERR("write data head failed, object name=%s.", objName);
     137            0 :         return TRACE_FAILURE;
     138              :     }
     139           23 :     return TRACE_SUCCESS;
     140              : }
     141              : 
     142           23 : STATIC TraStatus TracerScheduleSaveStruct(const struct RbLog* newRb, int32_t fd, const char* objName)
     143              : {
     144           23 :     if (TracerScheduleSaveTraceCtrl(newRb, fd, objName) != TRACE_SUCCESS) {
     145            0 :         ADIAG_ERR("write log ctrl failed, object name=%s.", objName);
     146            0 :         return TRACE_FAILURE;
     147              :     }
     148              : 
     149           23 :     if (TracerScheduleSaveStructSegment(newRb, fd, objName) != TRACE_SUCCESS) {
     150            0 :         ADIAG_ERR("write struct segment failed, object name=%s.", objName);
     151            0 :         return TRACE_FAILURE;
     152              :     }
     153              : 
     154           23 :     if (TracerScheduleSaveDataHead(newRb, fd, objName) != TRACE_SUCCESS) {
     155            0 :         ADIAG_ERR("write data head failed, object name=%s.", objName);
     156            0 :         return TRACE_FAILURE;
     157              :     }
     158           23 :     return TRACE_SUCCESS;
     159              : }
     160              : 
     161              : /**
     162              :  * @brief      save msg to file with binary file
     163              :  * @param [in] newRb:           ringbuffer
     164              :  * @param [in] timeStr:         time stamp of file name
     165              :  * @param [in] objName:         object name
     166              :  * @return     NA
     167              :  */
     168           45 : void TracerScheduleSaveObjBinData(struct RbLog* newRb, const char* timeStr, const char* eventName, const char* objName)
     169              : {
     170           45 :     TraceFileInfo fileInfo = {TRACER_SCHEDULE_NAME, objName, TRACE_FILE_BIN_SUFFIX};
     171           45 :     TraceDirInfo dirInfo = {eventName, TraceGetPid(), timeStr, false};
     172           45 :     int32_t fd = -1;
     173              : 
     174           45 :     char* txt = NULL;
     175           45 :     uint32_t txtLen = 0;
     176           45 :     TraStatus ret = TRACE_SUCCESS;
     177              :     do {
     178           68 :         ret = TraceRbLogReadOriRbMsg(newRb, &txt, &txtLen);
     179           68 :         if (ret == TRACE_RING_BUFFER_EMPTY) {
     180           45 :             break;
     181              :         }
     182           23 :         if (ret != TRACE_SUCCESS) {
     183            0 :             ADIAG_ERR("read log msg failed, ret : %d", ret);
     184            0 :             break;
     185              :         }
     186              : 
     187           46 :         if ((fd == -1) && ((TraceRecorderGetFd(&dirInfo, &fileInfo, &fd) != TRACE_SUCCESS) ||
     188           23 :                            (TracerScheduleSaveStruct(newRb, fd, objName) != TRACE_SUCCESS))) {
     189            0 :             ADIAG_ERR("get file fd failed, object name=%s.", objName);
     190            0 :             break;
     191              :         }
     192           23 :         (void)TraceRecorderWrite(fd, txt, txtLen);
     193           23 :     } while (ret == TRACE_SUCCESS);
     194           45 :     TraceClose(&fd);
     195           45 :     return;
     196              : }
     197              : 
     198              : /**
     199              :  * @brief      save msg to file with txt file, must be reentrant, cannot print msg
     200              :  * @param [in] newRb:           ringbuffer
     201              :  * @param [in] timeStr:         time stamp of file name
     202              :  * @param [in] objName:         object name
     203              :  * @return     NA
     204              :  */
     205           45 : STATIC void TracerScheduleSaveObjDataSafe(struct RbLog* newRb, const char* timeStr, const char* objName)
     206              : {
     207           45 :     TraceDirInfo dirInfo = {TRACER_STACKCORE_NAME, TraceGetPid(), timeStr, false};
     208           45 :     TraceFileInfo fileInfo = {TRACER_SCHEDULE_NAME, objName, TRACE_FILE_TXT_SUFFIX};
     209           45 :     int32_t fd = -1;
     210           45 :     char* txt = NULL;
     211           45 :     char timestamp[TIMESTAMP_MAX_LENGTH] = {0};
     212           45 :     TraStatus ret = TRACE_SUCCESS;
     213              :     do {
     214           67 :         ret = TraceRbLogReadRbMsgSafe(newRb, (char*)&timestamp, TIMESTAMP_MAX_LENGTH, &txt);
     215           67 :         if (ret == TRACE_RING_BUFFER_EMPTY) {
     216           45 :             break;
     217              :         }
     218           22 :         if (ret != TRACE_SUCCESS) {
     219            0 :             break;
     220              :         }
     221           22 :         if ((fd == -1) && (TraceRecorderSafeGetFd(&dirInfo, &fileInfo, &fd) != TRACE_SUCCESS)) {
     222            0 :             break;
     223              :         }
     224           22 :         uint32_t txtLen = (uint32_t)strlen(txt);
     225           22 :         (void)TraceRecorderWrite(fd, timestamp, (uint32_t)strlen(timestamp));
     226           22 :         (void)TraceRecorderWrite(fd, txt, txtLen);
     227           22 :         if ((txtLen > 0) && (txt[txtLen - 1U] != '\n')) {
     228           22 :             (void)TraceRecorderWrite(fd, "\n", 1);
     229              :         }
     230           22 :     } while (ret == TRACE_SUCCESS);
     231           45 :     TraceClose(&fd);
     232           45 :     return;
     233              : }
     234              : 
     235           23 : STATIC TraStatus TracerScheduleSaveTraceCtrlSafe(const RbLog* rb, int32_t fd)
     236              : {
     237           23 :     TraceCtrlHead traceCtrl = {0};
     238           23 :     traceCtrl.magic = TRACE_MAGIC;
     239           23 :     traceCtrl.version = TRACE_VERSION;
     240           23 :     traceCtrl.dataSize = rb->head.msgSize * TracerRbLogGetMsgNum(rb);
     241           23 :     traceCtrl.realTime = rb->head.realTime;
     242           23 :     traceCtrl.minutesWest = rb->head.minutesWest;
     243           23 :     traceCtrl.cpuFreq = rb->head.cpuFreq;
     244           23 :     traceCtrl.structSize = (uint32_t)sizeof(TraceStructSegmentHead);
     245          253 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
     246          230 :         if ((rb->entry[i].list == NULL) || (ListEmpty(&((struct AdiagList*)rb->entry[i].list)->list))) {
     247          207 :             continue;
     248              :         }
     249           23 :         traceCtrl.structSize += (uint32_t)sizeof(TraceStructHead) +
     250           23 :                                 ((struct AdiagList*)rb->entry[i].list)->cnt * (uint32_t)sizeof(TraceStructField);
     251              :     }
     252              : 
     253           23 :     if (TraceRecorderWrite(fd, (char*)&traceCtrl, (uint32_t)sizeof(TraceCtrlHead)) != TRACE_SUCCESS) {
     254            0 :         return TRACE_FAILURE;
     255              :     }
     256           23 :     return TRACE_SUCCESS;
     257              : }
     258              : 
     259           23 : STATIC TraStatus TracerScheduleSaveStructSegmentSafe(const RbLog* rb, int32_t fd)
     260              : {
     261           23 :     TraceStructSegmentHead structSegmentHead = {0};
     262          253 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
     263          230 :         if ((rb->entry[i].list == NULL) || (ListEmpty(&((struct AdiagList*)rb->entry[i].list)->list))) {
     264          207 :             continue;
     265              :         }
     266           23 :         structSegmentHead.structCount++;
     267              :     }
     268           23 :     if (TraceRecorderWrite(fd, (char*)&structSegmentHead, (uint32_t)sizeof(TraceStructSegmentHead)) != TRACE_SUCCESS) {
     269            0 :         return TRACE_FAILURE;
     270              :     }
     271              : 
     272          253 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
     273          230 :         struct AdiagList* traList = (struct AdiagList*)(rb->entry[i].list);
     274          230 :         if ((traList == NULL) || (ListEmpty(&traList->list))) {
     275          207 :             continue;
     276              :         }
     277           23 :         TraceStructHead structHead = {0};
     278           23 :         structHead.structType = (uint8_t)i;
     279           23 :         structHead.itemNum = ((struct AdiagList*)rb->entry[i].list)->cnt;
     280           23 :         errno_t err = strcpy_s(structHead.structName, TRACE_NAME_LENGTH, rb->entry[i].name);
     281              :         if (err != EOK) {
     282              :         }
     283           23 :         if (TraceRecorderWrite(fd, (char*)&structHead, (uint32_t)sizeof(TraceStructHead)) != TRACE_SUCCESS) {
     284            0 :             continue;
     285              :         }
     286              : 
     287           23 :         struct AdiagListNode* node = NULL;
     288           23 :         struct ListHead* pos = NULL;
     289              : 
     290          253 :         LIST_FOR_EACH(pos, &traList->list)
     291              :         {
     292          230 :             node = LIST_ENTRY(pos, struct AdiagListNode, list);
     293          460 :             if ((node == NULL) ||
     294          230 :                 (TraceRecorderWrite(fd, node->data, (uint32_t)sizeof(TraceStructField)) != TRACE_SUCCESS)) {
     295            0 :                 return TRACE_FAILURE;
     296              :             }
     297              :         }
     298              :     }
     299           23 :     return TRACE_SUCCESS;
     300              : }
     301              : 
     302           23 : STATIC TraStatus TracerScheduleSaveDataHeadSafe(const RbLog* rb, int32_t fd)
     303              : {
     304           23 :     TraceStructDataHead dataHead = {0};
     305           23 :     dataHead.msgSize = rb->head.msgSize;
     306           23 :     dataHead.msgTxtSize = rb->head.msgTxtSize;
     307           23 :     dataHead.msgNum = TracerRbLogGetMsgNum(rb);
     308           23 :     if (TraceRecorderWrite(fd, (char*)&dataHead, (uint32_t)sizeof(TraceStructDataHead)) != TRACE_SUCCESS) {
     309            0 :         return TRACE_FAILURE;
     310              :     }
     311           23 :     return TRACE_SUCCESS;
     312              : }
     313              : 
     314           23 : STATIC TraStatus TracerScheduleSaveStructSafe(const struct RbLog* newRb, int32_t fd)
     315              : {
     316           23 :     if (TracerScheduleSaveTraceCtrlSafe(newRb, fd) != TRACE_SUCCESS) {
     317            0 :         return TRACE_FAILURE;
     318              :     }
     319              : 
     320           23 :     if (TracerScheduleSaveStructSegmentSafe(newRb, fd) != TRACE_SUCCESS) {
     321            0 :         return TRACE_FAILURE;
     322              :     }
     323              : 
     324           23 :     if (TracerScheduleSaveDataHeadSafe(newRb, fd) != TRACE_SUCCESS) {
     325            0 :         return TRACE_FAILURE;
     326              :     }
     327           23 :     return TRACE_SUCCESS;
     328              : }
     329              : 
     330              : /**
     331              :  * @brief      save msg to file with binary file, must be reentrant, cannot print msg
     332              :  * @param [in] newRb:           ringbuffer
     333              :  * @param [in] timeStr:         time stamp of file name
     334              :  * @param [in] objName:         object name
     335              :  * @return     NA
     336              :  */
     337           23 : STATIC void TracerScheduleSaveObjBinDataSafe(struct RbLog* newRb, const char* timeStr, const char* objName)
     338              : {
     339           23 :     TraceDirInfo dirInfo = {TRACER_STACKCORE_NAME, TraceGetPid(), timeStr, false};
     340           23 :     TraceFileInfo fileInfo = {TRACER_SCHEDULE_NAME, objName, TRACE_FILE_BIN_SUFFIX};
     341           23 :     int32_t fd = -1;
     342           23 :     char* txt = NULL;
     343           23 :     uint32_t txtLen = 0;
     344           23 :     TraStatus ret = TRACE_SUCCESS;
     345           23 :     uint64_t cycle = 0;
     346              :     do {
     347           46 :         ret = TraceRbLogReadOriRbMsgSafe(newRb, &txt, &txtLen, &cycle);
     348           46 :         if (ret == TRACE_RING_BUFFER_EMPTY) {
     349           23 :             break;
     350              :         }
     351           23 :         if (ret != TRACE_SUCCESS) {
     352            0 :             break;
     353              :         }
     354           46 :         if ((fd == -1) && ((TraceRecorderSafeGetFd(&dirInfo, &fileInfo, &fd) != TRACE_SUCCESS) ||
     355           23 :                            (TracerScheduleSaveStructSafe(newRb, fd) != TRACE_SUCCESS))) {
     356              :             break;
     357              :         }
     358           23 :         (void)TraceRecorderWrite(fd, txt, txtLen);
     359           23 :     } while (ret == TRACE_SUCCESS);
     360           23 :     TraceClose(&fd);
     361           23 :     return;
     362              : }
     363              : 
     364              : /**
     365              :  * @brief      save msg to file with binary file, must be reentrant, cannot print msg
     366              :  * @param [in] tracer:          tracer pointer
     367              :  * @param [in] timeStamp:       timestamp
     368              :  * @return     NA
     369              :  */
     370          131 : TraStatus TracerScheduleSafeSave(Tracer* tracer, uint64_t timeStamp)
     371              : {
     372          131 :     if (tracer->mgr == NULL) {
     373           22 :         return TRACE_FAILURE;
     374              :     }
     375          109 :     char dirTimeStr[TIMESTAMP_MAX_LENGTH] = {0};
     376          109 :     TraStatus ret = TimestampToFileStr(timeStamp, dirTimeStr, TIMESTAMP_MAX_LENGTH);
     377          109 :     if (ret != TRACE_SUCCESS) {
     378            0 :         return TRACE_FAILURE;
     379              :     }
     380        11009 :     for (int32_t i = 0; i < MAX_OBJECT_NUM; i++) {
     381        10900 :         if ((tracer->mgr->obj[i].status != (int32_t)OBJ_STATUS_WORKING) || (tracer->mgr->obj[i].pid != TraceGetPid())) {
     382        10832 :             continue;
     383              :         }
     384              :         // read from ringbuffer, then write to file
     385           68 :         struct RbLog* rb = (RbLog*)tracer->mgr->obj[i].data;
     386           68 :         TraceRbLogPrepareForRead(rb);
     387           68 :         if (TracerScheduleCheckListEmpty(rb)) {
     388           45 :             TracerScheduleSaveObjDataSafe(rb, dirTimeStr, tracer->mgr->obj[i].name);
     389              :         } else {
     390           23 :             TracerScheduleSaveObjBinDataSafe(rb, dirTimeStr, tracer->mgr->obj[i].name);
     391              :         }
     392              :     }
     393              : 
     394          109 :     return TRACE_SUCCESS;
     395              : }
        

Generated by: LCOV version 2.0-1