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 "dump.h"
12 :
13 : #include <mutex>
14 : #include <sstream>
15 : #include <set>
16 :
17 : #include "mmpa/mmpa_api.h"
18 : #include "adump_pub.h"
19 : #include "dump_shim.h"
20 :
21 : #include "common/json_parser.h"
22 : #include "common/error_codes_inner.h"
23 :
24 : #include "common/log_inner.h"
25 : #include "utils/string_utils.h"
26 : #include "aclrt_impl/acl_rt_impl_base.h"
27 : #include "acl_rt_impl.h"
28 :
29 : namespace {
30 : bool aclmdlInitDumpFlag = false;
31 : std::mutex aclDumpMutex;
32 : constexpr int32_t ADX_ERROR_NONE = 0;
33 : } // namespace
34 :
35 : namespace acl {
36 93 : AclDump& AclDump::GetInstance()
37 : {
38 : static AclDump aclDumpProc;
39 93 : return aclDumpProc;
40 : }
41 :
42 33 : aclError AclDump::HandleDumpCommand(const char* configStr, size_t size, const char* configPath)
43 : {
44 33 : ACL_LOG_INFO("start to execute HandleDumpCommand.");
45 :
46 33 : const auto& funcs = acl::GetAdumpCallbacks();
47 33 : if (funcs.serverInit == nullptr) {
48 1 : ACL_LOG_INNER_ERROR("[Check][DumpCallback]Adump server init callback is not registered.");
49 1 : return ACL_ERROR_INTERNAL_ERROR;
50 : }
51 32 : int32_t adxRet = funcs.serverInit();
52 32 : if (adxRet != ADX_ERROR_NONE) {
53 1 : ACL_LOG_INNER_ERROR("[AdxDataDumpServer][Init]dump server run failed, adx errorCode = %d", adxRet);
54 1 : return ACL_ERROR_INTERNAL_ERROR;
55 : }
56 31 : acl::AclDump::GetInstance().SetAdxInitFromAclInitFlag(true);
57 :
58 : // base dump
59 : acl::AdumpDumpConfigInfo configInfo;
60 31 : configInfo.dumpConfigPath = configPath;
61 31 : configInfo.dumpConfigData = configStr;
62 31 : configInfo.dumpConfigSize = size;
63 31 : if (funcs.setDumpConfig == nullptr) {
64 1 : ACL_LOG_INNER_ERROR("[Check][DumpCallback]Adump set dump config callback is not registered.");
65 1 : return ACL_ERROR_INTERNAL_ERROR;
66 : }
67 30 : adxRet = funcs.setDumpConfig(configInfo);
68 30 : if (adxRet != ADX_ERROR_NONE) {
69 2 : auto ret = (adxRet == Adx::ADUMP_INPUT_FAILED) ? ACL_ERROR_INVALID_DUMP_CONFIG : ACL_ERROR_INTERNAL_ERROR;
70 2 : ACL_LOG_INNER_ERROR("[Set][Dump]set dump config failed, adx errorCode = %d", adxRet);
71 2 : return ret;
72 : }
73 :
74 28 : return ACL_SUCCESS;
75 : }
76 :
77 33 : aclError AclDump::HandleDumpConfig(const char_t* const configPath)
78 : {
79 33 : ACL_LOG_INFO("start to execute HandleDumpConfig.");
80 33 : std::string configStr;
81 33 : const aclError ret = acl::JsonParser::GetConfigStrFromFile(configPath, configStr);
82 33 : if (ret != ACL_SUCCESS) {
83 0 : ACL_LOG_INNER_ERROR("Get config string from file[%s] failed, errorCode = %d", configPath, ret);
84 0 : return ret;
85 : }
86 : try {
87 33 : if (!configStr.empty()) {
88 31 : return HandleDumpCommand(configStr.c_str(), configStr.size(), configPath);
89 : }
90 0 : } catch (const nlohmann::json::exception& e) {
91 0 : ACL_LOG_INNER_ERROR("[Convert][DumpConfig]parse json for config failed, exception:%s.", e.what());
92 0 : return ACL_ERROR_INVALID_DUMP_CONFIG;
93 0 : }
94 2 : ACL_LOG_INFO("HandleDumpConfig end in HandleDumpConfig.");
95 2 : return ACL_SUCCESS;
96 33 : }
97 : } // namespace acl
98 :
99 : #ifdef __cplusplus
100 : extern "C" {
101 : #endif
102 :
103 16 : aclError aclmdlInitDumpImpl()
104 : {
105 16 : ACL_LOG_INFO("start to execute aclmdlInitDump.");
106 16 : if (!acl::GetAclInitFlag()) {
107 1 : acl::AclErrorLogManager::ReportInputError(
108 2 : "EP0008", std::vector<const char*>({"func", "reason"}),
109 2 : std::vector<const char*>({"aclmdlInitDump", "aclInit must be executed before aclmdlInitDump is called"}));
110 1 : ACL_LOG_ERROR("[Check][AclInitFlag]aclInit must be executed before aclmdlInitDump is called");
111 1 : return ACL_ERROR_UNINITIALIZE;
112 : }
113 :
114 15 : const std::unique_lock<std::mutex> lk(aclDumpMutex);
115 15 : if (aclmdlInitDumpFlag) {
116 1 : acl::AclErrorLogManager::ReportInputError(
117 2 : "EP0008", std::vector<const char*>({"func", "reason"}),
118 2 : std::vector<const char*>({"aclmdlInitDump", "This API cannot be called repeatedly"}));
119 1 : ACL_LOG_ERROR("[Check][InitDumpFlag]This API cannot be called repeatedly");
120 1 : return ACL_ERROR_REPEAT_INITIALIZE;
121 : }
122 :
123 14 : const auto& funcs = acl::GetAdumpCallbacks();
124 14 : if (funcs.serverInit == nullptr) {
125 1 : ACL_LOG_INNER_ERROR("[Check][DumpCallback]Adump server init callback is not registered.");
126 1 : return ACL_ERROR_INTERNAL_ERROR;
127 : }
128 13 : const int32_t adxRet = funcs.serverInit();
129 13 : if (adxRet != ADX_ERROR_NONE) {
130 1 : ACL_LOG_CALL_ERROR("[AdxDataDumpServer][Init]dump server run failed, adx errorCode = %d", adxRet);
131 1 : return ACL_ERROR_INTERNAL_ERROR;
132 : }
133 :
134 12 : aclmdlInitDumpFlag = true;
135 12 : ACL_LOG_INFO("successfully initialized dump in aclmdlInitDump.");
136 12 : return ACL_SUCCESS;
137 15 : }
138 :
139 11 : aclError aclmdlSetDumpImpl(const char* dumpCfgPath)
140 : {
141 11 : ACL_LOG_INFO("start to execute aclmdlSetDump.");
142 11 : if (!acl::GetAclInitFlag()) {
143 1 : acl::AclErrorLogManager::ReportInputError(
144 2 : "EP0008", std::vector<const char*>({"func", "reason"}),
145 2 : std::vector<const char*>({"aclmdlSetDump", "aclInit must be executed before aclmdlSetDumpImpl is called"}));
146 1 : ACL_LOG_ERROR("[Check][AclInitFlag]aclInit must be executed before aclmdlSetDumpImpl is called");
147 1 : return ACL_ERROR_UNINITIALIZE;
148 : }
149 :
150 10 : const std::unique_lock<std::mutex> lk(aclDumpMutex);
151 10 : if (!aclmdlInitDumpFlag) {
152 2 : acl::AclErrorLogManager::ReportInputError(
153 4 : "EP0008", std::vector<const char*>({"func", "reason"}),
154 2 : std::vector<const char*>(
155 2 : {"aclmdlSetDump", "aclmdlInitDump must be executed before aclmdlSetDumpImpl is called"}));
156 2 : ACL_LOG_ERROR("[Check][aclmdlInitDumpFlag]aclmdlInitDump must be executed before aclmdlSetDumpImpl is called");
157 2 : return ACL_ERROR_DUMP_NOT_RUN;
158 : }
159 :
160 8 : ACL_REQUIRES_NOT_NULL_WITH_INPUT_REPORT(dumpCfgPath);
161 7 : std::string configStr;
162 7 : aclError ret = acl::JsonParser::GetConfigStrFromFile(dumpCfgPath, configStr);
163 7 : if (ret != ACL_SUCCESS) {
164 1 : ACL_LOG_INNER_ERROR("Get config string from file[%s] failed, errorCode = %d", dumpCfgPath, ret);
165 1 : return ret;
166 : }
167 :
168 : // base dump
169 6 : if (!configStr.empty()) {
170 6 : ACL_LOG_INFO("Start to set dump.");
171 6 : const auto& funcs = acl::GetAdumpCallbacks();
172 6 : if (funcs.setDumpConfig == nullptr) {
173 1 : ACL_LOG_INNER_ERROR("[Check][DumpCallback]Adump set dump config callback is not registered.");
174 3 : return ACL_ERROR_INTERNAL_ERROR;
175 : }
176 : acl::AdumpDumpConfigInfo configInfo;
177 5 : configInfo.dumpConfigPath = dumpCfgPath;
178 5 : configInfo.dumpConfigData = configStr.c_str();
179 5 : configInfo.dumpConfigSize = configStr.size();
180 5 : const auto adxRet = funcs.setDumpConfig(configInfo);
181 5 : if (adxRet != ADX_ERROR_NONE) {
182 2 : ret = (adxRet == Adx::ADUMP_INPUT_FAILED) ? ACL_ERROR_INVALID_DUMP_CONFIG : ACL_ERROR_INTERNAL_ERROR;
183 2 : ACL_LOG_INNER_ERROR("[Set][Dump]set dump config failed, adx errorCode = %d", adxRet);
184 2 : return ret;
185 : }
186 : }
187 3 : ACL_LOG_INFO("set dump config successfully.");
188 3 : return ACL_SUCCESS;
189 10 : }
190 :
191 23 : aclError aclmdlFinalizeDumpImpl()
192 : {
193 23 : ACL_LOG_INFO("start to execute aclmdlFinalizeDump.");
194 23 : if (!acl::GetAclInitFlag()) {
195 1 : acl::AclErrorLogManager::ReportInputError(
196 2 : "EP0008", std::vector<const char*>({"func", "reason"}),
197 1 : std::vector<const char*>(
198 1 : {"aclmdlFinalizeDump", "aclInit must be executed before aclmdlFinalizeDump is called"}));
199 1 : ACL_LOG_ERROR("[Check][AclInitFlag]aclInit must be executed before aclmdlFinalizeDump is called");
200 1 : return ACL_ERROR_UNINITIALIZE;
201 : }
202 :
203 22 : const std::unique_lock<std::mutex> lk(aclDumpMutex);
204 22 : if (!aclmdlInitDumpFlag) {
205 5 : acl::AclErrorLogManager::ReportInputError(
206 10 : "EP0008", std::vector<const char*>({"func", "reason"}),
207 5 : std::vector<const char*>(
208 5 : {"aclmdlFinalizeDump", "aclmdlInitDump must be executed before aclmdlFinalizeDump is called"}));
209 5 : ACL_LOG_ERROR("[Check][aclmdlInitDumpFlag]aclmdlInitDump must be executed before aclmdlFinalizeDump is called");
210 5 : return ACL_ERROR_DUMP_NOT_RUN;
211 : }
212 :
213 : // close adump opened
214 17 : const auto& funcs = acl::GetAdumpCallbacks();
215 17 : if (funcs.unsetDump == nullptr) {
216 1 : ACL_LOG_INNER_ERROR("[Check][DumpCallback]Adump unset dump callback is not registered.");
217 1 : return ACL_ERROR_INTERNAL_ERROR;
218 : }
219 16 : int32_t adxRet = funcs.unsetDump();
220 16 : if (adxRet != ADX_ERROR_NONE) {
221 2 : ACL_LOG_INNER_ERROR("[Set][Dump]set dump off failed, adx errorCode = %d", adxRet);
222 2 : return ACL_ERROR_INTERNAL_ERROR;
223 : }
224 :
225 : // close dump server
226 14 : if (funcs.serverUnInit == nullptr) {
227 1 : ACL_LOG_INNER_ERROR("[Check][DumpCallback]Adump server uninit callback is not registered.");
228 1 : return ACL_ERROR_INTERNAL_ERROR;
229 : }
230 13 : adxRet = funcs.serverUnInit();
231 13 : if (adxRet != ADX_ERROR_NONE) {
232 1 : ACL_LOG_CALL_ERROR("[AdxDataDumpServer][UnInit]generate dump file failed in disk, adx errorCode = %d", adxRet);
233 1 : return ACL_ERROR_INTERNAL_ERROR;
234 : }
235 :
236 12 : aclmdlInitDumpFlag = false;
237 12 : ACL_LOG_INFO("successfully execute aclmdlFinalizeDump, the dump task completed!");
238 12 : return ACL_SUCCESS;
239 22 : }
240 : #ifdef __cplusplus
241 : }
242 : #endif
|