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-08-31 10:07:06 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        91460 : TraStatus TracerObjSubmit(TraHandle handle, uint8_t bufferType, const void* buffer, uint32_t bufSize)
      26              : {
      27        91460 :     if (handle < 0) {
      28           24 :         return TRACE_FAILURE;
      29              :     }
      30        91436 :     TracerObject* obj = (TracerObject*)handle;
      31        91436 :     if (obj == NULL) {
      32            0 :         return TRACE_FAILURE;
      33              :     }
      34        91436 :     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        91436 :     if (obj->noLock == TRACE_LOCK_FREE) {
      39           26 :         return TraceRbLogWriteRbMsgNoLock((RbLog*)obj->data, bufferType, (const char*)buffer, bufSize);
      40              :     } else {
      41        91410 :         return TraceRbLogWriteRbMsg((RbLog*)obj->data, bufferType, (const char*)buffer, bufSize);
      42              :     }
      43              : }
      44              : 
      45          922 : TraHandle TracerObjCreate(TracerType tracerType, const char* objName, const TraceAttr* attr)
      46              : {
      47          922 :     ADIAG_CHK_NULL_PTR(attr, return TRACE_INVALID_HANDLE);
      48              : 
      49          922 :     if ((g_tracers[tracerType].mgr != NULL) && (g_tracers[tracerType].mgr->op.tracerCreateFunc != NULL)) {
      50          922 :         TraObjHandle hdl = g_tracers[tracerType].mgr->op.tracerCreateFunc(&g_tracers[tracerType], objName, attr);
      51          922 :         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           72 : TraHandle TracerObjGet(TracerType tracerType, const char* objName)
      58              : {
      59           72 :     ADIAG_CHK_EXPR_ACTION(
      60              :         tracerType >= TRACER_TYPE_MAX, return TRACE_INVALID_HANDLE, "tracer type %d is invalid.", (int32_t)tracerType);
      61           72 :     ADIAG_CHK_NULL_PTR(objName, return TRACE_INVALID_HANDLE);
      62              : 
      63           72 :     if ((g_tracers[tracerType].mgr != NULL) && (g_tracers[tracerType].mgr->op.tracerGetFunc != NULL)) {
      64           72 :         TraObjHandle hdl = g_tracers[tracerType].mgr->op.tracerGetFunc(&g_tracers[tracerType], objName);
      65           72 :         return hdl;
      66              :     }
      67              : 
      68            0 :     return TRACE_INVALID_HANDLE;
      69              : }
      70              : 
      71          968 : void TracerObjDestroy(TraHandle handle)
      72              : {
      73          968 :     if (handle < 0) {
      74           72 :         ADIAG_ERR("handle %ld is invalid.", (long)handle);
      75           72 :         return;
      76              :     }
      77          896 :     TracerObject* obj = (TracerObject*)handle;
      78          896 :     if (obj == NULL) {
      79           24 :         ADIAG_ERR("handle is null.");
      80           24 :         return;
      81              :     }
      82              : 
      83          916 :     for (uint8_t i = 0; i < obj->relatedEventNum; i++) {
      84           44 :         (void)TraceEventUnbindTrace(obj->relatedEvent[i], handle);
      85              :     }
      86          872 :     obj->relatedEventNum = 0;
      87              : 
      88          872 :     int32_t tracerType = obj->tracerType;
      89          872 :     ADIAG_CHK_EXPR_ACTION(tracerType >= (int32_t)TRACER_TYPE_MAX, return, "handle %ld is invalid.", (long)handle);
      90          872 :     ADIAG_DBG("AtraceDestroy [%s].", obj->name);
      91          872 :     if ((g_tracers[tracerType].mgr != NULL) && (g_tracers[tracerType].mgr->op.tracerDestroyFunc != NULL)) {
      92          872 :         (void)g_tracers[tracerType].mgr->op.tracerDestroyFunc(&g_tracers[tracerType], handle);
      93              :     }
      94              : }
      95              : 
      96          126 : TraStatus TracerSave(TracerType tracerType, bool syncFlag)
      97              : {
      98          126 :     ADIAG_CHK_EXPR_ACTION(
      99              :         tracerType >= TRACER_TYPE_MAX, return TRACE_INVALID_PARAM, "tracer type %d is invalid.", (int32_t)tracerType);
     100          126 :     TracerMgr* mgr = g_tracers[tracerType].mgr;
     101          126 :     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          126 :     return TraceEventReport(mgr->innerEvent);
     107              : }
     108              : 
     109          126 : TraStatus TracerSaveTracer(Tracer* tracer)
     110              : {
     111          126 :     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          126 :     return (tracer->mgr->op.tracerSaveFunc)(tracer, NULL);
     116              : }
     117              : 
     118          220 : TraStatus TracerSaveObj(TracerObject* obj)
     119              : {
     120          220 :     ADIAG_CHK_NULL_PTR(obj, return TRACE_FAILURE);
     121              : 
     122          220 :     Tracer* tracer = &g_tracers[obj->tracerType];
     123          220 :     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          220 :     return (tracer->mgr->op.tracerSaveFunc)(tracer, obj);
     128              : }
     129              : 
     130          982 : TraStatus TracerInit(void)
     131              : {
     132         3928 :     for (int32_t i = 0; i < (int32_t)TRACER_TYPE_MAX; i++) {
     133         2946 :         if (g_tracers[i].tracerRegisterFunc != NULL) {
     134          982 :             TraStatus ret = g_tracers[i].tracerRegisterFunc(&g_tracers[i]);
     135          982 :             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         2946 :         if ((g_tracers[i].mgr != NULL) && (g_tracers[i].mgr->op.tracerInitFunc != NULL)) {
     142          982 :             TraStatus ret = g_tracers[i].mgr->op.tracerInitFunc(&g_tracers[i]);
     143          982 :             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          982 :     return TRACE_SUCCESS;
     151              : }
     152              : 
     153         1060 : void TracerExit(void)
     154              : {
     155         4240 :     for (int32_t i = 0; i < (int32_t)TRACER_TYPE_MAX; i++) {
     156         3180 :         if ((g_tracers[i].mgr != NULL) && (g_tracers[i].mgr->op.tracerExitFunc != NULL)) {
     157          976 :             TraStatus ret = g_tracers[i].mgr->op.tracerExitFunc(&g_tracers[i]);
     158          976 :             if (ret != TRACE_SUCCESS) {
     159            0 :                 ADIAG_ERR("%s tracer exit failed.", g_tracers[i].name);
     160              :             }
     161              :         }
     162              : 
     163         3180 :         if (g_tracers[i].tracerUnregisterFunc != NULL) {
     164         1060 :             TraStatus ret = g_tracers[i].tracerUnregisterFunc(&g_tracers[i]);
     165         1060 :             if (ret != TRACE_SUCCESS) {
     166            0 :                 ADIAG_ERR("%s tracer unregister failed.", g_tracers[i].name);
     167              :             }
     168              :         }
     169              :     }
     170         1060 : }
     171              : 
     172          302 : void* TracerStructEntryListInit(void)
     173              : {
     174          302 :     void* list = AdiagMalloc(sizeof(struct AdiagList));
     175          302 :     if (list == NULL) {
     176           24 :         ADIAG_ERR("malloc for struct entry failed.");
     177           24 :         return NULL;
     178              :     }
     179          278 :     if (AdiagListInit((struct AdiagList*)list) != TRACE_SUCCESS) {
     180           22 :         ADIAG_ERR("init trace list failed.");
     181           22 :         ADIAG_SAFE_FREE(list);
     182           22 :         return NULL;
     183              :     }
     184          256 :     return list;
     185              : }
     186              : 
     187          280 : void TracerStructEntryName(TraceStructEntry* entry, const char* name)
     188              : {
     189          280 :     if ((entry == NULL) || (name == NULL)) {
     190            0 :         return;
     191              :     }
     192          280 :     errno_t ret = strcpy_s(entry->name, TRACE_NAME_LENGTH, name);
     193          280 :     if (ret != EOK) {
     194           24 :         ADIAG_WAR("[%s]entry name is invalid.", name);
     195           24 :         (void)memset_s(entry->name, TRACE_NAME_LENGTH, 0, TRACE_NAME_LENGTH);
     196              :     }
     197              : }
     198              : 
     199          936 : STATIC TraStatus TracerStructParamCheck(TraceStructEntry* entry, const char* name, uint8_t type, uint8_t mode)
     200              : {
     201          936 :     if ((entry == NULL) || (entry->list == NULL)) {
     202           24 :         ADIAG_ERR("entry is invalid, please init entry first.");
     203           24 :         return TRACE_FAILURE;
     204              :     }
     205          912 :     if (name == NULL) {
     206            0 :         ADIAG_ERR("field name is invalid.");
     207            0 :         return TRACE_FAILURE;
     208              :     }
     209              : 
     210          912 :     if (((type > TRACE_STRUCT_FIELD_TYPE_UINT64) && (type < TRACE_STRUCT_ARRAY_TYPE_CHAR)) ||
     211              :         (type > TRACE_STRUCT_ARRAY_TYPE_UINT64)) {
     212            0 :         ADIAG_ERR("struct type[%u] is invalid.", (uint32_t)type);
     213            0 :         return TRACE_FAILURE;
     214              :     }
     215          912 :     if (mode > TRACE_STRUCT_SHOW_MODE_CHAR) {
     216            0 :         ADIAG_ERR("struct mode[%u] is invalid.", (uint32_t)mode);
     217            0 :         return TRACE_FAILURE;
     218              :     }
     219          912 :     return TRACE_SUCCESS;
     220              : }
     221              : 
     222          936 : void TracerStructItemSet(TraceStructEntry* entry, const char* name, uint8_t type, uint8_t mode, uint16_t length)
     223              : {
     224          936 :     if (TracerStructParamCheck(entry, name, type, mode) != TRACE_SUCCESS) {
     225           24 :         ADIAG_ERR("input is invalid, add atrace struct item failed.");
     226           24 :         return;
     227              :     }
     228          912 :     TraceStructField* item = (TraceStructField*)AdiagMalloc(sizeof(TraceStructField));
     229          912 :     if (item == NULL) {
     230           22 :         ADIAG_ERR("[%s]malloc for struct field failed, field name = %s.", entry->name, name);
     231           22 :         return;
     232              :     }
     233          890 :     errno_t ret = strcpy_s(item->name, TRACE_NAME_LENGTH, name);
     234          890 :     if (ret != EOK) {
     235           24 :         ADIAG_ERR("[%s]memcpy for struct field failed, field name = %s.", entry->name, name);
     236           24 :         ADIAG_SAFE_FREE(item);
     237           24 :         return;
     238              :     }
     239          866 :     item->type = type;
     240          866 :     item->mode = mode;
     241          866 :     item->length = length;
     242          866 :     if (AdiagListInsert((struct AdiagList*)(entry->list), item) != ADIAG_SUCCESS) {
     243            0 :         ADIAG_ERR("[%s]trace struct insert to list failed, field name = %s.", entry->name, name);
     244            0 :         ADIAG_SAFE_FREE(item);
     245              :     }
     246              : }
     247              : 
     248          301 : STATIC INLINE void TraceStructEntryListExit(struct AdiagList* list)
     249              : {
     250          301 :     if (list != NULL) {
     251           46 :         (void)AdiagListDestroy(list);
     252           46 :         ADIAG_SAFE_FREE(list);
     253              :     }
     254          301 : }
     255              : 
     256          301 : void TracerStructEntryExit(TraceStructEntry* entry)
     257              : {
     258          301 :     if (entry != NULL) {
     259          301 :         (void)TraceStructEntryListExit((struct AdiagList*)entry->list);
     260          301 :         entry->list = NULL;
     261              :     }
     262          301 : }
     263              : 
     264           22 : TraceStructEntry* TraceStructEntryCreate(const char* name)
     265              : {
     266           22 :     TraceStructEntry* en = AdiagMalloc(sizeof(TraceStructEntry));
     267           22 :     if (en == NULL) {
     268            0 :         return NULL;
     269              :     }
     270           22 :     struct AdiagList* list = TracerStructEntryListInit();
     271           22 :     en->list = (void*)list;
     272           22 :     TracerStructEntryName(en, name);
     273           22 :     return en;
     274              : }
     275              : 
     276           22 : void TraceStructEntryDestroy(TraceStructEntry* en)
     277              : {
     278           22 :     if (en != NULL) {
     279           22 :         TracerStructEntryExit(en);
     280           22 :         ADIAG_SAFE_FREE(en);
     281              :     }
     282           22 : }
     283              : 
     284          154 : void TraceStructItemFieldSet(TraceStructEntry* en, const char* item, uint8_t type, uint8_t mode, uint16_t len)
     285              : {
     286          154 :     TracerStructItemSet(en, item, type, mode, len);
     287          154 : }
     288              : 
     289           66 : void TraceStructItemArraySet(TraceStructEntry* en, const char* item, uint8_t type, uint8_t mode, uint16_t len)
     290              : {
     291           66 :     TracerStructItemSet(en, item, type, mode, len);
     292           66 : }
     293              : 
     294           22 : void TraceStructSetAttr(TraceStructEntry* en, uint8_t type, TraceAttr* attr)
     295              : {
     296           22 :     if ((attr != NULL) && (en != NULL) && (type < TRACE_STRUCT_ENTRY_MAX_NUM)) {
     297           22 :         attr->handle[type] = en;
     298              :     }
     299           22 : }
     300              : 
     301          440 : STATIC bool CheckHandleValid(TraHandle handle)
     302              : {
     303          440 :     if (handle <= 0) {
     304           44 :         ADIAG_ERR("invalid handle %lld", handle);
     305           44 :         return false;
     306              :     }
     307          396 :     return true;
     308              : }
     309              : 
     310          242 : TraStatus TraceBindEvent(TraHandle handle, TraEventHandle eventHandle)
     311              : {
     312          242 :     if (!CheckHandleValid(handle)) {
     313           22 :         ADIAG_ERR("trace bind event failed");
     314           22 :         return TRACE_INVALID_PARAM;
     315              :     }
     316          220 :     TracerObject* tracer = (TracerObject*)handle;
     317          220 :     ADIAG_CHK_EXPR_ACTION(tracer == NULL, return TRACE_INVALID_PARAM, "invalid param handle %lld", handle);
     318          220 :     if (tracer->relatedEventNum >= MAX_RELATED_EVENT_NUM) {
     319            0 :         ADIAG_ERR("event bound to tracer exceeds the upper limit %u", MAX_RELATED_EVENT_NUM);
     320            0 :         return TRACE_FAILURE;
     321              :     }
     322          220 :     tracer->relatedEvent[tracer->relatedEventNum] = eventHandle;
     323          220 :     tracer->relatedEventNum++;
     324          220 :     return TRACE_SUCCESS;
     325              : }
     326              : 
     327          198 : TraStatus TraceUnbindEvent(TraHandle handle, TraEventHandle eventHandle)
     328              : {
     329          198 :     if (!CheckHandleValid(handle)) {
     330           22 :         ADIAG_ERR("trace bind event failed");
     331           22 :         return TRACE_INVALID_PARAM;
     332              :     }
     333          176 :     TracerObject* tracer = (TracerObject*)handle;
     334          176 :     ADIAG_CHK_EXPR_ACTION(tracer == NULL, return TRACE_INVALID_PARAM, "invalid param handle %lld", handle);
     335          176 :     if (tracer->relatedEventNum == 0) {
     336            0 :         ADIAG_ERR("tracer has no related event");
     337            0 :         return TRACE_FAILURE;
     338              :     }
     339          176 :     for (uint8_t i = 0; i < tracer->relatedEventNum; i++) {
     340          176 :         if (tracer->relatedEvent[i] == eventHandle) {
     341          176 :             tracer->relatedEvent[i] = tracer->relatedEvent[tracer->relatedEventNum - 1U];
     342          176 :             tracer->relatedEventNum--;
     343          176 :             return TRACE_SUCCESS;
     344              :         }
     345              :     }
     346            0 :     ADIAG_ERR("event %lld has not been bound to handle %lld", eventHandle, handle);
     347            0 :     return TRACE_FAILURE;
     348              : }
        

Generated by: LCOV version 2.0-1