LCOV - code coverage report
Current view: top level - atrace/utrace/tracer - tracer_core.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 83.1 % 201 167
Test Date: 2026-07-28 10:53:44 Functions: 100.0 % 23 23

            Line data    Source code
       1              : /**
       2              :  * Copyright (c) 2025 Huawei Technologies Co., Ltd.
       3              :  * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
       4              :  * CANN Open Software License Agreement Version 2.0 (the "License").
       5              :  * Please refer to the License for details. You may not use this file except in compliance with the License.
       6              :  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
       7              :  * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
       8              :  * See LICENSE in the root of the software repository for the full text of the License.
       9              :  */
      10              : 
      11              : #include "tracer_core.h"
      12              : #include "adiag_print.h"
      13              : #include "stacktrace_signal.h"
      14              : #include "tracer_schedule.h"
      15              : #include "trace_rb_log.h"
      16              : #include "adiag_utils.h"
      17              : #include "trace_system_api.h"
      18              : 
      19              : STATIC Tracer g_tracers[TRACER_TYPE_MAX] = {
      20              :     {TRACER_SCHEDULE_NAME,    TracerScheduleRegister, TracerScheduleUnregister, NULL},
      21              :     {"progress",   NULL, NULL, NULL},
      22              :     {"statistics", NULL, NULL, NULL},
      23              : };
      24              : 
      25        83154 : TraStatus TracerObjSubmit(TraHandle handle, uint8_t bufferType, const void *buffer, uint32_t bufSize)
      26              : {
      27        83154 :     if (handle < 0) {
      28           22 :         return TRACE_FAILURE;
      29              :     }
      30        83132 :     TracerObject *obj = (TracerObject *)handle;
      31        83132 :     if (obj == NULL) {
      32            0 :         return TRACE_FAILURE;
      33              :     }
      34        83132 :     if (obj->status != (int32_t)OBJ_STATUS_WORKING) {
      35            0 :         ADIAG_ERR("object[%s] is not working, status=%d.", obj->name, obj->status);
      36            0 :         return TRACE_FAILURE;
      37              :     }
      38        83132 :     if (obj->noLock == TRACE_LOCK_FREE) {
      39           24 :         return TraceRbLogWriteRbMsgNoLock((RbLog *)obj->data, bufferType, (const char *)buffer, bufSize);
      40              :     } else {
      41        83108 :         return TraceRbLogWriteRbMsg((RbLog *)obj->data, bufferType, (const char *)buffer, bufSize);
      42              :     }
      43              : }
      44              : 
      45          842 : TraHandle TracerObjCreate(TracerType tracerType, const char *objName, const TraceAttr *attr)
      46              : {
      47          842 :     ADIAG_CHK_NULL_PTR(attr, return TRACE_INVALID_HANDLE);
      48              : 
      49          842 :     if ((g_tracers[tracerType].mgr != NULL) && (g_tracers[tracerType].mgr->op.tracerCreateFunc != NULL)) {
      50          842 :         TraObjHandle hdl = g_tracers[tracerType].mgr->op.tracerCreateFunc(&g_tracers[tracerType], objName, attr);
      51          842 :         return hdl;
      52              :     }
      53            0 :     ADIAG_ERR("%d, g_tracers[tracerType].mgr %p", tracerType, g_tracers[tracerType].mgr);
      54            0 :     return TRACE_INVALID_HANDLE;
      55              : }
      56              : 
      57           66 : TraHandle TracerObjGet(TracerType tracerType, const char *objName)
      58              : {
      59           66 :     ADIAG_CHK_EXPR_ACTION(tracerType >= TRACER_TYPE_MAX, return TRACE_INVALID_HANDLE,
      60              :         "tracer type %d is invalid.", (int32_t)tracerType);
      61           66 :     ADIAG_CHK_NULL_PTR(objName, return TRACE_INVALID_HANDLE);
      62              : 
      63           66 :     if ((g_tracers[tracerType].mgr != NULL) && (g_tracers[tracerType].mgr->op.tracerGetFunc != NULL)) {
      64           66 :         TraObjHandle hdl = g_tracers[tracerType].mgr->op.tracerGetFunc(&g_tracers[tracerType], objName);
      65           66 :         return hdl;
      66              :     }
      67              : 
      68            0 :     return TRACE_INVALID_HANDLE;
      69              : }
      70              : 
      71          884 : void TracerObjDestroy(TraHandle handle)
      72              : {
      73          884 :     if (handle < 0) {
      74           66 :         ADIAG_ERR("handle %ld is invalid.", (long)handle);
      75           66 :         return;
      76              :     }
      77          818 :     TracerObject *obj = (TracerObject *)handle;
      78          818 :     if (obj == NULL) {
      79           22 :         ADIAG_ERR("handle is null.");
      80           22 :         return;
      81              :     }
      82              : 
      83          836 :     for (uint8_t i = 0; i < obj->relatedEventNum; i++) {
      84           40 :         (void)TraceEventUnbindTrace(obj->relatedEvent[i], handle);
      85              :     }
      86          796 :     obj->relatedEventNum = 0;
      87              : 
      88          796 :     int32_t tracerType = obj->tracerType;
      89          796 :     ADIAG_CHK_EXPR_ACTION(tracerType >= (int32_t)TRACER_TYPE_MAX, return, "handle %ld is invalid.", (long)handle);
      90          796 :     ADIAG_DBG("AtraceDestroy [%s].", obj->name);
      91          796 :     if ((g_tracers[tracerType].mgr != NULL) && (g_tracers[tracerType].mgr->op.tracerDestroyFunc != NULL)) {
      92          796 :         (void)g_tracers[tracerType].mgr->op.tracerDestroyFunc(&g_tracers[tracerType], handle);
      93              :     }
      94              : }
      95              : 
      96          116 : TraStatus TracerSave(TracerType tracerType, bool syncFlag)
      97              : {
      98          116 :     ADIAG_CHK_EXPR_ACTION(tracerType >= TRACER_TYPE_MAX, return TRACE_INVALID_PARAM,
      99              :         "tracer type %d is invalid.", (int32_t)tracerType);
     100          116 :     TracerMgr *mgr = g_tracers[tracerType].mgr;
     101          116 :     if ((mgr == NULL) || mgr->op.tracerSaveFunc == NULL || mgr->op.tracerReportFunc == NULL) {
     102            0 :         ADIAG_ERR("tracer manager has not been initialized or has been finalized");
     103            0 :         return TRACE_FAILURE;
     104              :     }
     105              :     (void)syncFlag;
     106          116 :     return TraceEventReport(mgr->innerEvent);
     107              : }
     108              : 
     109          116 : TraStatus TracerSaveTracer(Tracer *tracer)
     110              : {
     111          116 :     if ((tracer->mgr == NULL) || tracer->mgr->op.tracerSaveFunc == NULL) {
     112            0 :         ADIAG_ERR("tracer manager has not been initialized or has been finalized");
     113            0 :         return TRACE_FAILURE;
     114              :     }
     115          116 :     return (tracer->mgr->op.tracerSaveFunc)(tracer, NULL);
     116              : }
     117              : 
     118          200 : TraStatus TracerSaveObj(TracerObject *obj)
     119              : {
     120          200 :     ADIAG_CHK_NULL_PTR(obj, return TRACE_FAILURE);
     121              : 
     122          200 :     Tracer *tracer = &g_tracers[obj->tracerType];
     123          200 :     if ((tracer->mgr == NULL) || tracer->mgr->op.tracerSaveFunc == NULL) {
     124            0 :         ADIAG_ERR("tracer manager has not been initialized or has been finalized");
     125            0 :         return TRACE_FAILURE;
     126              :     }
     127          200 :     return (tracer->mgr->op.tracerSaveFunc)(tracer, obj);
     128              : }
     129              : 
     130          870 : TraStatus TracerInit(void)
     131              : {
     132         3480 :     for (int32_t i = 0; i < (int32_t)TRACER_TYPE_MAX; i++) {
     133         2610 :         if (g_tracers[i].tracerRegisterFunc != NULL) {
     134          870 :             TraStatus ret = g_tracers[i].tracerRegisterFunc(&g_tracers[i]);
     135          870 :             if (ret != TRACE_SUCCESS) {
     136            0 :                 ADIAG_ERR("%s tracer register failed.", g_tracers[i].name);
     137            0 :                 return TRACE_FAILURE;
     138              :             }
     139              :         }
     140              : 
     141         2610 :         if ((g_tracers[i].mgr != NULL) && (g_tracers[i].mgr->op.tracerInitFunc != NULL)) {
     142          870 :             TraStatus ret = g_tracers[i].mgr->op.tracerInitFunc(&g_tracers[i]);
     143          870 :             if (ret != TRACE_SUCCESS) {
     144            0 :                 ADIAG_ERR("%s tracer init failed.", g_tracers[i].name);
     145            0 :                 return TRACE_FAILURE;
     146              :             }
     147              :         }
     148              :     }
     149              : 
     150          870 :     return TRACE_SUCCESS;
     151              : }
     152              : 
     153          940 : void TracerExit(void)
     154              : {
     155         3760 :     for (int32_t i = 0; i < (int32_t)TRACER_TYPE_MAX; i++) {
     156         2820 :         if ((g_tracers[i].mgr != NULL) && (g_tracers[i].mgr->op.tracerExitFunc != NULL)) {
     157          864 :             TraStatus ret = g_tracers[i].mgr->op.tracerExitFunc(&g_tracers[i]);
     158          864 :             if (ret != TRACE_SUCCESS) {
     159            0 :                 ADIAG_ERR("%s tracer exit failed.", g_tracers[i].name);
     160              :             }
     161              :         }
     162              : 
     163         2820 :         if (g_tracers[i].tracerUnregisterFunc != NULL) {
     164          940 :             TraStatus ret = g_tracers[i].tracerUnregisterFunc(&g_tracers[i]);
     165          940 :             if (ret != TRACE_SUCCESS) {
     166            0 :                 ADIAG_ERR("%s tracer unregister failed.", g_tracers[i].name);
     167              :             }
     168              :         }
     169              :     }
     170          940 : }
     171              : 
     172          276 : void *TracerStructEntryListInit(void)
     173              : {
     174          276 :     void *list = AdiagMalloc(sizeof(struct AdiagList));
     175          276 :     if (list == NULL) {
     176           22 :         ADIAG_ERR("malloc for struct entry failed.");
     177           22 :         return NULL;
     178              :     }
     179          254 :     if (AdiagListInit((struct AdiagList *)list) != TRACE_SUCCESS) {
     180           20 :         ADIAG_ERR("init trace list failed.");
     181           20 :         ADIAG_SAFE_FREE(list);
     182           20 :         return NULL;
     183              :     }
     184          234 :     return list;
     185              : }
     186              : 
     187          256 : void TracerStructEntryName(TraceStructEntry *entry, const char *name)
     188              : {
     189          256 :     if ((entry == NULL) || (name == NULL)) {
     190            0 :         return;
     191              :     }
     192          256 :     errno_t ret = strcpy_s(entry->name, TRACE_NAME_LENGTH, name);
     193          256 :     if (ret != EOK) {
     194           22 :         ADIAG_WAR("[%s]entry name is invalid.", name);
     195           22 :         (void)memset_s(entry->name, TRACE_NAME_LENGTH, 0, TRACE_NAME_LENGTH);
     196              :     }
     197              : }
     198              : 
     199              : 
     200          858 : STATIC TraStatus TracerStructParamCheck(TraceStructEntry *entry, const char *name, uint8_t type, uint8_t mode)
     201              : {
     202          858 :     if ((entry == NULL) || (entry->list == NULL)) {
     203           22 :         ADIAG_ERR("entry is invalid, please init entry first.");
     204           22 :         return TRACE_FAILURE;
     205              :     }
     206          836 :     if (name == NULL) {
     207            0 :         ADIAG_ERR("field name is invalid.");
     208            0 :         return TRACE_FAILURE;
     209              :     }
     210              : 
     211          836 :     if (((type > TRACE_STRUCT_FIELD_TYPE_UINT64) && (type < TRACE_STRUCT_ARRAY_TYPE_CHAR)) ||
     212              :         (type > TRACE_STRUCT_ARRAY_TYPE_UINT64)) {
     213            0 :         ADIAG_ERR("struct type[%u] is invalid.", (uint32_t)type);
     214            0 :         return TRACE_FAILURE;
     215              :     }
     216          836 :     if (mode > TRACE_STRUCT_SHOW_MODE_CHAR) {
     217            0 :         ADIAG_ERR("struct mode[%u] is invalid.", (uint32_t)mode);
     218            0 :         return TRACE_FAILURE;
     219              :     }
     220          836 :     return TRACE_SUCCESS;
     221              : }
     222              : 
     223          858 : void TracerStructItemSet(TraceStructEntry *entry, const char *name, uint8_t type, uint8_t mode, uint16_t length)
     224              : {
     225          858 :     if (TracerStructParamCheck(entry, name, type, mode) != TRACE_SUCCESS) {
     226           22 :         ADIAG_ERR("input is invalid, add atrace struct item failed.");
     227           22 :         return;
     228              :     }
     229          836 :     TraceStructField *item = (TraceStructField *)AdiagMalloc(sizeof(TraceStructField));
     230          836 :     if (item == NULL) {
     231           20 :         ADIAG_ERR("[%s]malloc for struct field failed, field name = %s.", entry->name, name);
     232           20 :         return;
     233              :     }
     234          816 :     errno_t ret = strcpy_s(item->name, TRACE_NAME_LENGTH, name);
     235          816 :     if (ret != EOK) {
     236           22 :         ADIAG_ERR("[%s]memcpy for struct field failed, field name = %s.", entry->name, name);
     237           22 :         ADIAG_SAFE_FREE(item);
     238           22 :         return;
     239              :     }
     240          794 :     item->type = type;
     241          794 :     item->mode = mode;
     242          794 :     item->length = length;
     243          794 :     if (AdiagListInsert((struct AdiagList *)(entry->list), item) != ADIAG_SUCCESS) {
     244            0 :         ADIAG_ERR("[%s]trace struct insert to list failed, field name = %s.", entry->name, name);
     245            0 :         ADIAG_SAFE_FREE(item);
     246              :     }
     247              : }
     248              : 
     249          275 : STATIC INLINE void TraceStructEntryListExit(struct AdiagList *list)
     250              : {
     251          275 :     if (list != NULL) {
     252           42 :         (void)AdiagListDestroy(list);
     253           42 :         ADIAG_SAFE_FREE(list);
     254              :     }
     255          275 : }
     256              : 
     257          275 : void TracerStructEntryExit(TraceStructEntry *entry)
     258              : {
     259          275 :     if (entry != NULL) {
     260          275 :         (void)TraceStructEntryListExit((struct AdiagList *)entry->list);
     261          275 :         entry->list = NULL;
     262              :     }
     263          275 : }
     264              : 
     265           20 : TraceStructEntry *TraceStructEntryCreate(const char *name)
     266              : {
     267           20 :     TraceStructEntry *en = AdiagMalloc(sizeof(TraceStructEntry));
     268           20 :     if (en == NULL) {
     269            0 :         return NULL;
     270              :     }
     271           20 :     struct AdiagList *list = TracerStructEntryListInit();
     272           20 :     en->list = (void *)list;
     273           20 :     TracerStructEntryName(en, name);
     274           20 :     return en;
     275              : }
     276              : 
     277           20 : void TraceStructEntryDestroy(TraceStructEntry *en)
     278              : {
     279           20 :     if (en != NULL) {
     280           20 :         TracerStructEntryExit(en);
     281           20 :         ADIAG_SAFE_FREE(en);
     282              :     }
     283           20 : }
     284              : 
     285          140 : void TraceStructItemFieldSet(TraceStructEntry *en, const char *item, uint8_t type, uint8_t mode, uint16_t len)
     286              : {
     287          140 :     TracerStructItemSet(en, item, type, mode, len);
     288          140 : }
     289              : 
     290           60 : void TraceStructItemArraySet(TraceStructEntry *en, const char *item, uint8_t type, uint8_t mode, uint16_t len)
     291              : {
     292           60 :     TracerStructItemSet(en, item, type, mode, len);
     293           60 : }
     294              : 
     295           20 : void TraceStructSetAttr(TraceStructEntry *en, uint8_t type, TraceAttr *attr)
     296              : {
     297           20 :     if ((attr != NULL) && (en != NULL) && (type < TRACE_STRUCT_ENTRY_MAX_NUM)) {
     298           20 :         attr->handle[type] = en;
     299              :     }
     300           20 : }
     301              : 
     302          400 : STATIC bool CheckHandleValid(TraHandle handle)
     303              : {
     304          400 :     if (handle <= 0) {
     305           40 :         ADIAG_ERR("invalid handle %lld", handle);
     306           40 :         return false;
     307              :     }
     308          360 :     return true;
     309              : }
     310              : 
     311          220 : TraStatus TraceBindEvent(TraHandle handle, TraEventHandle eventHandle)
     312              : {
     313          220 :     if (!CheckHandleValid(handle)) {
     314           20 :         ADIAG_ERR("trace bind event failed");
     315           20 :         return TRACE_INVALID_PARAM;
     316              :     }
     317          200 :     TracerObject *tracer = (TracerObject *)handle;
     318          200 :     ADIAG_CHK_EXPR_ACTION(tracer == NULL, return TRACE_INVALID_PARAM, "invalid param handle %lld", handle);
     319          200 :     if (tracer->relatedEventNum >= MAX_RELATED_EVENT_NUM) {
     320            0 :         ADIAG_ERR("event bound to tracer exceeds the upper limit %u", MAX_RELATED_EVENT_NUM);
     321            0 :         return TRACE_FAILURE;
     322              :     }
     323          200 :     tracer->relatedEvent[tracer->relatedEventNum] = eventHandle;
     324          200 :     tracer->relatedEventNum++;
     325          200 :     return TRACE_SUCCESS;
     326              : }
     327              : 
     328          180 : TraStatus TraceUnbindEvent(TraHandle handle, TraEventHandle eventHandle)
     329              : {
     330          180 :     if (!CheckHandleValid(handle)) {
     331           20 :         ADIAG_ERR("trace bind event failed");
     332           20 :         return TRACE_INVALID_PARAM;
     333              :     }
     334          160 :     TracerObject *tracer = (TracerObject *)handle;
     335          160 :     ADIAG_CHK_EXPR_ACTION(tracer == NULL, return TRACE_INVALID_PARAM, "invalid param handle %lld", handle);
     336          160 :     if (tracer->relatedEventNum == 0) {
     337            0 :         ADIAG_ERR("tracer has no related event");
     338            0 :         return TRACE_FAILURE;
     339              :     }
     340          160 :     for (uint8_t i = 0; i < tracer->relatedEventNum; i++) {
     341          160 :         if (tracer->relatedEvent[i] == eventHandle) {
     342          160 :             tracer->relatedEvent[i] = tracer->relatedEvent[tracer->relatedEventNum - 1U];
     343          160 :             tracer->relatedEventNum--;
     344          160 :             return TRACE_SUCCESS;
     345              :         }
     346              :     }
     347            0 :     ADIAG_ERR("event %lld has not been bound to handle %lld", eventHandle, handle);
     348            0 :     return TRACE_FAILURE;
     349              : }
        

Generated by: LCOV version 2.0-1