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: 73.2 % 205 150
Test Date: 2026-07-28 10:53:44 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,
     104              :         SOCKET_MAX_DATA_SIZE - (uint32_t)sizeof(UtraceMsg), &pos) != 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 (!UtraceIsSocketFdValid()) {
     117            3 :         int32_t fd = UtraceCreateSocket(TraceAttrGetGlobalDevId());
     118            3 :         if (fd != TRACE_FAILURE) {
     119            3 :             UtraceSetSocketFd(fd);
     120              :         } else {
     121            0 :             ADIAG_SAFE_FREE(buffer);
     122            0 :             ADIAG_ERR("create socket failed, objName = %s, device id = %d.", objName, TraceAttrGetGlobalDevId());
     123            0 :             return;
     124              :         }
     125              :     }
     126            6 :     if (TraceRecorderWrite(UtraceGetSocketFd(), (char *)buffer, (uint32_t)sizeof(UtraceMsg) + pos) != TRACE_SUCCESS) {
     127            1 :         ADIAG_SAFE_FREE(buffer);
     128            1 :         ADIAG_ERR("write trace data to socket failed, objName = %s. strerror %s.",
     129              :             objName, strerror(AdiagGetErrorCode()));
     130            1 :         return;
     131              :     }
     132            5 :     ADIAG_SAFE_FREE(buffer);
     133            5 :     ADIAG_INF("write trace data to socket successfully, objName = %s.", objName);
     134            5 :     return;
     135              : }
     136              : 
     137            7 : STATIC TraStatus TracerGetTraceCtrl(const struct RbLog *rb, char *data, uint32_t len, uint32_t *dataPos)
     138              : {
     139            7 :     TraceCtrlHead traceCtrl = { 0 };
     140            7 :     traceCtrl.magic = TRACE_MAGIC;
     141            7 :     traceCtrl.version = TRACE_VERSION;
     142            7 :     traceCtrl.pos = TRACE_POS_DEVICE;
     143            7 :     traceCtrl.traceType = TRACE_TYPE_BIN;
     144            7 :     traceCtrl.dataSize = rb->head.msgSize * TracerRbLogGetMsgNum(rb);
     145            7 :     traceCtrl.realTime = rb->head.realTime;
     146            7 :     traceCtrl.minutesWest = rb->head.minutesWest;
     147            7 :     traceCtrl.cpuFreq = rb->head.cpuFreq;
     148            7 :     traceCtrl.structSize = (uint32_t)sizeof(TraceStructSegmentHead);
     149           77 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
     150           70 :         if ((rb->entry[i].list == NULL) || (ListEmpty(&((struct AdiagList *)rb->entry[i].list)->list))) {
     151           63 :             continue;
     152              :         }
     153            7 :         traceCtrl.structSize += (uint32_t)sizeof(TraceStructHead) +
     154            7 :             ((struct AdiagList *)rb->entry[i].list)->cnt * (uint32_t)sizeof(TraceStructField);
     155              :     }
     156            7 :     if (memcpy_s(data + *dataPos, len - *dataPos, (char *)&traceCtrl, sizeof(TraceCtrlHead)) != EOK) {
     157            0 :         ADIAG_ERR("memcpy log ctrl failed, strerr=%s.", strerror(AdiagGetErrorCode()));
     158            0 :         return TRACE_FAILURE;
     159              :     }
     160            7 :     *dataPos += (uint32_t)sizeof(TraceCtrlHead);
     161            7 :     return TRACE_SUCCESS;
     162              : }
     163              : 
     164            7 : STATIC TraStatus TracerScheduleSaveStructSegment(const struct RbLog *rb, char *data, uint32_t len, uint32_t *dataPos)
     165              : {
     166            7 :     TraceStructSegmentHead structSegmentHead = { 0 };
     167           77 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
     168           70 :         if ((rb->entry[i].list == NULL) || (ListEmpty(&((struct AdiagList *)rb->entry[i].list)->list))) {
     169           63 :             continue;
     170              :         }
     171            7 :         structSegmentHead.structCount++;
     172              :     }
     173            7 :     if (memcpy_s(data + *dataPos, len - *dataPos, (char *)&structSegmentHead, sizeof(TraceStructSegmentHead)) != EOK) {
     174            0 :         ADIAG_ERR("memcpy struct segment head failed, strerr=%s.", strerror(AdiagGetErrorCode()));
     175            0 :         return TRACE_FAILURE;
     176              :     }
     177            7 :     *dataPos += (uint32_t)sizeof(TraceStructSegmentHead);
     178              :  
     179           77 :     for (uint32_t i = 0; i < TRACE_STRUCT_ENTRY_MAX_NUM; i++) {
     180           70 :         struct AdiagList *traList = (struct AdiagList *)(rb->entry[i].list);
     181           70 :         if ((traList == NULL) || (ListEmpty(&traList->list))) {
     182           63 :             continue;
     183              :         }
     184            7 :         TraceStructHead structHead = { 0 };
     185            7 :         structHead.structType = i;
     186            7 :         structHead.itemNum = ((struct AdiagList *)rb->entry[i].list)->cnt;
     187            7 :         errno_t err = strcpy_s(structHead.structName, TRACE_NAME_LENGTH, rb->entry[i].name);
     188            7 :         if (err != EOK) {
     189            0 :             ADIAG_ERR("copy struct name failed, struct name=%s.", rb->entry[i].name);
     190              :         }
     191            7 :         if (memcpy_s(data + *dataPos, len - *dataPos, (char *)&structHead, sizeof(TraceStructHead)) != EOK) {
     192            0 :             ADIAG_ERR("memcpy struct head failed, entry name=%s, struct name=%s, strerr=%s.",
     193              :                 rb->entry[i].name, structHead.structName, strerror(AdiagGetErrorCode()));
     194            0 :             continue;
     195              :         }
     196            7 :         *dataPos += (uint32_t)sizeof(TraceStructHead);
     197              :  
     198            7 :         struct AdiagListNode *node = NULL;
     199            7 :         struct ListHead *pos = NULL;
     200              :  
     201           69 :         LIST_FOR_EACH(pos, &traList->list) {
     202           62 :             node = LIST_ENTRY(pos, struct AdiagListNode, list);
     203          124 :             if ((node == NULL) ||
     204           62 :                 (memcpy_s(data + *dataPos, len - *dataPos, node->data, sizeof(TraceStructField)) != EOK)) {
     205            0 :                 ADIAG_ERR("get trace struct field failed, struct name=%s, strerr=%s.",
     206              :                     rb->entry[i].name, strerror(AdiagGetErrorCode()));
     207            0 :                 return TRACE_FAILURE;
     208              :             }
     209           62 :             *dataPos += (uint32_t)sizeof(TraceStructField);
     210              :         }
     211              :     }
     212            7 :     return TRACE_SUCCESS;
     213              : }
     214              : 
     215            7 : STATIC TraStatus TracerScheduleSaveDataHead(const struct RbLog *rb, char *data, uint32_t len, uint32_t *dataPos)
     216              : {
     217            7 :     TraceStructDataHead dataHead = { 0 };
     218            7 :     dataHead.msgSize = rb->head.msgSize;
     219            7 :     dataHead.msgTxtSize = rb->head.msgTxtSize;
     220            7 :     dataHead.msgNum = TracerRbLogGetMsgNum(rb);
     221            7 :     if (memcpy_s(data + *dataPos, len - *dataPos, (char *)&dataHead, sizeof(TraceStructDataHead)) != EOK) {
     222            0 :         ADIAG_ERR("memcpy data head failed, strerr=%s.", strerror(AdiagGetErrorCode()));
     223            0 :         return TRACE_FAILURE;
     224              :     }
     225            7 :     *dataPos += (uint32_t)sizeof(TraceStructDataHead);
     226            7 :     return TRACE_SUCCESS;
     227              : }
     228              : 
     229            7 : STATIC TraStatus TracerGetDataStruct(const struct RbLog *newRb, char *data, uint32_t len, uint32_t *dataPos)
     230              : {
     231            7 :     if (TracerGetTraceCtrl(newRb, data, len, dataPos) != TRACE_SUCCESS) {
     232            0 :         ADIAG_ERR("get log ctrl failed.");
     233            0 :         return TRACE_FAILURE;
     234              :     }
     235              :  
     236            7 :     if (TracerScheduleSaveStructSegment(newRb, data, len, dataPos) != TRACE_SUCCESS) {
     237            0 :         ADIAG_ERR("write struct segment failed.");
     238            0 :         return TRACE_FAILURE;
     239              :     }
     240              :  
     241            7 :     if (TracerScheduleSaveDataHead(newRb, data, len, dataPos) != TRACE_SUCCESS) {
     242            0 :         ADIAG_ERR("write data head failed.");
     243            0 :         return TRACE_FAILURE;
     244              :     }
     245            7 :     return TRACE_SUCCESS;
     246              : }
     247              : 
     248            7 : STATIC TraStatus TracerGetOriMsgData(struct RbLog *newRb, char *data, uint32_t len, uint32_t *dataPos)
     249              : {
     250            7 :     if (TracerGetDataStruct(newRb, data, len, dataPos) != TRACE_SUCCESS) {
     251            0 :         ADIAG_ERR("get data struct failed.");
     252            0 :         return TRACE_FAILURE;
     253              :     }
     254              : 
     255            7 :     char *txt = NULL;
     256            7 :     uint32_t txtLen = 0;
     257            7 :     TraStatus ret = TRACE_SUCCESS;
     258            7 :     uint32_t dataLen = *dataPos;
     259              :     do {
     260           67 :         ret = TraceRbLogReadOriRbMsg(newRb, &txt, &txtLen);
     261           67 :         if (ret == TRACE_RING_BUFFER_EMPTY) {
     262            7 :             break;
     263              :         }
     264           60 :         if (ret != TRACE_SUCCESS) {
     265            0 :             break;
     266              :         }
     267           60 :         if (memcpy_s(data + dataLen, len - dataLen, txt, txtLen) != EOK) {
     268            0 :             continue;
     269              :         }
     270           60 :         dataLen += txtLen;
     271           60 :     } while (ret == TRACE_SUCCESS);
     272              :     // if data is null, clear dataPos
     273            7 :     *dataPos = (*dataPos == dataLen) ? 0 : dataLen;
     274            7 :     return TRACE_SUCCESS;
     275              : }
     276              : 
     277              : /**
     278              :  * @brief      save msg to file with binary file
     279              :  * @param [in] newRb:           ringbuffer
     280              :  * @param [in] timeStr:         time stamp of file name
     281              :  * @param [in] objName:         object name
     282              :  * @return     NA
     283              :  */
     284            7 : void TracerScheduleSaveObjBinData(struct RbLog *newRb, const char *timeStr, const char *eventName, const char *objName)
     285              : {
     286              :     (void)eventName;
     287            7 :     if (TraceAttrGetSaveMode() != 1) {
     288            0 :         return;
     289              :     }
     290            7 :     UtraceMsg *buffer = (UtraceMsg *)AdiagMalloc(SOCKET_MAX_DATA_SIZE);
     291            7 :     if (buffer == NULL) {
     292            0 :         ADIAG_ERR("malloc for send msg to utrace server failed, strerr = %s.", strerror(AdiagGetErrorCode()));
     293            0 :         return;
     294              :     }
     295              : 
     296            7 :     if (TracerGetMsgHead(buffer, FILE_SAVE_MODE_BIN, objName, timeStr) != TRACE_SUCCESS) {
     297            0 :         ADIAG_SAFE_FREE(buffer);
     298            0 :         ADIAG_ERR("get timestamp failed, objName = %s.", objName);
     299            0 :         return;
     300              :     }
     301            7 :     uint32_t pos = 0;
     302            7 :     if ((TracerGetOriMsgData(newRb, buffer->data,
     303              :         SOCKET_MAX_DATA_SIZE - (uint32_t)sizeof(UtraceMsg), &pos) != TRACE_SUCCESS)) {
     304            0 :         ADIAG_SAFE_FREE(buffer);
     305            0 :         ADIAG_ERR("get msg data failed, objName = %s.", objName);
     306            0 :         return;
     307              :     }
     308            7 :     if (pos == 0) {
     309            1 :         ADIAG_SAFE_FREE(buffer);
     310            1 :         ADIAG_INF("no date need to save, objName = %s.", objName);
     311            1 :         return;
     312              :     }
     313            6 :     buffer->dataLength = pos;
     314              : 
     315            6 :     if (!UtraceIsSocketFdValid()) {
     316            4 :         int32_t fd = UtraceCreateSocket(TraceAttrGetGlobalDevId());
     317            4 :         if (fd != TRACE_FAILURE) {
     318            2 :             UtraceSetSocketFd(fd);
     319              :         } else {
     320            2 :             ADIAG_SAFE_FREE(buffer);
     321            2 :             ADIAG_ERR("create socket failed, objName = %s, device id = %d.", objName, TraceAttrGetGlobalDevId());
     322            2 :             return;
     323              :         }
     324              :     }
     325            4 :     if (TraceRecorderWrite(UtraceGetSocketFd(), (char *)buffer, (uint32_t)sizeof(UtraceMsg) + pos) != TRACE_SUCCESS) {
     326            0 :         ADIAG_SAFE_FREE(buffer);
     327            0 :         ADIAG_ERR("write trace data to socket failed, objName = %s.", objName);
     328            0 :         return;
     329              :     }
     330            4 :     ADIAG_SAFE_FREE(buffer);
     331            4 :     return;
     332              : }
     333              : 
     334            0 : TraStatus TracerScheduleSafeSave(Tracer *tracer, uint64_t timeStamp)
     335              : {
     336              :     (void)tracer;
     337              :     (void)timeStamp;
     338            0 :     return TRACE_SUCCESS;
     339              : }
        

Generated by: LCOV version 2.0-1