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 650 : void StacktraceLogSetPathSuffix(const char *path, const char *name, const char *suffix)
32 : {
33 650 : if (g_stackLogMgr == NULL) {
34 18 : return;
35 : }
36 632 : if ((strstr(path, "../") != NULL) || (strstr(name, "../") != NULL)) {
37 36 : LOGE("file path [%s] or file name [%s] is not allowed", path, name);
38 36 : return;
39 : }
40 596 : int32_t ret = snprintf_s(g_stackLogMgr->path, SCD_MAX_FULLPATH_LEN + 1U, SCD_MAX_FULLPATH_LEN, "%s/%s%s",
41 : path, name, suffix);
42 596 : if (ret == -1) {
43 18 : LOGE("snprintf_s file path failed");
44 18 : return;
45 : }
46 : }
47 :
48 122 : void StacktraceLogSetPath(const char *path, const char *name)
49 : {
50 122 : StacktraceLogSetPathSuffix(path, name, ".txt");
51 122 : }
52 :
53 1471 : void StacktraceLogInner(const char *format, ...)
54 : {
55 1471 : if (g_stackLogMgr == NULL) {
56 364 : return;
57 : }
58 1107 : int32_t writeIdx = AO_F_ADD(&g_stackLogMgr->logIndex, 1);
59 1107 : if (writeIdx >= STACKTRACE_LOG_MAX_NUM) {
60 0 : return;
61 : }
62 :
63 : va_list args;
64 1107 : va_start(args, format);
65 1107 : (void)vsnprintf_s(g_stackLogMgr->logContent[writeIdx], STACKTRACE_LOG_SIZE, STACKTRACE_LOG_SIZE, format, args) ;
66 1107 : va_end(args);
67 : }
68 :
69 479 : void StackcoreLogSaveWithFlag(uint32_t flag)
70 : {
71 479 : if (g_stackLogMgr == NULL) {
72 18 : return;
73 : }
74 :
75 461 : int32_t fd = TraceOpen(g_stackLogMgr->path, flag, 0640);
76 461 : if (fd < 0) {
77 0 : LOGE("open log file \"%s\" failed, fd=%d.", g_stackLogMgr->path, fd);
78 0 : return;
79 : }
80 :
81 461 : ScdUtilWriteTitle(fd, g_stackLogMgr->title);
82 461 : int32_t logNum = g_stackLogMgr->logIndex;
83 3115 : for (int32_t i = 0; i < logNum; i++) {
84 2654 : (void)ScdUtilWrite(fd, g_stackLogMgr->logContent[i], strlen(g_stackLogMgr->logContent[i]));
85 : }
86 461 : ScdUtilWriteNewLine(fd);
87 461 : TraceClose(&fd);
88 : }
89 :
90 447 : void StackcoreLogSave(void)
91 : {
92 447 : StackcoreLogSaveWithFlag((uint32_t)O_CREAT | (uint32_t)O_RDWR | (uint32_t)O_APPEND);
93 447 : }
94 :
95 929 : TraStatus StacktraceLogInit(const char *title)
96 : {
97 929 : g_stackLogMgr = AdiagMalloc(sizeof(StacktraceLogMgr));
98 929 : if (g_stackLogMgr == NULL) {
99 18 : LOGE("malloc for stacktrace log failed, strerr=%s.", strerror(AdiagGetErrorCode()));
100 18 : return TRACE_FAILURE;
101 : }
102 911 : errno_t err = strcpy_s(g_stackLogMgr->title, STACKTRACE_LOG_TITLE_SIZE, title);
103 911 : STACK_CHK_EXPR_ACTION(err != EOK, return TRACE_FAILURE,
104 : "strcpy_s failed, result=%d, strerr=%s.", (int32_t)err, strerror(AdiagGetErrorCode()));
105 911 : return TRACE_SUCCESS;
106 : }
107 :
108 999 : void StackcoreLogExit(void)
109 : {
110 999 : if (g_stackLogMgr != NULL) {
111 905 : ADIAG_SAFE_FREE(g_stackLogMgr);
112 : }
113 999 : }
|