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 : }
|