• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 #ifdef USE_NATIVE_TOKEN_KLOG
16 #include "accesstoken_klog.h"
17 #else
18 #include "accesstoken_common_log.h"
19 #endif
20 
21 #include <cstdlib>
22 #include <cstdio>
23 #include <cstdarg>
24 #include <cstdint>
25 #include <cstring>
26 #include <string>
27 #include "securec.h"
28 
29 static constexpr uint32_t MAX_ERROR_MESSAGE_LEN = 4096;
30 static __thread uint32_t g_msgLen = 0;
31 static __thread char g_errMsg[MAX_ERROR_MESSAGE_LEN + 1];
32 
33 #ifdef USE_NATIVE_TOKEN_KLOG
34 #define ACCESSTOKEN_COMMON_LOGE(domain, tag, fmt, ...) \
35     ((void)LOGE(fmt, ##__VA_ARGS__))
36 #else
37 #define ACCESSTOKEN_COMMON_LOGE(domain, tag, fmt, ...) \
38     ((void)LOGE(domain, tag, fmt, ##__VA_ARGS__))
39 #endif
40 
GetThreadErrorMsgLen(void)41 uint32_t GetThreadErrorMsgLen(void)
42 {
43     return g_msgLen;
44 }
45 
GetThreadErrorMsg(void)46 const char* GetThreadErrorMsg(void)
47 {
48     return g_errMsg;
49 }
50 
ClearThreadErrorMsg(void)51 void ClearThreadErrorMsg(void)
52 {
53     (void)memset_s(g_errMsg, MAX_ERROR_MESSAGE_LEN + 1, 0, MAX_ERROR_MESSAGE_LEN + 1);
54     g_msgLen = 0;
55 }
56 
AppendThreadErrMsg(unsigned int domain,const char * tag,const uint8_t * buff,uint32_t buffLen)57 void AppendThreadErrMsg(unsigned int domain, const char* tag,
58     const uint8_t* buff, uint32_t buffLen)
59 {
60     if (g_msgLen + buffLen >= MAX_ERROR_MESSAGE_LEN) {
61         ACCESSTOKEN_COMMON_LOGE(domain, tag, "Buff will overflow!"
62             "g_msgLen = %" LOG_PUBLIC "u, buffLen = %" LOG_PUBLIC "u", g_msgLen, buffLen);
63         return;
64     }
65     if (memcpy_s(g_errMsg + g_msgLen, MAX_ERROR_MESSAGE_LEN - g_msgLen, buff, buffLen) != EOK) {
66         ACCESSTOKEN_COMMON_LOGE(domain, tag, "Failed to memcpy_s!"
67             "g_msgLen = %" LOG_PUBLIC "u, buffLen = %" LOG_PUBLIC "u", g_msgLen, buffLen);
68         return;
69     }
70     g_msgLen += buffLen;
71 }
72 
ReplaceSubstring(unsigned int domain,const char * tag,const char * format,char result[MAX_ERROR_MESSAGE_LEN])73 static bool ReplaceSubstring(unsigned int domain, const char* tag,
74     const char* format, char result[MAX_ERROR_MESSAGE_LEN])
75 {
76     std::string formatString(format);
77 #ifndef USE_NATIVE_TOKEN_KLOG
78     std::string::size_type pos;
79     while ((pos = formatString.find(LOG_PUBLIC)) != std::string::npos) {
80         formatString.replace(pos, strlen(LOG_PUBLIC), "");
81     }
82 #endif
83     if (memcpy_s(result, MAX_ERROR_MESSAGE_LEN, formatString.c_str(), formatString.size()) != EOK) {
84         return false;
85     }
86     return true;
87 }
88 
AddEventMessage(unsigned int domain,const char * tag,const char * format,...)89 void AddEventMessage(unsigned int domain, const char* tag,
90     const char* format, ...)
91 {
92     va_list ap;
93 
94     if (g_msgLen == 0) {
95         char newFormat[MAX_ERROR_MESSAGE_LEN] = {0};
96         if (!ReplaceSubstring(domain, tag, format, newFormat)) {
97             ACCESSTOKEN_COMMON_LOGE(domain, tag, "Skip to add errMsg");
98             return;
99         }
100         va_start(ap, format);
101         char buff[MAX_ERROR_MESSAGE_LEN] = {0};
102         int32_t buffLen = vsnprintf_s(buff, MAX_ERROR_MESSAGE_LEN, MAX_ERROR_MESSAGE_LEN - 1, newFormat, ap);
103         va_end(ap);
104         if (buffLen < 0) {
105             ACCESSTOKEN_COMMON_LOGE(domain, tag,
106                 "Failed to vsnprintf_s! Ret: %" LOG_PUBLIC "d, newFormat:[%" LOG_PUBLIC "s]", buffLen, newFormat);
107             return;
108         }
109         if (g_msgLen + static_cast<uint32_t>(buffLen) >= MAX_ERROR_MESSAGE_LEN) {
110             ACCESSTOKEN_COMMON_LOGE(domain, tag, "ErrMsg is almost full!");
111             return;
112         }
113 
114         if (memcpy_s(g_errMsg + g_msgLen, MAX_ERROR_MESSAGE_LEN, buff, buffLen) != EOK) {
115             ACCESSTOKEN_COMMON_LOGE(domain, tag, "Failed to copy errMsg buff!");
116             return;
117         }
118         g_msgLen += static_cast<uint32_t>(buffLen);
119     } else {
120         va_start(ap, format);
121         char* funName = va_arg(ap, char*);
122         uint32_t lineNo = va_arg(ap, uint32_t);
123         va_end(ap);
124 
125         if (funName == nullptr) {
126             ACCESSTOKEN_COMMON_LOGE(domain, tag, "Get funName fail!");
127             return;
128         }
129         int32_t offset = sprintf_s(g_errMsg + g_msgLen, MAX_ERROR_MESSAGE_LEN - g_msgLen, " <%s[%u]",
130             funName, lineNo);
131         if (offset <= 0) {
132             ACCESSTOKEN_COMMON_LOGE(domain, tag, "Failed to append call chain! Offset: [%" LOG_PUBLIC "d]", offset);
133             return;
134         }
135         g_msgLen += static_cast<uint32_t>(offset);
136     }
137 }
138