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 <sstream>
12 : #include "securec.h"
13 : #include "dfx_args_parser.h"
14 : #include "dump_memory.h"
15 : #include "adump_platform_manager.h"
16 : #include "log/adx_log.h"
17 :
18 : namespace Adx {
19 : uint64_t GetDFXInfoChunkCursor(uint8_t bufferId);
20 :
21 : namespace {
22 : constexpr uint32_t ATOMIC_INDEX_SIZE = 8;
23 : constexpr uint32_t BUFFER_ID_SHIFT_BITS = 31;
24 : constexpr uint64_t BUFFER_ID_MASK = 0x080000000;
25 : constexpr uint64_t OFFSET_MASK = 0x0FFFFFF;
26 : constexpr uint64_t MAGIC_NUM = 0xA5A5A5A500000000;
27 : constexpr uint64_t MAGIC_NUM_MASK = 0xFFFFFFFF00000000;
28 : constexpr uint64_t SPACE_MASK = 0x00000000FFFFFFFF;
29 : constexpr uint32_t ARGS_PER_STRING_MAX_LEN = 20;
30 :
31 10 : uint64_t ReadAtomicIndex(const uint8_t *data)
32 : {
33 10 : uint64_t atomicIndex = 0;
34 10 : if (memcpy_s(&atomicIndex, sizeof(atomicIndex), data, sizeof(atomicIndex)) != EOK) {
35 0 : IDE_LOGE("Read atomicIndex failed, data=%p.", data);
36 0 : return 0U;
37 : }
38 10 : return atomicIndex;
39 : }
40 : }
41 :
42 29 : DfxArgsParser::~DfxArgsParser()
43 : {
44 29 : if (hostArgsData_ != nullptr) {
45 23 : DumpMemory::FreeHost(hostArgsData_);
46 23 : hostArgsData_ = nullptr;
47 : }
48 29 : }
49 :
50 29 : int32_t DfxArgsParser::Init(void *argAddr, uint64_t argSize, const uint8_t *dfxAddr, uint16_t dfxSize)
51 : {
52 29 : IDE_CTRL_VALUE_FAILED(argAddr != nullptr && argSize != 0, return ADUMP_FAILED,
53 : "Invalid arg. argAddr=%p, argSize=%llu.", argAddr, argSize);
54 29 : IDE_CTRL_VALUE_FAILED(dfxAddr != nullptr && dfxSize != 0, return ADUMP_FAILED,
55 : "Invalid dfx. dfxAddr=%p, dfxSize=%u.", dfxAddr, dfxSize);
56 :
57 29 : argAddr_ = argAddr;
58 29 : argSize_ = argSize;
59 :
60 29 : hostArgsData_ = DumpMemory::CopyDeviceToHostEx(argAddr, argSize);
61 29 : IDE_CTRL_VALUE_FAILED(hostArgsData_ != nullptr, return ADUMP_FAILED,
62 : "Copy device args to host failed. argAddr=%p, argSize=%llu.", argAddr, argSize);
63 :
64 23 : argOnHost_ = static_cast<const void **>(hostArgsData_);
65 23 : maxArgNum_ = argSize / sizeof(uint64_t);
66 :
67 23 : dfxAddr_ = dfxAddr;
68 23 : dfxSize_ = dfxSize;
69 23 : currDfxSize_ = 0;
70 :
71 23 : LogArgsInfo();
72 23 : return ADUMP_SUCCESS;
73 : }
74 :
75 23 : void DfxArgsParser::LogArgsInfo()
76 : {
77 23 : const uint32_t argsLogTimes = (maxArgNum_ % ARGS_PER_STRING_MAX_LEN > 0) ?
78 23 : ((maxArgNum_ / ARGS_PER_STRING_MAX_LEN) + 1) :
79 0 : (maxArgNum_ / ARGS_PER_STRING_MAX_LEN);
80 50 : for (uint32_t i = 1; i <= argsLogTimes; ++i) {
81 27 : std::stringstream ss;
82 27 : uint32_t endIndex = maxArgNum_ > (i * ARGS_PER_STRING_MAX_LEN) ? (i * ARGS_PER_STRING_MAX_LEN) : maxArgNum_;
83 241 : for (uint32_t j = (i - 1) * ARGS_PER_STRING_MAX_LEN; j < endIndex; ++j) {
84 214 : ss << *(argOnHost_ + j) << ", ";
85 : }
86 27 : RecordDumpLog(StrUtils::Format("[AIC_INFO] args(%u to %u) after execute:%s",
87 54 : (i - 1) * ARGS_PER_STRING_MAX_LEN, endIndex, ss.str().c_str()));
88 27 : }
89 23 : IDE_LOGE("[AIC_INFO] after execute:args print end");
90 23 : }
91 :
92 152 : void DfxArgsParser::RecordDumpLog(const std::string &log)
93 : {
94 152 : IDE_LOGE("%s", log.c_str());
95 152 : logRecords_.emplace_back(log + "\n");
96 152 : }
97 :
98 6 : int32_t DfxArgsParser::GetAddressBias(uint64_t &addrBias, const void *argAddr, void *baseAddr, uint64_t argsSize)
99 : {
100 6 : addrBias = reinterpret_cast<uint64_t>(argAddr) - reinterpret_cast<uint64_t>(baseAddr);
101 6 : if (addrBias >= argsSize) {
102 2 : IDE_LOGE("Address bias[%llu] >= argsSize[%llu], invalid.", addrBias, argsSize);
103 2 : return ADUMP_FAILED;
104 : }
105 4 : return ADUMP_SUCCESS;
106 : }
107 :
108 29 : int32_t DfxArgsParser::CheckAddressOverArgs(const uint64_t *address, const void **argOnHost, uint64_t maxArgNum)
109 : {
110 29 : uint64_t *endArgAddr = reinterpret_cast<uint64_t *>(argOnHost + maxArgNum);
111 29 : if (address >= endArgAddr) {
112 0 : IDE_LOGE("Address[%p] >= endArgAddr[%p], over args range.", address, endArgAddr);
113 0 : return ADUMP_FAILED;
114 : }
115 29 : return ADUMP_SUCCESS;
116 : }
117 :
118 41 : int32_t DfxArgsParser::CheckShapeDataAddress() const
119 : {
120 41 : if (shapeDataAddr_ == nullptr || shapeDataMaxAddr_ == nullptr) {
121 0 : IDE_LOGE("The shape data addr[%p] or max addr[%p] is nullptr.", shapeDataAddr_, shapeDataMaxAddr_);
122 0 : return ADUMP_FAILED;
123 : }
124 41 : if (shapeDataAddr_ >= shapeDataMaxAddr_) {
125 1 : IDE_LOGE("The shape data addr[%p] is over max addr[%p].", shapeDataAddr_, shapeDataMaxAddr_);
126 1 : return ADUMP_FAILED;
127 : }
128 40 : return ADUMP_SUCCESS;
129 : }
130 :
131 50 : bool DfxArgsParser::CheckMagicMemory(const uint8_t *address) const
132 : {
133 58 : for (uint16_t i = 0; i < 4; ++i) {
134 56 : if (*(address + i) != 0xA5) {
135 48 : return false;
136 : }
137 : }
138 2 : return true;
139 : }
140 :
141 100 : const char* DfxArgsParser::GetTensorTypeName(DfxTensorType tensorType)
142 : {
143 100 : switch (tensorType) {
144 38 : case DfxTensorType::INPUT_TENSOR: return "INPUT_TENSOR";
145 30 : case DfxTensorType::OUTPUT_TENSOR: return "OUTPUT_TENSOR";
146 4 : case DfxTensorType::WORKSPACE_TENSOR: return "WORKSPACE_TENSOR";
147 4 : case DfxTensorType::TILING_DATA: return "TILING_DATA";
148 2 : case DfxTensorType::MC2_CTX: return "MC2_CTX";
149 0 : case DfxTensorType::SHAPE_TENSOR: return "SHAPE_TENSOR";
150 18 : case DfxTensorType::GENERAL_TENSOR: return "GENERAL_TENSOR";
151 4 : default: return "UNKNOWN";
152 : }
153 : }
154 :
155 100 : const char* DfxArgsParser::GetPointerTypeName(DfxPointerType pointerType)
156 : {
157 100 : switch (pointerType) {
158 80 : case DfxPointerType::LEVEL_1_POINTER: return "L1_POINTER";
159 8 : case DfxPointerType::LEVEL_2_POINTER: return "L2_POINTER";
160 12 : case DfxPointerType::LEVEL_2_POINTER_WITH_SHAPE: return "L2_POINTER_WITH_SHAPE";
161 0 : case DfxPointerType::SHAPE_TENSOR_PLACEHOLD: return "SHAPE_TENSOR_PLACEHOLD";
162 0 : default: return "INVALID_POINTER";
163 : }
164 : }
165 :
166 10 : int32_t DfxArgsParser::GetShapeData(uint64_t atomicIndex)
167 : {
168 10 : uint8_t bufferId = static_cast<uint8_t>((atomicIndex & BUFFER_ID_MASK) >> BUFFER_ID_SHIFT_BITS);
169 10 : uint32_t offset = static_cast<uint32_t>(atomicIndex & OFFSET_MASK);
170 10 : uint32_t chunkSize = 0;
171 10 : uint64_t *chunkAddr = nullptr;
172 10 : if (bufferId == 0U) {
173 9 : chunkSize = DYNAMIC_RING_CHUNK_SIZE;
174 9 : chunkAddr = g_dynamicChunk;
175 : } else {
176 1 : chunkSize = STATIC_RING_CHUNK_SIZE;
177 1 : chunkAddr = g_staticChunk;
178 : }
179 10 : IDE_LOGI("Decode atomicIndex, atomicIndex=0x%llx, bufferId=%u, offset=%u, chunkAddr=%p, chunkSize=%u.",
180 : atomicIndex, bufferId, offset, chunkAddr, chunkSize);
181 :
182 10 : IDE_CTRL_VALUE_FAILED(chunkAddr != nullptr, return ADUMP_FAILED, "GetShapeData failed, the chunk memory is null.");
183 9 : IDE_CTRL_VALUE_FAILED(offset < chunkSize, return ADUMP_FAILED,
184 : "GetShapeData failed, offset is over chunk size, atomicIndex=0x%llx, bufferId=%u, offset=%u, chunkSize=%u.",
185 : atomicIndex, bufferId, offset, chunkSize);
186 :
187 8 : uint64_t magicAndSpace = chunkAddr[offset];
188 8 : uint64_t magicNum = magicAndSpace & MAGIC_NUM_MASK;
189 8 : uint32_t space = static_cast<uint32_t>(magicAndSpace & SPACE_MASK);
190 8 : IDE_LOGI("Parse chunk header, magicAndSpace=0x%llx, magicNum=0x%llx, space=%u.", magicAndSpace, magicNum, space);
191 :
192 8 : IDE_CTRL_VALUE_FAILED(magicNum == MAGIC_NUM, return ADUMP_FAILED,
193 : "GetShapeData failed, magic is invalid, atomicIndex=0x%llx, magicAndSpace=0x%llx, magic=0x%llx, "
194 : "magicMask=0x%llx.", atomicIndex, magicAndSpace, magicNum, MAGIC_NUM_MASK);
195 6 : IDE_CTRL_VALUE_FAILED(space <= DFX_MAX_TENSOR_NUM, return ADUMP_FAILED,
196 : "GetShapeData failed, space is over max, atomicIndex=0x%llx, magicAndSpace=0x%llx, space=%u, maxSpace=%u.",
197 : atomicIndex, magicAndSpace, space, DFX_MAX_TENSOR_NUM);
198 :
199 5 : uint64_t dumpAtomicIndex = chunkAddr[offset + 1];
200 5 : uint64_t chunkCursor = GetDFXInfoChunkCursor(bufferId);
201 5 : uint64_t chunkRound = chunkCursor / chunkSize;
202 5 : uint32_t chunkOffset = static_cast<uint32_t>(chunkCursor % chunkSize);
203 5 : IDE_CTRL_VALUE_FAILED(dumpAtomicIndex == atomicIndex, return ADUMP_FAILED,
204 : "GetShapeData failed, atomic index mismatch, atomicIndex=0x%llx, dumpAtomicIndex=0x%llx, chunkRound=%llu, "
205 : "chunkOffset=%u.", atomicIndex, dumpAtomicIndex, chunkRound, chunkOffset);
206 :
207 4 : shapeDataAddr_ = chunkAddr + offset + RESERVE_SPACE;
208 4 : shapeDataMaxAddr_ = shapeDataAddr_ + space;
209 4 : std::stringstream ss;
210 59 : for (uint32_t i = 0; i < space; i++) {
211 55 : ss << *(shapeDataAddr_ + i) << ", ";
212 : }
213 4 : IDE_LOGI("The shape item size: %s", ss.str().c_str());
214 4 : return ADUMP_SUCCESS;
215 4 : }
216 :
217 6 : bool DfxArgsParser::GetIsDataTypeSizeByte(bool &isDataTypeSizeByte) const
218 : {
219 6 : auto *plat = ExceptionDumpManager::Get();
220 6 : if (plat == nullptr) {
221 : // 未注册平台沿用默认语义:视为非按字节并继续解析,保持与平台工厂化前一致
222 0 : isDataTypeSizeByte = false;
223 0 : return true;
224 : }
225 6 : isDataTypeSizeByte = plat->IsArgsDataTypeSizeByByte();
226 6 : return true;
227 : }
228 :
229 13 : int32_t DfxArgsParser::InitTensorModeInfoInner(uint32_t currArgsIndex, const uint8_t *&dfxAddr, uint64_t &currDfxSize)
230 : {
231 13 : IDE_LOGI("Find tiling data, the mode is dynamic");
232 13 : dynamicModeFlag_ = true;
233 :
234 13 : uint64_t tilingDataSize = 0;
235 13 : int32_t ret = GetPointerValueByBigEndian(&dfxAddr, tilingDataSize, currDfxSize, dfxSize_);
236 13 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
237 :
238 13 : if (tilingDataSize < ATOMIC_INDEX_SIZE) {
239 2 : IDE_LOGE("The tiling data size[%llu] is less than the min size[%u].", tilingDataSize, ATOMIC_INDEX_SIZE);
240 2 : return ADUMP_FAILED;
241 : }
242 :
243 11 : void *tilingDataAddr = DumpMemory::CopyDeviceToHostEx(argOnHost_[currArgsIndex], tilingDataSize);
244 11 : if (tilingDataAddr == nullptr) {
245 1 : IDE_LOGE("Copy device tiling to host failed.");
246 1 : return ADUMP_FAILED;
247 : }
248 20 : HOST_RT_MEMORY_GUARD(tilingDataAddr);
249 :
250 10 : auto addr = static_cast<uint8_t *>(tilingDataAddr);
251 10 : if (isTik_) {
252 50 : for (size_t i = 4; i <= tilingDataSize - 4; ++i) {
253 50 : if (!CheckMagicMemory(addr + i)) {
254 48 : continue;
255 : }
256 2 : uint64_t atomicIndex = ReadAtomicIndex(addr + i - 4);
257 2 : if (GetShapeData(atomicIndex) == ADUMP_SUCCESS) {
258 2 : return ADUMP_SUCCESS;
259 : }
260 : }
261 0 : IDE_LOGE("Can not find shape info. tiling data addr=%p, size=%llu", argOnHost_[currArgsIndex], tilingDataSize);
262 0 : return ADUMP_FAILED;
263 : } else {
264 8 : uint64_t atomicIndex = ReadAtomicIndex(addr + tilingDataSize - ATOMIC_INDEX_SIZE);
265 8 : ret = GetShapeData(atomicIndex);
266 8 : IDE_CTRL_VALUE_FAILED(ret == ADUMP_SUCCESS, return ADUMP_FAILED,
267 : "Can not find shape info. tiling data addr=%p, size=%llu", argOnHost_[currArgsIndex], tilingDataSize);
268 : }
269 :
270 2 : return ADUMP_SUCCESS;
271 10 : }
272 :
273 23 : int32_t DfxArgsParser::InitTensorModeInfo()
274 : {
275 23 : uint64_t currDfxSize = 0;
276 23 : const uint8_t *dfxAddr = dfxAddr_;
277 23 : uint32_t currArgsIndex = 0;
278 103 : while (currDfxSize < dfxSize_) {
279 98 : std::stringstream exceptionDfxStr;
280 8658 : for (size_t i = 0; i < (dfxSize_ - currDfxSize); ++i) {
281 8560 : exceptionDfxStr << int32_t(*(dfxAddr + i)) << ", ";
282 : }
283 98 : IDE_LOGI("current arg index[%u], Tiling current exception dfx raw data:%s ", currArgsIndex,
284 : exceptionDfxStr.str().c_str());
285 :
286 98 : if (currArgsIndex >= maxArgNum_) {
287 1 : IDE_LOGE("The current arg index[%u] is greater than the max arg number[%llu]",
288 : currArgsIndex, maxArgNum_);
289 1 : return ADUMP_FAILED;
290 : }
291 :
292 97 : uint16_t argsInfoType = 0;
293 97 : int32_t ret = GetPointerValueByBigEndian(&dfxAddr, argsInfoType, currDfxSize, dfxSize_);
294 97 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
295 97 : uint16_t argsInfoNum = 0;
296 97 : ret = GetPointerValueByBigEndian(&dfxAddr, argsInfoNum, currDfxSize, dfxSize_);
297 97 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
298 97 : if (argsInfoNum == 0) {
299 4 : IDE_LOGE("The dfx args info num[%u] is invalid.", argsInfoNum);
300 4 : return ADUMP_FAILED;
301 : }
302 :
303 93 : if (argsInfoType == TYPE_L0_EXCEPTION_DFX_ARGS_INFO) {
304 90 : uint64_t typeInfo = 0;
305 90 : ret = GetPointerValueByBigEndian(&dfxAddr, typeInfo, currDfxSize, dfxSize_);
306 103 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
307 90 : DfxTensorType tensorType = static_cast<DfxTensorType>(typeInfo & TENSOR_TYPE_MASK);
308 90 : if (tensorType == DfxTensorType::TILING_DATA) {
309 13 : ret = InitTensorModeInfoInner(currArgsIndex, dfxAddr, currDfxSize);
310 13 : return ret;
311 : }
312 77 : currDfxSize += sizeof(uint64_t) * (argsInfoNum - 1);
313 77 : dfxAddr += sizeof(uint64_t) * (argsInfoNum - 1);
314 77 : ++currArgsIndex;
315 : } else {
316 3 : currDfxSize += sizeof(uint64_t) * argsInfoNum;
317 3 : dfxAddr += sizeof(uint64_t) * argsInfoNum;
318 : }
319 80 : IDE_LOGI("Current dfx total size is %llu", currDfxSize);
320 98 : }
321 :
322 5 : if (currDfxSize > dfxSize_) {
323 1 : IDE_LOGE("The dfx info size[%llu] is over the max size[%u].", currDfxSize, dfxSize_);
324 1 : return ADUMP_FAILED;
325 : }
326 :
327 4 : return ADUMP_SUCCESS;
328 : }
329 :
330 22 : int32_t DfxArgsParser::LoadDfxL1PtrTensor(TensorBuffer &tensor)
331 : {
332 22 : int32_t ret = ADUMP_SUCCESS;
333 22 : if (dynamicModeFlag_) {
334 10 : dfxAddr_ += sizeof(uint64_t);
335 10 : currDfxSize_ += sizeof(uint64_t);
336 10 : ret = CheckShapeDataAddress();
337 10 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
338 10 : tensor.size = *shapeDataAddr_;
339 10 : shapeDataAddr_++;
340 10 : tensors_.push_back(tensor);
341 10 : IDE_LOGE("[Dump][Exception] tensor type:%u(%s), pointer type:%u(%s)",
342 : static_cast<uint16_t>(tensor.tensorType), GetTensorTypeName(tensor.tensorType),
343 : static_cast<uint16_t>(tensor.pointerType), GetPointerTypeName(tensor.pointerType));
344 10 : RecordDumpLog(StrUtils::Format("[Dump][Exception] exception info dump args data, addr:%p; size:%llu bytes",
345 : tensor.addr, tensor.size));
346 : } else {
347 12 : uint64_t size = 0;
348 12 : ret = GetPointerValueByBigEndian(&dfxAddr_, size, currDfxSize_, dfxSize_);
349 12 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
350 12 : IDE_LOGI("Tensor size[%llu].", size);
351 12 : tensor.size = size;
352 :
353 12 : uint64_t dimension = 0;
354 12 : ret = GetPointerValueByBigEndian(&dfxAddr_, dimension, currDfxSize_, dfxSize_);
355 12 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
356 12 : IDE_LOGI("Tensor dimension[%llu].", dimension);
357 12 : tensor.dimension = dimension;
358 :
359 36 : for (uint64_t i = 0; i < dimension; ++i) {
360 24 : uint64_t shape = 0;
361 24 : ret = GetPointerValueByBigEndian(&dfxAddr_, shape, currDfxSize_, dfxSize_);
362 24 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
363 24 : IDE_LOGI("Tensor shape[%llu].", shape);
364 24 : tensor.shape.push_back(shape);
365 : }
366 :
367 12 : tensors_.push_back(tensor);
368 12 : IDE_LOGE("[Dump][Exception] tensor type:%u(%s), pointer type:%u(%s)",
369 : static_cast<uint16_t>(tensor.tensorType), GetTensorTypeName(tensor.tensorType),
370 : static_cast<uint16_t>(tensor.pointerType), GetPointerTypeName(tensor.pointerType));
371 12 : RecordDumpLog(StrUtils::Format("[Dump][Exception] exception info dump args data, addr:%p; size:%llu bytes",
372 : tensor.addr, tensor.size));
373 : }
374 :
375 22 : return ADUMP_SUCCESS;
376 : }
377 :
378 6 : int32_t DfxArgsParser::LoadDfxL2ShapePtrTensor(TensorBuffer &tensor)
379 : {
380 6 : uint64_t addrBias = 0;
381 6 : int32_t ret = GetAddressBias(addrBias, tensor.addr, argAddr_, argSize_);
382 6 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
383 :
384 4 : uint64_t *dynamicTensorAddr = reinterpret_cast<uint64_t *>(addrBias + reinterpret_cast<uint64_t>(argOnHost_));
385 4 : ret = CheckAddressOverArgs(dynamicTensorAddr, argOnHost_, maxArgNum_);
386 4 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
387 :
388 4 : uint64_t offset = *dynamicTensorAddr;
389 4 : dynamicTensorAddr++;
390 :
391 4 : void **tensorAddr = reinterpret_cast<void **>(reinterpret_cast<uint64_t>(argOnHost_) + addrBias + offset);
392 4 : uint64_t shapeInfoCount = (offset - sizeof(uint64_t)) / sizeof(uint64_t);
393 4 : ret = LoadTensorShapeAndSize(tensor, dynamicTensorAddr, tensorAddr, shapeInfoCount);
394 4 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
395 4 : shapeDataAddr_++;
396 :
397 4 : return ADUMP_SUCCESS;
398 : }
399 :
400 4 : int32_t DfxArgsParser::LoadTensorShapeAndSize(TensorBuffer &tensor, uint64_t *dynamicTensorAddr,
401 : void **tensorAddr, uint64_t shapeInfoCount)
402 : {
403 4 : int32_t ret = ADUMP_SUCCESS;
404 4 : uint64_t currShapeCount = 0;
405 14 : while (currShapeCount < shapeInfoCount) {
406 11 : ret = CheckAddressOverArgs(dynamicTensorAddr, argOnHost_, maxArgNum_);
407 11 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
408 11 : uint64_t dimAndCnt = *dynamicTensorAddr;
409 11 : if (dimAndCnt == 0) {
410 1 : IDE_LOGI("The tensor dimension and count are 0, which is an empty address.");
411 1 : break;
412 : }
413 10 : uint32_t tensorDim = static_cast<uint32_t>(dimAndCnt & TENSOR_DIMENSION_MASK);
414 10 : uint32_t tensorCount = static_cast<uint32_t>((dimAndCnt & TENSOR_COUNT_MASK) >> TENSOR_COUNT_SHIFT_BITS);
415 10 : tensor.dimension = tensorDim;
416 10 : IDE_LOGI("The tensor dimension[%u], count[%u].", tensorDim, tensorCount);
417 10 : dynamicTensorAddr++;
418 10 : currShapeCount++;
419 10 : uint64_t size = 1;
420 10 : std::vector<uint64_t> tmpShapeVec;
421 24 : for (uint32_t i = 0; i < tensorDim; ++i) {
422 14 : ret = CheckAddressOverArgs(dynamicTensorAddr, argOnHost_, maxArgNum_);
423 14 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
424 14 : size *= *dynamicTensorAddr;
425 14 : IDE_LOGI("The tensor shape[%llu].", *dynamicTensorAddr);
426 14 : tmpShapeVec.push_back(*dynamicTensorAddr);
427 14 : dynamicTensorAddr++;
428 14 : currShapeCount++;
429 : }
430 10 : tensor.shape = tmpShapeVec;
431 10 : tensor.size = size;
432 :
433 10 : const void **endArgAddr = argOnHost_ + maxArgNum_;
434 21 : for (uint32_t i = 0; i < tensorCount; ++i) {
435 11 : if (tensorAddr >= endArgAddr) {
436 0 : IDE_LOGE("Args address[%p] is over args end address[%p].", tensorAddr, endArgAddr);
437 0 : return ADUMP_FAILED;
438 : }
439 11 : tensor.addr = *tensorAddr;
440 11 : tensors_.push_back(tensor);
441 11 : RecordDumpLog(StrUtils::Format("[Dump][Exception] exception info dump args data, addr:%p; size:%llu bytes",
442 : *tensorAddr, tensor.GetTotalByteSize()));
443 11 : tensorAddr++;
444 : }
445 10 : }
446 :
447 4 : return ADUMP_SUCCESS;
448 : }
449 :
450 32 : int32_t DfxArgsParser::LoadDfxTensor(TensorBuffer &tensor, uint16_t argsInfoNum)
451 : {
452 32 : int32_t ret = ADUMP_SUCCESS;
453 64 : RecordDumpLog(StrUtils::Format(
454 : "[Dump][Exception] begin to load normal tensor, index:%u, tensor type:%u(%s), pointer type:%u(%s)",
455 32 : tensor.argIndex, static_cast<uint16_t>(tensor.tensorType), GetTensorTypeName(tensor.tensorType),
456 32 : static_cast<uint16_t>(tensor.pointerType), GetPointerTypeName(tensor.pointerType)));
457 32 : if (tensor.pointerType == DfxPointerType::LEVEL_2_POINTER_WITH_SHAPE) {
458 6 : dfxAddr_ += sizeof(uint64_t);
459 6 : currDfxSize_ += sizeof(uint64_t);
460 6 : uint64_t dataTypeSize = 0;
461 6 : ret = GetPointerValueByBigEndian(&dfxAddr_, dataTypeSize, currDfxSize_, dfxSize_);
462 8 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
463 6 : IDE_LOGI("The tensor datatype size[%llu].", dataTypeSize);
464 6 : IDE_CTRL_VALUE_FAILED(GetIsDataTypeSizeByte(tensor.isDataTypeSizeByte), return ADUMP_FAILED,
465 : "Load data type size unit failed.");
466 6 : tensor.dataTypeSize = dataTypeSize;
467 6 : ret = LoadDfxL2ShapePtrTensor(tensor);
468 6 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
469 26 : } else if (tensor.pointerType == DfxPointerType::LEVEL_1_POINTER ||
470 4 : tensor.pointerType == DfxPointerType::SHAPE_TENSOR_PLACEHOLD) {
471 22 : ret = LoadDfxL1PtrTensor(tensor);
472 22 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
473 : } else {
474 4 : dfxAddr_ += sizeof(uint64_t) * (argsInfoNum - 1);
475 4 : currDfxSize_ += sizeof(uint64_t) * (argsInfoNum - 1);
476 4 : tensor.size = 0;
477 : }
478 30 : RecordDumpLog(StrUtils::Format("[Dump][Exception] end to load normal tensor, index:%u", tensor.argIndex));
479 30 : return ADUMP_SUCCESS;
480 : }
481 :
482 4 : int32_t DfxArgsParser::LoadDfxWorkspace(TensorBuffer &tensor)
483 : {
484 4 : RecordDumpLog(StrUtils::Format("[Dump][Exception] begin to load workspace, index:%u", tensor.argIndex));
485 :
486 : DumpWorkspace workspace;
487 4 : workspace.addr = tensor.addr;
488 4 : workspace.argsOffset = tensor.argIndex;
489 :
490 4 : if (dynamicModeFlag_) {
491 3 : int32_t ret = CheckShapeDataAddress();
492 3 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
493 3 : workspace.bytes = *shapeDataAddr_;
494 3 : shapeDataAddr_++;
495 : } else {
496 1 : uint64_t size = 0;
497 1 : int32_t ret = GetPointerValueByBigEndian(&dfxAddr_, size, currDfxSize_, dfxSize_);
498 1 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
499 1 : IDE_LOGI("Workspace size[%llu].", size);
500 1 : workspace.bytes = size;
501 : }
502 :
503 4 : workspaces_.push_back(workspace);
504 4 : RecordDumpLog(StrUtils::Format("[Dump][Exception] exception info dump workspace data, addr:%p; size:%llu bytes",
505 : workspace.addr, workspace.bytes));
506 4 : RecordDumpLog(StrUtils::Format("[Dump][Exception] end to load workspace, index:%u", tensor.argIndex));
507 :
508 4 : return ADUMP_SUCCESS;
509 : }
510 :
511 4 : int32_t DfxArgsParser::LoadDfxTilingData(TensorBuffer &tensor)
512 : {
513 4 : RecordDumpLog(StrUtils::Format("[Dump][Exception] begin to load tiling data, index:%u", tensor.argIndex));
514 4 : uint64_t tilingDataSize = 0;
515 4 : int32_t ret = GetPointerValueByBigEndian(&dfxAddr_, tilingDataSize, currDfxSize_, dfxSize_);
516 4 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
517 4 : IDE_LOGI("The tiling data size=%llu.", tilingDataSize);
518 4 : tensor.size = tilingDataSize;
519 :
520 : // TBE算子无法区分tensor和workspace,当前GE框架无法识别TBE算子,
521 : // 对workspace不会添加dim和shape信息,解析到shape地址越界报错时,忽略错误
522 4 : (void)LoadDfxShapeData();
523 4 : tensors_.push_back(tensor);
524 4 : RecordDumpLog(StrUtils::Format("[Dump][Exception] exception info dump tiling data, addr:%p; size:%llu bytes",
525 : tensor.addr, tilingDataSize));
526 4 : RecordDumpLog(StrUtils::Format("[Dump][Exception] end to load tiling data, index:%u", tensor.argIndex));
527 4 : return ADUMP_SUCCESS;
528 : }
529 :
530 4 : int32_t DfxArgsParser::LoadDfxShapeData()
531 : {
532 4 : int32_t ret = ADUMP_SUCCESS;
533 4 : size_t tensorBufferSize = tensors_.size();
534 4 : IDE_LOGI("The tensor buffer size=%llu.", tensorBufferSize);
535 17 : for (size_t i = 0; i < tensorBufferSize; ++i) {
536 14 : DfxPointerType localPointerType = tensors_[i].pointerType;
537 23 : if ((localPointerType == DfxPointerType::LEVEL_1_POINTER) && tensors_[i].size != 0 &&
538 9 : tensors_[i].tensorType != DfxTensorType::SHAPE_TENSOR) {
539 9 : ret = CheckShapeDataAddress();
540 9 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
541 9 : uint64_t tensorDim = *shapeDataAddr_;
542 9 : IDE_LOGI("The tensor dimension[%llu].", tensorDim);
543 9 : tensors_[i].dimension = tensorDim;
544 9 : shapeDataAddr_++;
545 27 : for (uint64_t dim = 0; dim < tensorDim; ++dim) {
546 19 : ret = CheckShapeDataAddress();
547 19 : IDE_CHECK_RET(ret, {
548 : tensors_[i].dimension = 0;
549 : return ADUMP_FAILED;
550 : });
551 18 : IDE_LOGI("The tensor shape[%llu].", *shapeDataAddr_);
552 18 : tensors_[i].shape.push_back(*shapeDataAddr_);
553 18 : shapeDataAddr_++;
554 : }
555 : }
556 : }
557 :
558 3 : return ret;
559 : }
560 :
561 2 : void DfxArgsParser::LoadDfxMc2(const TensorBuffer &tensor)
562 : {
563 2 : RecordDumpLog(StrUtils::Format("[Dump][Exception] begin to load mc2, index:%u", tensor.argIndex));
564 : DumpWorkspace workspace;
565 2 : workspace.addr = tensor.addr;
566 2 : workspace.argsOffset = tensor.argIndex;
567 2 : workspace.bytes = 0;
568 2 : mc2Space_.push_back(workspace);
569 2 : shapeDataAddr_++;
570 2 : RecordDumpLog(StrUtils::Format("[Dump][Exception] exception info dump mc2 data, addr:%p; size:%llu bytes",
571 : workspace.addr, workspace.bytes));
572 2 : RecordDumpLog(StrUtils::Format("[Dump][Exception] end to load mc2, index:%u", tensor.argIndex));
573 2 : }
574 :
575 47 : int32_t DfxArgsParser::LoadDfxInfo(uint32_t &currArgsIndex)
576 : {
577 47 : uint16_t argsInfoType = 0;
578 47 : int32_t ret = GetPointerValueByBigEndian(&dfxAddr_, argsInfoType, currDfxSize_, dfxSize_);
579 47 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
580 47 : uint16_t argsInfoNum = 0;
581 47 : ret = GetPointerValueByBigEndian(&dfxAddr_, argsInfoNum, currDfxSize_, dfxSize_);
582 47 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
583 47 : IDE_LOGI("The arg info type: %u, info num:%u", argsInfoType, argsInfoNum);
584 47 : IDE_CTRL_VALUE_FAILED(argsInfoNum != 0, return ADUMP_FAILED,
585 : "The dfx args info num[%u] is invalid.", argsInfoNum);
586 :
587 47 : if (argsInfoType == TYPE_L0_EXCEPTION_DFX_ARGS_INFO) {
588 46 : uint64_t typeInfo = 0;
589 46 : ret = GetPointerValueByBigEndian(&dfxAddr_, typeInfo, currDfxSize_, dfxSize_);
590 48 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
591 46 : DfxTensorType tensorType = static_cast<DfxTensorType>(typeInfo & TENSOR_TYPE_MASK);
592 46 : DfxPointerType pointerType =
593 46 : static_cast<DfxPointerType>((typeInfo & POINTER_TYPE_MASK) >> POINTER_TYPE_SHIFT_BITS);
594 46 : IDE_LOGI("The arg type info: %llu, tensor type: %u(%s), pointer type: %u(%s)", typeInfo,
595 : static_cast<uint16_t>(tensorType), GetTensorTypeName(tensorType),
596 : static_cast<uint16_t>(pointerType), GetPointerTypeName(pointerType));
597 :
598 46 : TensorBuffer tensor(argOnHost_[currArgsIndex], currArgsIndex, tensorType, pointerType);
599 46 : if ((tensorType <= DfxTensorType::OUTPUT_TENSOR && tensorType > DfxTensorType::INVALID_TENSOR) ||
600 : tensorType == DfxTensorType::SHAPE_TENSOR) {
601 32 : ret = LoadDfxTensor(tensor, argsInfoNum);
602 32 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
603 14 : } else if (tensorType == DfxTensorType::WORKSPACE_TENSOR) {
604 4 : ret = LoadDfxWorkspace(tensor);
605 4 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
606 10 : } else if (tensorType == DfxTensorType::TILING_DATA) {
607 4 : ret = LoadDfxTilingData(tensor);
608 4 : IDE_CHECK_RET(ret, return ADUMP_FAILED);
609 6 : } else if (tensorType == DfxTensorType::MC2_CTX) {
610 2 : LoadDfxMc2(tensor);
611 : } else {
612 4 : IDE_LOGE("[Dump][Exception] args dump dfx info, addr:%p, tensor type:%u, pointer type:%u, index: %u",
613 : argOnHost_[currArgsIndex], static_cast<uint16_t>(tensorType), static_cast<uint16_t>(pointerType),
614 : currArgsIndex);
615 4 : dfxAddr_ += sizeof(uint64_t) * (argsInfoNum - 1);
616 4 : currDfxSize_ += sizeof(uint64_t) * (argsInfoNum - 1);
617 : }
618 44 : ++currArgsIndex;
619 46 : } else {
620 1 : IDE_LOGW("The dfx args info type[%u] is not allowed", argsInfoType);
621 1 : dfxAddr_ += sizeof(uint64_t) * argsInfoNum;
622 1 : currDfxSize_ += sizeof(uint64_t) * argsInfoNum;
623 : }
624 :
625 45 : return ADUMP_SUCCESS;
626 : }
627 :
628 8 : int32_t DfxArgsParser::ParseAll()
629 : {
630 8 : uint32_t currArgsIndex = 0;
631 53 : while (currDfxSize_ < dfxSize_) {
632 47 : std::stringstream exceptionDfxStr;
633 5463 : for (size_t i = 0; i < (dfxSize_ - currDfxSize_); ++i) {
634 5416 : exceptionDfxStr << int32_t(*(dfxAddr_ + i)) << ", ";
635 : }
636 47 : IDE_LOGI("Current exception dfx raw data:%s ", exceptionDfxStr.str().c_str());
637 :
638 47 : if (currArgsIndex >= maxArgNum_) {
639 0 : IDE_LOGE("The current arg index[%u] is greater than the max arg number[%llu]",
640 : currArgsIndex, maxArgNum_);
641 0 : return ADUMP_FAILED;
642 : }
643 :
644 47 : int32_t ret = LoadDfxInfo(currArgsIndex);
645 47 : if (ret != ADUMP_SUCCESS) {
646 2 : return ret;
647 : }
648 47 : }
649 :
650 6 : return ADUMP_SUCCESS;
651 : }
652 :
653 : } // namespace Adx
|