LCOV - code coverage report
Current view: top level - atrace/utrace/tracer - tracer_mgr_operate_utrace.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.3 % 191 142
Test Date: 2026-08-31 10:07:06 Functions: 90.0 % 10 9

            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 "trace_recorder.h"
      14              : #include "adiag_utils.h"
      15              : #include "trace_system_api.h"
      16              : #include "trace_msg.h"
      17              : #include "utrace_socket.h"
      18              : #include "trace_attr.h"
      19              : 
      20              : #define SOCKET_MAX_DATA_SIZE 524288
      21              : 
      22           15 : STATIC TraStatus TracerGetMsgHead(UtraceMsg* traceHead, uint8_t saveType, const char* objName, const char* timeStr)
      23              : {
      24           15 :     traceHead->magic = UTRACE_HEAD_MAGIC;
      25           15 :     traceHead->version = UTRACE_HEAD_VERSION;
      26           15 :     traceHead->hostPid = TraceAttrGetGlobalPid();
      27           15 :     traceHead->devicePid = TraceAttrGetPid();
      28           15 :     traceHead->deviceId = TraceAttrGetGlobalDevId();
      29           15 :     traceHead->tracerType = TRACER_TYPE_SCHEDULE;
      30           15 :     traceHead->saveType = saveType;
      31              : 
      32           15 :     errno_t err = strcpy_s(traceHead->objName, TRACE_NAME_LENGTH, objName);
      33           15 :     if (err != EOK) {
      34            0 :         ADIAG_ERR("strcpy objName failed, result=%d, strerr=%s.", (int32_t)err, strerror(AdiagGetErrorCode()));
      35            0 :         return TRACE_FAILURE;
      36              :     }
      37           15 :     err = strcpy_s(traceHead->eventTime, TIMESTAMP_MAX_LENGTH, timeStr);
      38           15 :     if (err != EOK) {
      39            0 :         ADIAG_ERR("strcpy eventTime failed, result=%d, strerr=%s.", (int32_t)err, strerror(AdiagGetErrorCode()));
      40            0 :         return TRACE_FAILURE;
      41              :     }
      42           15 :     return TRACE_SUCCESS;
      43              : }
      44              : 
      45            8 : STATIC TraStatus TracerGetMsgData(struct RbLog* newRb, char* data, uint32_t len, uint32_t* dataPos)
      46              : {
      47            8 :     char* txt = NULL;
      48            8 :     TraStatus ret = TRACE_SUCCESS;
      49            8 :     char timestamp[TIMESTAMP_MAX_LENGTH] = {0};
      50              :     do {
      51           14 :         ret = TraceRbLogReadRbMsg(newRb, (char*)&timestamp, TIMESTAMP_MAX_LENGTH, &txt);
      52           14 :         if (ret == TRACE_RING_BUFFER_EMPTY) {
      53            8 :             break;
      54              :         }
      55            6 :         if (ret != TRACE_SUCCESS) {
      56            0 :             break;
      57              :         }
      58            6 :         if (memcpy_s(data + *dataPos, len - *dataPos, timestamp, (uint32_t)strlen(timestamp)) != EOK) {
      59            0 :             continue;
      60              :         }
      61            6 :         *dataPos += (uint32_t)strlen(timestamp);
      62            6 :         uint32_t txtLen = (uint32_t)strlen(txt);
      63            6 :         if (memcpy_s(data + *dataPos, len - *dataPos, txt, txtLen) != EOK) {
      64            0 :             continue;
      65              :         }
      66            6 :         *dataPos += txtLen;
      67            6 :         if ((txtLen > 0) && (txt[txtLen - 1U] != '\n')) {
      68            6 :             if (memcpy_s(data + *dataPos, len - *dataPos, "\n", 1) != EOK) {
      69            0 :                 continue;
      70              :             }
      71            6 :             *dataPos += 1U;
      72              :         }
      73            6 :     } while (ret == TRACE_SUCCESS);
      74            8 :     return TRACE_SUCCESS;
      75              : }
      76              : 
      77              : /**
      78              :  * @brief      save msg to file with txt file
      79              :  * @param [in] newRb:           ringbuffer
      80              :  * @param [in] timeStr:         time stamp of file name
      81              :  * @param [in] objName:         object name
      82              :  * @return     NA
      83              :  */
      84            8 : void TracerScheduleSaveObjData(struct RbLog* newRb, const char* timeStr, const char* eventName, const char* objName)
      85              : {
      86              :     (void)eventName;
      87            8 :     if (TraceAttrGetSaveMode() != 1) {
      88            0 :         return;
      89              :     }
      90            8 :     UtraceMsg* buffer = (UtraceMsg*)AdiagMalloc(SOCKET_MAX_DATA_SIZE);
      91            8 :     if (buffer == NULL) {
      92            0 :         ADIAG_ERR("malloc for send msg to utrace server failed, strerr = %s.", strerror(AdiagGetErrorCode()));
      93            0 :         return;
      94              :     }
      95              : 
      96            8 :     if (TracerGetMsgHead(buffer, FILE_SAVE_MODE_CHAR, objName, timeStr) != TRACE_SUCCESS) {
      97            0 :         ADIAG_SAFE_FREE(buffer);
      98            0 :         ADIAG_ERR("get timestamp failed, objName = %s.", objName);
      99            0 :         return;
     100              :     }
     101              : 
     102            8 :     uint32_t pos = 0;
     103            8 :     if ((TracerGetMsgData(newRb, buffer->data, SOCKET_MAX_DATA_SIZE - (uint32_t)sizeof(UtraceMsg), &pos) !=
     104              :          TRACE_SUCCESS)) {
     105            0 :         ADIAG_SAFE_FREE(buffer);
     106            0 :         ADIAG_ERR("get msg data failed, objName = %s.", objName);
     107            0 :         return;
     108              :     }
     109            8 :     if (pos == 0) {
     110            2 :         ADIAG_SAFE_FREE(buffer);
     111            2 :         ADIAG_INF("no date need to save, objName = %s.", objName);
     112            2 :         return;
     113              :     }
     114            6 :     buffer->dataLength = pos;
     115              : 
     116            6 :     if (UtraceWriteSocket(TraceAttrGetGlobalDevId(), (char*)buffer, (uint32_t)sizeof(UtraceMsg) + pos) !=
     117              :         TRACE_SUCCESS) {
     118            1 :         ADIAG_SAFE_FREE(buffer);
     119            1 :         ADIAG_ERR(
     120              :             "write trace data to socket failed, objName = %s. strerror %s.", objName, strerror(AdiagGetErrorCode()));
     121            1 :         return;
     122              :     }
     123            5 :     ADIAG_SAFE_FREE(buffer);
     124            5 :     ADIAG_INF("write trace data to socket successfully, objName = %s.", objName);
     125            5 :     return;
     126              : }
     127              : 
     128            7 : STATIC TraStatus TracerGetTraceCtrl(const struct RbLog* rb, char* data, uint32_t len, uint32_t* dataPos)
     129              : {
     130            7 :     TraceCtrlHead traceCtrl = {0};
     131            7 :     traceCtrl.magic = TRACE_MAGIC;
     132            7 :     traceCtrl.version = TRACE_VERSION;
     133            7 :     traceCtrl.pos = TRACE_POS_DEVICE;
     134            7 :     traceCtrl.traceType = TRACE_TYPE_BIN;
     135            7 :     traceCtrl.dataSize = rb->head.msgSize * TracerRbLogGetMsgNum(rb);
     136            7 :     traceCtrl.realTime = rb->head.realTime;
     137            7 :     traceCtrl.minutesWest = rb->head.minutesWest;
     138            7 :     traceCtrl.cpuFreq = rb->head.cpuFreq;
     139            7 :     traceCtrl.structSize = (uint32_t)sizeof(TraceStructSegmentHead);
     140           77 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
     141           70 :         if ((rb->entry[i].list == NULL) || (ListEmpty(&((struct AdiagList*)rb->entry[i].list)->list))) {
     142           63 :             continue;
     143              :         }
     144            7 :         traceCtrl.structSize += (uint32_t)sizeof(TraceStructHead) +
     145            7 :                                 ((struct AdiagList*)rb->entry[i].list)->cnt * (uint32_t)sizeof(TraceStructField);
     146              :     }
     147            7 :     if (memcpy_s(data + *dataPos, len - *dataPos, (char*)&traceCtrl, sizeof(TraceCtrlHead)) != EOK) {
     148            0 :         ADIAG_ERR("memcpy log ctrl failed, strerr=%s.", strerror(AdiagGetErrorCode()));
     149            0 :         return TRACE_FAILURE;
     150              :     }
     151            7 :     *dataPos += (uint32_t)sizeof(TraceCtrlHead);
     152            7 :     return TRACE_SUCCESS;
     153              : }
     154              : 
     155            7 : STATIC TraStatus TracerScheduleSaveStructSegment(const struct RbLog* rb, char* data, uint32_t len, uint32_t* dataPos)
     156              : {
     157            7 :     TraceStructSegmentHead structSegmentHead = {0};
     158           77 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
     159           70 :         if ((rb->entry[i].list == NULL) || (ListEmpty(&((struct AdiagList*)rb->entry[i].list)->list))) {
     160           63 :             continue;
     161              :         }
     162            7 :         structSegmentHead.structCount++;
     163              :     }
     164            7 :     if (memcpy_s(data + *dataPos, len - *dataPos, (char*)&structSegmentHead, sizeof(TraceStructSegmentHead)) != EOK) {
     165            0 :         ADIAG_ERR("memcpy struct segment head failed, strerr=%s.", strerror(AdiagGetErrorCode()));
     166            0 :         return TRACE_FAILURE;
     167              :     }
     168            7 :     *dataPos += (uint32_t)sizeof(TraceStructSegmentHead);
     169              : 
     170           77 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
     171           70 :         struct AdiagList* traList = (struct AdiagList*)(rb->entry[i].list);
     172           70 :         if ((traList == NULL) || (ListEmpty(&traList->list))) {
     173           63 :             continue;
     174              :         }
     175            7 :         TraceStructHead structHead = {0};
     176            7 :         structHead.structType = (uint8_t)i;
     177            7 :         structHead.itemNum = ((struct AdiagList*)rb->entry[i].list)->cnt;
     178            7 :         errno_t err = strcpy_s(structHead.structName, TRACE_NAME_LENGTH, rb->entry[i].name);
     179            7 :         if (err != EOK) {
     180            0 :             ADIAG_ERR("copy struct name failed, struct name=%s.", rb->entry[i].name);
     181              :         }
     182            7 :         if (memcpy_s(data + *dataPos, len - *dataPos, (char*)&structHead, sizeof(TraceStructHead)) != EOK) {
     183            0 :             ADIAG_ERR(
     184              :                 "memcpy struct head failed, entry name=%s, struct name=%s, strerr=%s.", rb->entry[i].name,
     185              :                 structHead.structName, strerror(AdiagGetErrorCode()));
     186            0 :             continue;
     187              :         }
     188            7 :         *dataPos += (uint32_t)sizeof(TraceStructHead);
     189              : 
     190            7 :         struct AdiagListNode* node = NULL;
     191            7 :         struct ListHead* pos = NULL;
     192              : 
     193           69 :         LIST_FOR_EACH(pos, &traList->list)
     194              :         {
     195           62 :             node = LIST_ENTRY(pos, struct AdiagListNode, list);
     196          124 :             if ((node == NULL) ||
     197           62 :                 (memcpy_s(data + *dataPos, len - *dataPos, node->data, sizeof(TraceStructField)) != EOK)) {
     198            0 :                 ADIAG_ERR(
     199              :                     "get trace struct field failed, struct name=%s, strerr=%s.", rb->entry[i].name,
     200              :                     strerror(AdiagGetErrorCode()));
     201            0 :                 return TRACE_FAILURE;
     202              :             }
     203           62 :             *dataPos += (uint32_t)sizeof(TraceStructField);
     204              :         }
     205              :     }
     206            7 :     return TRACE_SUCCESS;
     207              : }
     208              : 
     209            7 : STATIC TraStatus TracerScheduleSaveDataHead(const struct RbLog* rb, char* data, uint32_t len, uint32_t* dataPos)
     210              : {
     211            7 :     TraceStructDataHead dataHead = {0};
     212            7 :     dataHead.msgSize = rb->head.msgSize;
     213            7 :     dataHead.msgTxtSize = rb->head.msgTxtSize;
     214            7 :     dataHead.msgNum = TracerRbLogGetMsgNum(rb);
     215            7 :     if (memcpy_s(data + *dataPos, len - *dataPos, (char*)&dataHead, sizeof(TraceStructDataHead)) != EOK) {
     216            0 :         ADIAG_ERR("memcpy data head failed, strerr=%s.", strerror(AdiagGetErrorCode()));
     217            0 :         return TRACE_FAILURE;
     218              :     }
     219            7 :     *dataPos += (uint32_t)sizeof(TraceStructDataHead);
     220            7 :     return TRACE_SUCCESS;
     221              : }
     222              : 
     223            7 : STATIC TraStatus TracerGetDataStruct(const struct RbLog* newRb, char* data, uint32_t len, uint32_t* dataPos)
     224              : {
     225            7 :     if (TracerGetTraceCtrl(newRb, data, len, dataPos) != TRACE_SUCCESS) {
     226            0 :         ADIAG_ERR("get log ctrl failed.");
     227            0 :         return TRACE_FAILURE;
     228              :     }
     229              : 
     230            7 :     if (TracerScheduleSaveStructSegment(newRb, data, len, dataPos) != TRACE_SUCCESS) {
     231            0 :         ADIAG_ERR("write struct segment failed.");
     232            0 :         return TRACE_FAILURE;
     233              :     }
     234              : 
     235            7 :     if (TracerScheduleSaveDataHead(newRb, data, len, dataPos) != TRACE_SUCCESS) {
     236            0 :         ADIAG_ERR("write data head failed.");
     237            0 :         return TRACE_FAILURE;
     238              :     }
     239            7 :     return TRACE_SUCCESS;
     240              : }
     241              : 
     242            7 : STATIC TraStatus TracerGetOriMsgData(struct RbLog* newRb, char* data, uint32_t len, uint32_t* dataPos)
     243              : {
     244            7 :     if (TracerGetDataStruct(newRb, data, len, dataPos) != TRACE_SUCCESS) {
     245            0 :         ADIAG_ERR("get data struct failed.");
     246            0 :         return TRACE_FAILURE;
     247              :     }
     248              : 
     249            7 :     char* txt = NULL;
     250            7 :     uint32_t txtLen = 0;
     251            7 :     TraStatus ret = TRACE_SUCCESS;
     252            7 :     uint32_t dataLen = *dataPos;
     253              :     do {
     254           67 :         ret = TraceRbLogReadOriRbMsg(newRb, &txt, &txtLen);
     255           67 :         if (ret == TRACE_RING_BUFFER_EMPTY) {
     256            7 :             break;
     257              :         }
     258           60 :         if (ret != TRACE_SUCCESS) {
     259            0 :             break;
     260              :         }
     261           60 :         if (memcpy_s(data + dataLen, len - dataLen, txt, txtLen) != EOK) {
     262            0 :             continue;
     263              :         }
     264           60 :         dataLen += txtLen;
     265           60 :     } while (ret == TRACE_SUCCESS);
     266              :     // if data is null, clear dataPos
     267            7 :     *dataPos = (*dataPos == dataLen) ? 0 : dataLen;
     268            7 :     return TRACE_SUCCESS;
     269              : }
     270              : 
     271              : /**
     272              :  * @brief      save msg to file with binary file
     273              :  * @param [in] newRb:           ringbuffer
     274              :  * @param [in] timeStr:         time stamp of file name
     275              :  * @param [in] objName:         object name
     276              :  * @return     NA
     277              :  */
     278            7 : void TracerScheduleSaveObjBinData(struct RbLog* newRb, const char* timeStr, const char* eventName, const char* objName)
     279              : {
     280              :     (void)eventName;
     281            7 :     if (TraceAttrGetSaveMode() != 1) {
     282            0 :         return;
     283              :     }
     284            7 :     UtraceMsg* buffer = (UtraceMsg*)AdiagMalloc(SOCKET_MAX_DATA_SIZE);
     285            7 :     if (buffer == NULL) {
     286            0 :         ADIAG_ERR("malloc for send msg to utrace server failed, strerr = %s.", strerror(AdiagGetErrorCode()));
     287            0 :         return;
     288              :     }
     289              : 
     290            7 :     if (TracerGetMsgHead(buffer, FILE_SAVE_MODE_BIN, objName, timeStr) != TRACE_SUCCESS) {
     291            0 :         ADIAG_SAFE_FREE(buffer);
     292            0 :         ADIAG_ERR("get timestamp failed, objName = %s.", objName);
     293            0 :         return;
     294              :     }
     295            7 :     uint32_t pos = 0;
     296            7 :     if ((TracerGetOriMsgData(newRb, buffer->data, SOCKET_MAX_DATA_SIZE - (uint32_t)sizeof(UtraceMsg), &pos) !=
     297              :          TRACE_SUCCESS)) {
     298            0 :         ADIAG_SAFE_FREE(buffer);
     299            0 :         ADIAG_ERR("get msg data failed, objName = %s.", objName);
     300            0 :         return;
     301              :     }
     302            7 :     if (pos == 0) {
     303            1 :         ADIAG_SAFE_FREE(buffer);
     304            1 :         ADIAG_INF("no date need to save, objName = %s.", objName);
     305            1 :         return;
     306              :     }
     307            6 :     buffer->dataLength = pos;
     308              : 
     309            6 :     if (UtraceWriteSocket(TraceAttrGetGlobalDevId(), (char*)buffer, (uint32_t)sizeof(UtraceMsg) + pos) !=
     310              :         TRACE_SUCCESS) {
     311            2 :         ADIAG_SAFE_FREE(buffer);
     312            2 :         ADIAG_ERR("write trace data to socket failed, objName = %s.", objName);
     313            2 :         return;
     314              :     }
     315            4 :     ADIAG_SAFE_FREE(buffer);
     316            4 :     return;
     317              : }
     318              : 
     319            0 : TraStatus TracerScheduleSafeSave(Tracer* tracer, uint64_t timeStamp)
     320              : {
     321              :     (void)tracer;
     322              :     (void)timeStamp;
     323            0 :     return TRACE_SUCCESS;
     324              : }
        

Generated by: LCOV version 2.0-1