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

Generated by: LCOV version 2.0-1