1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifdef L2_STANDARD
17
18 #include "hks_error_msg.h"
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include "hks_mem.h"
24 #include "securec.h"
25 #include "hks_log.h"
26
27 static __thread uint32_t g_msgLen = 0;
28 static __thread char g_errMsg[MAX_ERROR_MESSAGE_LEN + 1];
29
HksGetThreadErrorMsgLen(void)30 uint32_t HksGetThreadErrorMsgLen(void)
31 {
32 return g_msgLen;
33 }
34
HksGetThreadErrorMsg(void)35 const char *HksGetThreadErrorMsg(void)
36 {
37 return g_errMsg;
38 }
39
HksClearThreadErrorMsg(void)40 void HksClearThreadErrorMsg(void)
41 {
42 (void)memset_s(g_errMsg, MAX_ERROR_MESSAGE_LEN + 1, 0, MAX_ERROR_MESSAGE_LEN + 1);
43 g_msgLen = 0;
44 }
45
HksAppendThreadErrMsg(const uint8_t * buff,uint32_t buffLen)46 void HksAppendThreadErrMsg(const uint8_t *buff, uint32_t buffLen)
47 {
48 if (g_msgLen + buffLen >= MAX_ERROR_MESSAGE_LEN) {
49 HILOG_ERROR(LOG_ENGINE, "[HksLog] HksAppendThreadErrMsg: buff will overflow!"
50 "g_msgLen = %{public}u, buffLen = %{public}u", g_msgLen, buffLen);
51 return;
52 }
53 if (memcpy_s(g_errMsg + g_msgLen, MAX_ERROR_MESSAGE_LEN - g_msgLen, buff, buffLen) != EOK) {
54 HILOG_ERROR(LOG_ENGINE, "[HksLog] HksAppendThreadErrMsg: memcpy_s fail!"
55 "g_msgLen = %{public}u, buffLen = %{public}u", g_msgLen, buffLen);
56 return;
57 }
58 g_msgLen += buffLen;
59 }
60
removeSubstring(const char * format,char result[MAX_ERROR_MESSAGE_LEN])61 static uint32_t removeSubstring(const char *format, char result[MAX_ERROR_MESSAGE_LEN])
62 {
63 char *pos;
64 uint32_t substringLen = strlen(LOG_PUBLIC);
65 if (substringLen == 0) {
66 HILOG_INFO(LOG_ENGINE, "nothing needs to be replaced");
67 return HKS_FAILURE;
68 }
69 uint32_t formatLen = strlen(format);
70 if (g_msgLen + (uint32_t)formatLen >= MAX_ERROR_MESSAGE_LEN - 1) {
71 HILOG_INFO(LOG_ENGINE, "drop this errMsg");
72 return HKS_FAILURE;
73 }
74 uint32_t i = 0;
75 uint32_t j = 0;
76 while (j < formatLen && (pos = strstr(format + j, LOG_PUBLIC)) != NULL) {
77 if (memcpy_s(result + i, MAX_ERROR_MESSAGE_LEN - (i + 1), format + j, pos - format - j) != EOK) {
78 HILOG_ERROR(LOG_ENGINE, "errMsg memcpy_s failed");
79 return HKS_FAILURE;
80 }
81 i += pos - format - j;
82 j = pos - format + substringLen;
83 }
84 while (j < formatLen && i <= MAX_ERROR_MESSAGE_LEN - 1) {
85 result[i++] = *(format + j);
86 j++;
87 }
88 result[i] = '\0';
89 return HKS_SUCCESS;
90 }
91
HksLog(uint32_t logLevel,const char * format,...)92 void HksLog(uint32_t logLevel, const char *format, ...)
93 {
94 #ifndef LOG_PUBLIC
95 return;
96 #endif
97 va_list ap;
98
99 if (g_msgLen == 0 || logLevel == HKS_LOG_LEVEL_E_IMPORTANT) {
100 char newFormat[MAX_ERROR_MESSAGE_LEN] = {0};
101 if (removeSubstring(format, newFormat) != HKS_SUCCESS) {
102 HILOG_INFO(LOG_ENGINE, "skip to add errMsg");
103 return;
104 }
105 va_start(ap, format);
106 char buff[MAX_ERROR_MESSAGE_LEN] = {0};
107 int32_t buffLen = vsnprintf_s(buff, MAX_ERROR_MESSAGE_LEN, MAX_ERROR_MESSAGE_LEN - 1, newFormat, ap);
108 va_end(ap);
109 if (buffLen < 0) {
110 HILOG_ERROR(LOG_ENGINE, "[HksLog] vsnprintf_s fail! ret: %{public}d, newFormat:[%{public}s]", buffLen,
111 newFormat);
112 return;
113 }
114 if (g_msgLen + (uint32_t)buffLen >= MAX_ERROR_MESSAGE_LEN) {
115 HILOG_INFO(LOG_ENGINE, "errMsg is almost full!");
116 return;
117 }
118
119 if (memcpy_s(g_errMsg + g_msgLen, MAX_ERROR_MESSAGE_LEN, buff, buffLen) != EOK) {
120 HILOG_ERROR(LOG_ENGINE, "[HksLog] copy errMsg buff fail!");
121 return;
122 }
123 g_msgLen += (uint32_t)buffLen;
124 } else {
125 va_start(ap, format);
126 char *funName = va_arg(ap, char *);
127 uint32_t lineNo = va_arg(ap, uint32_t);
128 va_end(ap);
129
130 if (funName == NULL) {
131 HILOG_ERROR(LOG_ENGINE, "[HksLog] get funName fail!");
132 return;
133 }
134 int32_t offset = sprintf_s(g_errMsg + g_msgLen, MAX_ERROR_MESSAGE_LEN - g_msgLen, " <%s[%u]",
135 funName, lineNo);
136 if (offset <= 0) {
137 HILOG_ERROR(LOG_ENGINE, "[HksLog] append call chain fail! offset: [%{public}d]", offset);
138 return;
139 }
140 g_msgLen += (uint32_t)offset;
141 }
142 }
143
144 #endif