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 "stacktrace_logger.h"
12 : #include <fcntl.h>
13 : #include "trace_system_api.h"
14 : #include "scd_util.h"
15 :
16 : #define STACKTRACE_LOG_TITLE_SIZE 32U
17 : #define STACKTRACE_LOG_MAX_NUM 200
18 : #define STACKTRACE_LOG_SIZE 128U
19 :
20 : #define AO_F_ADD(ptr, value) ((__typeof__(*(ptr)))__sync_fetch_and_add((ptr), (value)))
21 :
22 : typedef struct {
23 : char title[STACKTRACE_LOG_TITLE_SIZE];
24 : char path[SCD_MAX_FULLPATH_LEN + 1U];
25 : volatile int32_t logIndex;
26 : char logContent[STACKTRACE_LOG_MAX_NUM][STACKTRACE_LOG_SIZE];
27 : } StacktraceLogMgr;
28 :
29 : STATIC StacktraceLogMgr* g_stackLogMgr = NULL;
30 :
31 726 : void StacktraceLogSetPathSuffix(const char* path, const char* name, const char* suffix)
32 : {
33 726 : if (g_stackLogMgr == NULL) {
34 20 : return;
35 : }
36 706 : if ((strstr(path, "../") != NULL) || (strstr(name, "../") != NULL)) {
37 40 : LOGE("file path [%s] or file name [%s] is not allowed", path, name);
38 40 : return;
39 : }
40 : int32_t ret =
41 666 : snprintf_s(g_stackLogMgr->path, SCD_MAX_FULLPATH_LEN + 1U, SCD_MAX_FULLPATH_LEN, "%s/%s%s", path, name, suffix);
42 666 : if (ret == -1) {
43 20 : LOGE("snprintf_s file path failed");
44 20 : return;
45 : }
46 : }
47 :
48 136 : void StacktraceLogSetPath(const char* path, const char* name) { StacktraceLogSetPathSuffix(path, name, ".txt"); }
49 :
50 1688 : void StacktraceLogInner(const char* format, ...)
51 : {
52 1688 : if (g_stackLogMgr == NULL) {
53 449 : return;
54 : }
55 1239 : int32_t writeIdx = AO_F_ADD(&g_stackLogMgr->logIndex, 1);
56 1239 : if (writeIdx >= STACKTRACE_LOG_MAX_NUM) {
57 0 : return;
58 : }
59 :
60 : va_list args;
61 1239 : va_start(args, format);
62 1239 : (void)vsnprintf_s(g_stackLogMgr->logContent[writeIdx], STACKTRACE_LOG_SIZE, STACKTRACE_LOG_SIZE, format, args);
63 1239 : va_end(args);
64 : }
65 :
66 537 : void StackcoreLogSaveWithFlag(uint32_t flag)
67 : {
68 537 : if (g_stackLogMgr == NULL) {
69 20 : return;
70 : }
71 :
72 517 : int32_t fd = TraceOpen(g_stackLogMgr->path, flag, 0640);
73 517 : if (fd < 0) {
74 0 : LOGE("open log file \"%s\" failed, fd=%d.", g_stackLogMgr->path, fd);
75 0 : return;
76 : }
77 :
78 517 : ScdUtilWriteTitle(fd, g_stackLogMgr->title);
79 517 : int32_t logNum = g_stackLogMgr->logIndex;
80 3497 : for (int32_t i = 0; i < logNum; i++) {
81 2980 : (void)ScdUtilWrite(fd, g_stackLogMgr->logContent[i], strlen(g_stackLogMgr->logContent[i]));
82 : }
83 517 : ScdUtilWriteNewLine(fd);
84 517 : TraceClose(&fd);
85 : }
86 :
87 501 : void StackcoreLogSave(void) { StackcoreLogSaveWithFlag((uint32_t)O_CREAT | (uint32_t)O_RDWR | (uint32_t)O_APPEND); }
88 :
89 1049 : TraStatus StacktraceLogInit(const char* title)
90 : {
91 1049 : g_stackLogMgr = AdiagMalloc(sizeof(StacktraceLogMgr));
92 1049 : if (g_stackLogMgr == NULL) {
93 20 : LOGE("malloc for stacktrace log failed, strerr=%s.", strerror(AdiagGetErrorCode()));
94 20 : return TRACE_FAILURE;
95 : }
96 1029 : errno_t err = strcpy_s(g_stackLogMgr->title, STACKTRACE_LOG_TITLE_SIZE, title);
97 1029 : STACK_CHK_EXPR_ACTION(
98 : err != EOK, return TRACE_FAILURE, "strcpy_s failed, result=%d, strerr=%s.", (int32_t)err,
99 : strerror(AdiagGetErrorCode()));
100 1029 : return TRACE_SUCCESS;
101 : }
102 :
103 1127 : void StackcoreLogExit(void)
104 : {
105 1127 : if (g_stackLogMgr != NULL) {
106 1023 : ADIAG_SAFE_FREE(g_stackLogMgr);
107 : }
108 1127 : }
|