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 <cstring>
12 : #include "exception_info_common.h"
13 : #include "kernel_symbol_locator.h"
14 : #include "runtime/rts/rts_kernel.h"
15 : #include "adump_pub.h"
16 : #include "str_utils.h"
17 : #include "log/adx_log.h"
18 : #include "log/hdc_log.h"
19 :
20 : namespace Adx {
21 : namespace {
22 : constexpr char MIX_AIC_SUFFIX[] = "_mix_aic";
23 : constexpr char MIX_AIV_SUFFIX[] = "_mix_aiv";
24 :
25 43 : const char* GetKernelMixSuffix(KernelMixType kernelMixType)
26 : {
27 43 : switch (kernelMixType) {
28 29 : case KernelMixType::AIC:
29 29 : return MIX_AIC_SUFFIX;
30 0 : case KernelMixType::AIV:
31 0 : return MIX_AIV_SUFFIX;
32 14 : default:
33 14 : return nullptr;
34 : }
35 : }
36 : } // namespace
37 :
38 201 : int32_t ExceptionInfoCommon::GetExceptionInfo(const rtExceptionInfo &exception,
39 : rtExceptionArgsInfo_t &exceptionArgsInfo)
40 : {
41 201 : rtExceptionExpandType_t exceptionTaskType = exception.expandInfo.type;
42 201 : if (exceptionTaskType == RT_EXCEPTION_AICORE) {
43 185 : exceptionArgsInfo = exception.expandInfo.u.aicoreInfo.exceptionArgs;
44 16 : } else if (exceptionTaskType == RT_EXCEPTION_FFTS_PLUS) {
45 9 : exceptionArgsInfo = exception.expandInfo.u.fftsPlusInfo.exceptionArgs;
46 7 : } else if (exceptionTaskType == RT_EXCEPTION_FUSION) {
47 6 : exceptionArgsInfo = exception.expandInfo.u.fusionInfo.u.aicoreCcuInfo.exceptionArgs;
48 : } else {
49 1 : IDE_LOGW("Not support exception dump, type=%d(%s)", static_cast<int32_t>(exceptionTaskType),
50 : GetExceptionTaskTypeName(exception).c_str());
51 1 : return ADUMP_FAILED;
52 : }
53 :
54 200 : return ADUMP_SUCCESS;
55 : }
56 :
57 82 : std::string ExceptionInfoCommon::GetExceptionTaskTypeName(const rtExceptionInfo &exception)
58 : {
59 82 : switch (exception.expandInfo.type) {
60 8 : case RT_EXCEPTION_INVALID:
61 16 : return "invalid";
62 3 : case RT_EXCEPTION_FFTS_PLUS:
63 6 : return "fftsplus";
64 52 : case RT_EXCEPTION_AICORE:
65 104 : return "aicore";
66 3 : case RT_EXCEPTION_UB:
67 6 : return "ub";
68 1 : case RT_EXCEPTION_CCU:
69 2 : return "ccu";
70 3 : case RT_EXCEPTION_FUSION:
71 6 : return "fusion";
72 11 : case RT_EXCEPTION_AICPU:
73 22 : return "aicpu";
74 1 : default:
75 2 : return "unknown";
76 : }
77 : }
78 :
79 82 : bool ExceptionInfoCommon::IsSupportExceptionDump(const rtExceptionInfo &exception)
80 : {
81 82 : if (exception.retcode == ACL_ERROR_RT_AICORE_OVER_FLOW ||
82 81 : exception.retcode == ACL_ERROR_RT_AIVEC_OVER_FLOW ||
83 : // Hardware faults do not need dump.
84 80 : exception.retcode == ACL_ERROR_RT_DEVICE_MEM_ERROR ||
85 79 : exception.retcode == ACL_ERROR_RT_SUSPECT_REMOTE_ERROR ||
86 78 : exception.retcode == ACL_ERROR_RT_LINK_ERROR) {
87 5 : IDE_LOGW("Not support exception dump, rts retcode=%u.", exception.retcode);
88 5 : return false;
89 : }
90 :
91 77 : rtExceptionExpandType_t exceptionType = exception.expandInfo.type;
92 77 : if (exceptionType == RT_EXCEPTION_FFTS_PLUS ||
93 16 : exceptionType == RT_EXCEPTION_AICORE ||
94 14 : exceptionType == RT_EXCEPTION_FUSION ||
95 : // Supported for callback exception dump.
96 : exceptionType == RT_EXCEPTION_AICPU) {
97 68 : return true;
98 : }
99 :
100 9 : IDE_LOGW("Not support exception dump, type=%d(%s)", static_cast<int32_t>(exceptionType),
101 : GetExceptionTaskTypeName(exception).c_str());
102 9 : return false;
103 : }
104 :
105 61 : bool ExceptionInfoCommon::IsSupportDefaultExceptionDump(const rtExceptionInfo &exception)
106 : {
107 61 : rtExceptionExpandType_t exceptionType = exception.expandInfo.type;
108 61 : if (exceptionType == RT_EXCEPTION_FFTS_PLUS ||
109 10 : exceptionType == RT_EXCEPTION_AICORE ||
110 : exceptionType == RT_EXCEPTION_FUSION) {
111 54 : return true;
112 : }
113 7 : IDE_LOGW("Not support default exception dump, type=%d(%s)", static_cast<int32_t>(exceptionType),
114 : GetExceptionTaskTypeName(exception).c_str());
115 7 : return false;
116 : }
117 :
118 43 : std::string ExceptionInfoCommon::GetKernelNameWithoutMixSuffix(const std::string &kernelName)
119 : {
120 43 : const char *suffix = GetKernelMixSuffix(GetKernelMixType(kernelName));
121 43 : if (suffix == nullptr) {
122 14 : return kernelName;
123 : }
124 :
125 29 : std::string processedKernelName = kernelName;
126 29 : const size_t suffixLen = std::strlen(suffix);
127 29 : processedKernelName.resize(processedKernelName.size() - suffixLen);
128 29 : return processedKernelName;
129 29 : }
130 :
131 67 : std::string ExceptionInfoCommon::GetExceptionKernelName(const rtExceptionInfo &exception)
132 : {
133 67 : std::string rawKernelName;
134 67 : if (exception.expandInfo.type == RT_EXCEPTION_AICPU) {
135 7 : const rtAicpuExDetailInfo_t &aicpuInfo = exception.expandInfo.u.aicpuInfo;
136 7 : if (aicpuInfo.kernelName == nullptr) {
137 12 : return "";
138 : }
139 1 : rawKernelName.assign(aicpuInfo.kernelName);
140 : } else {
141 60 : rtExceptionArgsInfo_t exceptionArgsInfo{};
142 60 : if (GetExceptionInfo(exception, exceptionArgsInfo) != ADUMP_SUCCESS) {
143 2 : return "";
144 : }
145 :
146 59 : const rtExceptionKernelInfo_t &kernelInfo = exceptionArgsInfo.exceptionKernelInfo;
147 59 : if (kernelInfo.kernelName == nullptr || kernelInfo.kernelNameSize == 0) {
148 96 : return "";
149 : }
150 11 : rawKernelName.assign(kernelInfo.kernelName, kernelInfo.kernelNameSize);
151 : }
152 :
153 12 : return GetKernelNameWithoutMixSuffix(rawKernelName);
154 67 : }
155 :
156 7 : int32_t ExceptionInfoCommon::GetKernelDeviceAddr(rtBinHandle binHandle, void * &devAddr)
157 : {
158 7 : devAddr = nullptr;
159 7 : uint32_t binSize = 0;
160 7 : IDE_CTRL_VALUE_WARN(binHandle != nullptr, return ADUMP_FAILED, "bindHandle is nullptr.");
161 7 : rtError_t ret = rtsBinaryGetDevAddress(binHandle, &devAddr, &binSize);
162 7 : IDE_CTRL_VALUE_FAILED(ret == RT_ERROR_NONE && devAddr != nullptr, return ADUMP_FAILED,
163 : "rtsBinaryGetDevAddress failed, ret=%d, binHandle=%p, devAddr=%p.",
164 : static_cast<int32_t>(ret), binHandle, devAddr);
165 :
166 2 : IDE_LOGI("The device address of binHandle(%p) is %p, binSize=%u.", binHandle, devAddr, binSize);
167 2 : return ADUMP_SUCCESS;
168 : }
169 :
170 43 : KernelMixType ExceptionInfoCommon::GetKernelMixType(const std::string &kernelName)
171 : {
172 43 : if (kernelName.size() > std::strlen(MIX_AIC_SUFFIX) && StrUtils::EndsWith(kernelName, MIX_AIC_SUFFIX)) {
173 29 : return KernelMixType::AIC;
174 : }
175 14 : if (kernelName.size() > std::strlen(MIX_AIV_SUFFIX) && StrUtils::EndsWith(kernelName, MIX_AIV_SUFFIX)) {
176 0 : return KernelMixType::AIV;
177 : }
178 14 : return KernelMixType::NONE;
179 : }
180 :
181 65 : int32_t ExceptionInfoCommon::GetExceptionRegInfo(const rtExceptionInfo &exception, ExceptionRegInfo &exceptionRegInfo)
182 : {
183 65 : rtError_t rtRet = rtGetExceptionRegInfo(&exception, &exceptionRegInfo.errRegInfo, &exceptionRegInfo.coreNum);
184 65 : IDE_CTRL_VALUE_FAILED(rtRet == RT_ERROR_NONE, return ADUMP_FAILED,
185 : "rtGetExceptionRegInfo failed. ret: %d", static_cast<int32_t>(rtRet));
186 :
187 65 : IDE_LOGI("Get exception register information. coreNum=%u", exceptionRegInfo.coreNum);
188 65 : return ADUMP_SUCCESS;
189 : }
190 :
191 79 : int32_t ExceptionInfoCommon::GetBinDataFromHandle(rtBinHandle binHandle, std::string &binData, uint32_t &binSize)
192 : {
193 79 : IDE_CTRL_VALUE_FAILED(binHandle != nullptr, return ADUMP_FAILED, "binHandle is null");
194 :
195 41 : void *bufAddr = nullptr;
196 41 : uint32_t bufSize = 0;
197 41 : rtError_t ret = rtGetBinBuffer(binHandle, RT_BIN_HOST_ADDR, &bufAddr, &bufSize);
198 41 : IDE_CTRL_VALUE_FAILED(ret == RT_ERROR_NONE && bufAddr != nullptr && bufSize != 0, return ADUMP_FAILED,
199 : "rtGetBinBuffer failed, ret=%d, binHandle=%p, bufAddr=%p, bufSize=%u.",
200 : static_cast<int32_t>(ret), binHandle, bufAddr, bufSize);
201 :
202 39 : IDE_LOGI("Get kernel bin data success. binHandle=%p, bufAddr=%p, bufSize=%u", binHandle, bufAddr, bufSize);
203 39 : binData.assign(reinterpret_cast<char*>(bufAddr), bufSize);
204 39 : binSize = bufSize;
205 39 : return ADUMP_SUCCESS;
206 : }
207 :
208 : } // namespace Adx
|