LCOV - code coverage report
Current view: top level - adump/manage/dump_manager - dump_manager.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.9 % 536 455
Test Date: 2026-08-12 11:04:53 Functions: 94.2 % 52 49

            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              : #include "dump_manager.h"
      11              : #include <thread>
      12              : #include <cctype>
      13              : #include <cinttypes>
      14              : #include <map>
      15              : #include <algorithm>
      16              : #include <cerrno>
      17              : #include <sstream>
      18              : #include "str_utils.h"
      19              : #include "lib_path.h"
      20              : #include "file_utils.h"
      21              : #include "adump_platform_manager.h"
      22              : #include "log/adx_log.h"
      23              : #include "runtime/context.h"
      24              : #include "runtime/config.h"
      25              : #include "rts/rts_snapshot.h"
      26              : #include "error_codes/rt_error_codes.h"
      27              : #include "adump_dsmi.h"
      28              : #include "common_utils.h"
      29              : #include "exception_info_common.h"
      30              : #include "dump_config_converter.h"
      31              : #include "adump_api.h"
      32              : #include "adump_error_manager.h"
      33              : #include "operator_dumper.h"
      34              : #include "kernel_dfx_dumper.h"
      35              : #include "adx_dump_record.h"
      36              : #include "common/file.h"
      37              : #include "common/path.h"
      38              : #include "sys_utils.h"
      39              : #include "dump_file.h"
      40              : #include "adx_datadump_server.h"
      41              : 
      42              : namespace Adx {
      43              : constexpr char EXCEPTION_CB_MODULE[] = "AdumpException";
      44              : constexpr char COREDUMP_CB_MODULE[] = "AdumpCoredump";
      45              : 
      46              : std::vector<std::shared_ptr<OperatorPreliminary>> DumpManager::operatorMap_;
      47              : 
      48            0 : static void ExceptionCallback(rtExceptionInfo* const exception)
      49              : {
      50            0 :     IDE_RUN_LOGI("An exception callback message is received.");
      51            0 :     if (exception != nullptr) {
      52            0 :         (void)DumpManager::Instance().DumpExceptionInfo(*exception);
      53            0 :         AdxLogFlush();
      54              :     }
      55            0 : }
      56              : 
      57            6 : static void NotifyCoredumpCallback(uint32_t devId, bool isOpen)
      58              : {
      59            6 :     static std::map<uint32_t, uint32_t> setDeviceRecord;
      60              :     static std::mutex coredumpMtx;
      61            6 :     std::lock_guard<std::mutex> lk(coredumpMtx);
      62            6 :     auto it = setDeviceRecord.find(devId);
      63            6 :     if (!isOpen) {
      64            2 :         if (it != setDeviceRecord.end()) {
      65            2 :             it->second--;
      66            2 :             if (it->second == 0) {
      67            1 :                 setDeviceRecord.erase(it);
      68            1 :                 IDE_LOGI("Device %u has been removed from the effective list.", devId);
      69              :             }
      70              :         }
      71            2 :         return;
      72              :     }
      73            4 :     if (it != setDeviceRecord.end()) {
      74            2 :         it->second++;
      75            2 :         return;
      76              :     }
      77            2 :     rtError_t ret = rtDebugSetDumpMode(RT_DEBUG_DUMP_ON_EXCEPTION);
      78            2 :     if (ret != RT_ERROR_NONE) {
      79            0 :         IDE_RUN_LOGI("detail exception dump mode not support, switch to lite exception dump, ret:%d", ret);
      80            0 :         DumpManager::Instance().ExceptionModeDowngrade();
      81              :     }
      82            2 :     IDE_LOGI("Device %u has been added to the effective list.", devId);
      83            2 :     setDeviceRecord[devId] = 1;
      84            6 : }
      85              : 
      86            0 : static uint32_t DumpSnapShotLockPreCallback(int32_t deviceId, void* args)
      87              : {
      88              :     UNUSED(deviceId);
      89              :     UNUSED(args);
      90            0 :     return DumpManager::Instance().StopDataDumpServer() ? 0U : 1U;
      91              : }
      92              : 
      93         2062 : DumpManager& DumpManager::Instance()
      94              : {
      95         2062 :     static DumpManager instance;
      96         2062 :     return instance;
      97              : }
      98              : 
      99            3 : DumpManager::DumpManager()
     100              : {
     101              :     try {
     102              :         // 1. 通过环境变量使能Exception Dump
     103            3 :         EnableExceptionDumpWithEnv();
     104              :         // 2. 通过环境变量使能Kernel Dfx Dump
     105            3 :         KernelDfxDumper::Instance();
     106            0 :     } catch (...) {
     107            0 :         IDE_LOGW("Enable dump function with env variable failed!");
     108            0 :     }
     109            3 : }
     110              : 
     111          258 : bool DumpManager::StartDataDumpServer()
     112              : {
     113              :     // 注册快照回调:快照备份前关闭Data Dump Server
     114          258 :     RegisterSnapShotCallback();
     115              : #if !defined(ADUMP_SOC_HOST) || ADUMP_SOC_HOST == 1
     116              :     // 如果没有启动Data Dump Server,启动Data Dump Server
     117          258 :     int32_t dumpNum = AdxDumpRecord::Instance().GetDumpInitNum();
     118          258 :     if (dumpNum == 0) {
     119           39 :         return AdxDataDumpServerInit() == ADUMP_SUCCESS;
     120              :     }
     121              : #endif
     122          219 :     return true;
     123              : }
     124              : 
     125           39 : bool DumpManager::StopDataDumpServer()
     126              : {
     127              : #if !defined(ADUMP_SOC_HOST) || ADUMP_SOC_HOST == 1
     128           39 :     int32_t dumpNum = AdxDumpRecord::Instance().GetDumpInitNum();
     129           78 :     while (dumpNum > 0) {
     130           39 :         IDE_CTRL_VALUE_FAILED(
     131              :             AdxDataDumpServerUnInit() == ADUMP_SUCCESS, return false, "Stop data dump server failed!");
     132           39 :         dumpNum = AdxDumpRecord::Instance().GetDumpInitNum();
     133              :     }
     134              : #endif
     135           39 :     return true;
     136              : }
     137              : 
     138          267 : void DumpManager::RegisterSnapShotCallback()
     139              : {
     140          267 :     if (!snapCbkRegistered_) {
     141           15 :         rtError_t ret = rtSnapShotCallbackRegister(RT_SNAPSHOT_LOCK_PRE, DumpSnapShotLockPreCallback, nullptr);
     142           15 :         if (ret == ACL_ERROR_RT_FEATURE_NOT_SUPPORT) {
     143            3 :             IDE_LOGI("RTS does not support snapshot feature. ret=%d", ret);
     144            3 :             return;
     145              :         }
     146           12 :         IDE_CTRL_VALUE_WARN(
     147              :             ret == ACL_SUCCESS, return, "Register DumpSnapShotLockPreCallback to RTS failed. ret=%d", ret);
     148            9 :         snapCbkRegistered_ = true;
     149            9 :         IDE_LOGI("Register DumpSnapShotLockPreCallback success.");
     150              :     }
     151              : }
     152              : 
     153            3 : void DumpManager::EnableExceptionDumpWithEnv()
     154              : {
     155            3 :     DumpConfig config;
     156              :     DumpType dumpType;
     157            3 :     if (DumpConfigConverter::EnableExceptionDumpWithEnv(config, dumpType)) {
     158            0 :         if (SetDumpConfig(dumpType, config) != ADUMP_SUCCESS) {
     159            0 :             IDE_LOGW("Enable exception dump failed. dumpType: %d", dumpType);
     160              :         } else {
     161            0 :             isEnvExceptionDump_ = true;
     162              :         }
     163              :     }
     164            3 : }
     165              : 
     166          258 : bool DumpManager::AdjustOpExecuteTimeOut()
     167              : {
     168          258 :     if (opTimeoutModified_) {
     169          195 :         IDE_LOGI("Op execute timeout has been adjusted for data dump, skip.");
     170          195 :         return true;
     171              :     }
     172           63 :     uint32_t curTimeout = 0U;
     173           63 :     rtError_t ret = rtGetOpExecuteTimeoutV2(&curTimeout);
     174           63 :     IDE_CTRL_VALUE_FAILED(ret == RT_ERROR_NONE, return false,
     175              :         "Get op execute timeout failed, skip adjust for data dump. ret=%d", ret);
     176           60 :     if (curTimeout >= OP_EXECUTE_TIMEOUT_FOR_DATADUMP_MS) {
     177            6 :         IDE_LOGI("Current op execute timeout %ums is no less than %ums, no need to adjust for data dump.",
     178              :             curTimeout, OP_EXECUTE_TIMEOUT_FOR_DATADUMP_MS);
     179            6 :         return true;
     180              :     }
     181           54 :     ret = rtSetOpExecuteTimeOutWithMs(OP_EXECUTE_TIMEOUT_FOR_DATADUMP_MS);
     182           54 :     IDE_CTRL_VALUE_FAILED(ret == RT_ERROR_NONE, return false,
     183              :         "Set op execute timeout to %ums failed for data dump. ret=%d", OP_EXECUTE_TIMEOUT_FOR_DATADUMP_MS, ret);
     184           51 :     originOpExecuteTimeOut_ = curTimeout;
     185           51 :     opTimeoutModified_ = true;
     186           51 :     IDE_LOGI("Adjust op execute timeout from %ums to %ums for data dump.",
     187              :         curTimeout, OP_EXECUTE_TIMEOUT_FOR_DATADUMP_MS);
     188           51 :     return true;
     189              : }
     190              : 
     191           36 : bool DumpManager::RestoreOpExecuteTimeOut()
     192              : {
     193           36 :     if (!opTimeoutModified_) {
     194            9 :         return true;
     195              :     }
     196           27 :     rtError_t ret = rtSetOpExecuteTimeOutWithMs(originOpExecuteTimeOut_);
     197              :     // 恢复失败时保持 opTimeoutModified_=true,以便下次关闭 data dump 时重试恢复
     198           27 :     IDE_CTRL_VALUE_FAILED(ret == RT_ERROR_NONE, return false,
     199              :         "Restore op execute timeout to %ums failed. ret=%d", originOpExecuteTimeOut_, ret);
     200           24 :     IDE_LOGI("Restore op execute timeout to %ums after data dump disabled.", originOpExecuteTimeOut_);
     201           24 :     opTimeoutModified_ = false;
     202           24 :     originOpExecuteTimeOut_ = 0U;
     203           24 :     return true;
     204              : }
     205              : 
     206            0 : void DumpManager::KFCResourceInit()
     207              : {
     208              : #if !defined(ADUMP_SOC_HOST) || ADUMP_SOC_HOST == 1
     209            0 :     if (isKFCInit_) {
     210            0 :         IDE_LOGD("KFC resources have been initialized on all devices.");
     211            0 :         return;
     212              :     }
     213            0 :     std::vector<uint32_t> devList = AdumpDsmi::DrvGetDeviceList();
     214              : 
     215            0 :     for (uint32_t& deviceId : devList) {
     216            0 :         IDE_LOGI("Start to initialize KFC resources on device %u.", deviceId);
     217            0 :         SharedPtr<OperatorPreliminary> opIniter = MakeSharedInstance<OperatorPreliminary>(GetDumpSetting(), deviceId);
     218            0 :         IDE_CTRL_VALUE_FAILED_NODO(
     219              :             opIniter != nullptr && opIniter->OperatorInit() == ADUMP_SUCCESS, return,
     220              :             "Failed to execute the resource initialization task on device %u.", deviceId);
     221            0 :         DumpManager::operatorMap_.emplace_back(std::move(opIniter));
     222            0 :         IDE_LOGI("KFC executed on the device %u successfully.", deviceId);
     223            0 :     }
     224              : #endif
     225            0 :     isKFCInit_ = true;
     226            0 : }
     227              : 
     228           54 : int32_t DumpManager::ExceptionConfig(DumpType dumpType, const DumpConfig& dumpConfig)
     229              : {
     230           54 :     if (exceptionDumper_.IsRepeatEnableException(dumpType, dumpConfig)) {
     231            3 :         IDE_LOGW(
     232              :             "Exception dump has been enabled, not support enable exception dump[%s] again",
     233              :             DumpConfigConverter::DumpTypeToStr(dumpType).c_str());
     234            3 :         return ADUMP_SUCCESS;
     235              :     }
     236              : 
     237           51 :     if (dumpType == DumpType::AIC_ERR_DETAIL_DUMP && !CheckCoredumpSupportedPlatform()) {
     238            3 :         IDE_LOGE("Current platform is not support coredump mode.");
     239            3 :         return ADUMP_FAILED;
     240              :     }
     241              : 
     242           48 :     IDE_RUN_LOGI(
     243              :         "Set %s[%d] dump setting, status: %s, dump switch: %llu", DumpConfigConverter::DumpTypeToStr(dumpType).c_str(),
     244              :         dumpType, dumpConfig.dumpStatus.c_str(), dumpConfig.dumpSwitch);
     245           48 :     if (exceptionDumper_.ExceptionDumperInit(dumpType, dumpConfig) != ADUMP_SUCCESS) {
     246            1 :         IDE_LOGW("Failed to initialize the exception dump.");
     247            1 :         return ADUMP_SUCCESS;
     248              :     }
     249           47 :     dumpSetting_.InitDumpSwitch(dumpConfig.dumpSwitch & DUMP_SWITCH_MASK);
     250           47 :     IDE_CTRL_VALUE_WARN(
     251              :         RegsiterExceptionCallback(), return ADUMP_SUCCESS,
     252              :         "Failed to register the args exception dump callback function.");
     253           46 :     if (exceptionDumper_.GetCoredumpStatus()) { // 如果启动了coredump模式
     254            1 :         IDE_CTRL_VALUE_FAILED(
     255              :             rtRegDeviceStateCallbackEx(COREDUMP_CB_MODULE, &NotifyCoredumpCallback, DEV_CB_POS_BACK) == RT_ERROR_NONE,
     256              :             return ADUMP_FAILED, "Failed to register the coredump callback function to rtSetDevice.");
     257              :     }
     258           46 :     return ADUMP_SUCCESS;
     259              : }
     260              : 
     261          399 : int32_t DumpManager::SetDumpConfig(DumpType dumpType, const DumpConfig& dumpConfig)
     262              : {
     263          399 :     std::lock_guard<std::mutex> lk(resourceMtx_);
     264          399 :     if (dumpType == DumpType::EXCEPTION || dumpType == DumpType::ARGS_EXCEPTION ||
     265              :         dumpType == DumpType::AIC_ERR_DETAIL_DUMP) {
     266           54 :         return ExceptionConfig(dumpType, dumpConfig);
     267              :     }
     268          345 :     auto ret = dumpSetting_.Init(dumpType, dumpConfig);
     269          345 :     if (ret != ADUMP_SUCCESS) {
     270           21 :         return ret;
     271              :     }
     272              : 
     273              :     // 启动Data Dump Server
     274          324 :     if (dumpConfig.dumpStatus != ADUMP_DUMP_STATUS_SWITCH_OFF) {
     275          258 :         IDE_CTRL_VALUE_FAILED(StartDataDumpServer(), return ADUMP_FAILED,
     276              :             "Start data dump server failed! dumpType=%s[%d]",
     277              :             DumpConfigConverter::DumpTypeToStr(dumpType).c_str(), dumpType);
     278              :         // 后续失败不恢复超时时间,不影响功能。
     279          258 :         IDE_CTRL_VALUE_FAILED(AdjustOpExecuteTimeOut(), return ADUMP_FAILED, "Adjust op execute timeout failed.");
     280              :     }
     281              : 
     282          318 :     if (CheckBinValidation() && (isKFCInit_ == false)) {
     283            0 :         auto kfcBind = std::bind(&DumpManager::KFCResourceInit, this);
     284            0 :         std::thread kfcThread(kfcBind);
     285            0 :         kfcThread.join();
     286            0 :         if (!isKFCInit_) {
     287            0 :             IDE_LOGE("SetDumpConfig failed due to kfc resource initialization error.");
     288            0 :             DumpManager::operatorMap_.clear();
     289            0 :             return ADUMP_FAILED;
     290              :         }
     291            0 :     }
     292              : 
     293          318 :     ret = OperatorDumper(dumpSetting_).UpdateDevMemCache();
     294          318 :     IDE_CTRL_VALUE_FAILED(ret == ADUMP_SUCCESS, return ADUMP_FAILED,
     295              :         "Update device memery cache for data dump failed! dumpType=%s[%d]",
     296              :         DumpConfigConverter::DumpTypeToStr(dumpType).c_str(), dumpType);
     297              : 
     298          318 :     IDE_RUN_LOGI(
     299              :         "Set %s[%d] dump setting, status: %s, mode: %s, data: %s, dump switch: %llu, path:%s, dump stats:%s.",
     300              :         DumpConfigConverter::DumpTypeToStr(dumpType).c_str(), dumpType, dumpConfig.dumpStatus.c_str(),
     301              :         dumpConfig.dumpMode.c_str(), dumpConfig.dumpData.c_str(), dumpConfig.dumpSwitch, dumpConfig.dumpPath.c_str(),
     302              :         StrUtils::ToString(dumpConfig.dumpStatsItem).c_str());
     303          318 :     return ADUMP_SUCCESS;
     304          399 : }
     305              : 
     306          111 : int32_t DumpManager::SetDumpConfig(const char *dumpConfigData, size_t dumpConfigSize, const char *dumpConfigPath)
     307              : {
     308          111 :     std::lock_guard<std::mutex> lk(resourceMtx2_);
     309          111 :     if ((dumpConfigData == nullptr) || (dumpConfigSize == 0U) || (dumpConfigPath == nullptr)) {
     310           24 :         IDE_LOGE("Set dump config failed. Config data is null or empty.");
     311           24 :         return ADUMP_FAILED;
     312              :     }
     313           87 :     DumpConfig dumpConfig;
     314           87 :     DumpDfxConfig dumpDfxConfig;
     315              :     DumpType dumpType;
     316           87 :     bool needDump = true;
     317           87 :     DumpConfigConverter converter{dumpConfigData, dumpConfigSize, dumpConfigPath};
     318           87 :     int32_t ret = converter.Convert(dumpType, dumpConfig, needDump, dumpDfxConfig);
     319           87 :     if (ret != ADUMP_SUCCESS) {
     320           12 :         IDE_LOGE("Parse dump config from memory[%s] failed.", dumpConfigData);
     321           12 :         return ADUMP_INPUT_FAILED;
     322              :     }
     323              : 
     324              :     // 开启KernelDataDump
     325           75 :     ret = KernelDfxDumper::Instance().EnableDfxDumper(dumpDfxConfig);
     326           75 :     IDE_CTRL_VALUE_FAILED(ret == ADUMP_SUCCESS, return ret, "Enable kernel dfx dump failed.");
     327              : 
     328           75 :     if (!needDump) {
     329            9 :         return ADUMP_SUCCESS;
     330              :     }
     331              : 
     332              :     // 已开启exception dump:不支持重复使能,不更新配置缓存,不重复回调注册模块组件
     333           66 :     if (exceptionDumper_.IsRepeatEnableException(dumpType, dumpConfig)) {
     334            0 :         IDE_LOGW(
     335              :             "Exception dump has been enabled, not support enable exception dump[%s] again",
     336              :             DumpConfigConverter::DumpTypeToStr(dumpType).c_str());
     337            0 :         return ADUMP_SUCCESS;
     338              :     }
     339              : 
     340           66 :     (void)dumpConfigInfo_.assign(dumpConfigData, dumpConfigSize);
     341           66 :     IDE_LOGI("Dump config info set: addr=%p, size=%zu", dumpConfigInfo_.data(), dumpConfigInfo_.size());
     342           66 :     ret = SetDumpConfig(dumpType, dumpConfig);
     343              :     // 同步触发callback事件
     344           93 :     for (auto& item : enableCallbackFunc_) {
     345           27 :         IDE_LOGI("SetDumpConfig HandleDumpEvent start for module [%zu]", item.first);
     346           27 :         HandleDumpEvent(item.first, DumpEnableAction::ENABLE);
     347              :     }
     348           66 :     IDE_CTRL_VALUE_FAILED(ret == ADUMP_SUCCESS, return ret, "Set dump config failed.");
     349           60 :     (void)openedDump_.insert(dumpType);
     350           60 :     return ADUMP_SUCCESS;
     351          111 : }
     352              : 
     353           42 : int32_t DumpManager::UnSetDumpConfig()
     354              : {
     355           42 :     std::lock_guard<std::mutex> lk(resourceMtx2_);
     356           42 :     DumpConfig config;
     357           42 :     config.dumpStatus = ADUMP_DUMP_STATUS_SWITCH_OFF;
     358           42 :     config.dumpSwitch = 0;
     359           66 :     for (const auto dumpType : openedDump_) {
     360           30 :         if (IsEnableDump(dumpType)) {
     361           30 :             const auto ret = SetDumpConfig(dumpType, config);
     362           30 :             IDE_CTRL_VALUE_FAILED(
     363              :                 ret == ADUMP_SUCCESS, return ADUMP_FAILED, "[Set][Dump]Set dump off failed! dumpType=%s[%d], ret=%d",
     364              :                 DumpConfigConverter::DumpTypeToStr(dumpType).c_str(), dumpType, ret);
     365           24 :             IDE_LOGI(
     366              :                 "[Set][Dump]Set dump off successfully, dumpType=%s[%d]",
     367              :                 DumpConfigConverter::DumpTypeToStr(dumpType).c_str(), dumpType);
     368              :         }
     369              :     }
     370           36 :     openedDump_.clear();
     371              :     // 同步触发callback事件
     372           81 :     for (auto& item : disableCallbackFunc_) {
     373           45 :         IDE_LOGI("UnSetDumpConfig start for module [%zu]", item.first);
     374           45 :         HandleDumpEvent(item.first, DumpEnableAction::DISABLE);
     375              :     }
     376           36 :     dumpConfigInfo_.clear();
     377           36 :     IDE_LOGI("Dump config info cleared.");
     378              : 
     379              :     // 等待所有 dump 操作完成并清理资源
     380           36 :     DumpResourceSafeMap::Instance().waitAndClear();
     381              :     // 释放device资源
     382           36 :     OperatorDumper::FreeDevMemCache();
     383              :     // 停止data dump server
     384           36 :     IDE_CTRL_VALUE_FAILED(StopDataDumpServer(), return ADUMP_FAILED, "Stop data dump server failed!");
     385              :     // 恢复算子超时时间
     386           36 :     IDE_CTRL_VALUE_FAILED(RestoreOpExecuteTimeOut(), return ADUMP_FAILED, "Restore op execute timeout failed!");
     387              : 
     388           33 :     return ADUMP_SUCCESS;
     389           42 : }
     390              : 
     391          321 : std::string DumpManager::GetBinName() const
     392              : {
     393          321 :     auto plat = PlatformReflection<DataDumpInterface>::CreatePlatform(dumpSetting_.GetPlatformType());
     394          321 :     if (plat == nullptr) {
     395          642 :         return "";
     396              :     }
     397            0 :     return plat->GetKfcBinName();
     398          321 : }
     399              : 
     400          321 : bool DumpManager::CheckBinValidation()
     401              : {
     402          321 :     const std::string opName = GetBinName();
     403          321 :     if ((dumpSetting_.GetDumpData().compare(DUMP_STATS_DATA) != 0) || opName.empty()) {
     404          321 :         return false;
     405              :     }
     406            0 :     const std::string opPath = LibPath::Instance().GetTargetPath(opName);
     407            0 :     IDE_CTRL_VALUE_FAILED(!opPath.empty(), return false, "Received an empty path for file %s.", opName.c_str());
     408            0 :     bool isExist = FileUtils::IsFileExist(opPath);
     409            0 :     IDE_LOGI("CheckBinValidation result is %s", isExist ? "true" : "false");
     410            0 :     return isExist;
     411          321 : }
     412              : 
     413          161 : bool DumpManager::IsEnableDump(DumpType dumpType)
     414              : {
     415          161 :     std::lock_guard<std::mutex> lk(resourceMtx_);
     416          161 :     if (dumpType == DumpType::ARGS_EXCEPTION) {
     417           38 :         return exceptionDumper_.GetArgsExceptionStatus() || exceptionDumper_.GetCoredumpStatus();
     418          123 :     } else if (dumpType == DumpType::OPERATOR) {
     419           93 :         return dumpSetting_.GetDumpStatus();
     420           30 :     } else if (dumpType == DumpType::OP_OVERFLOW) {
     421           21 :         return dumpSetting_.GetDumpDebugStatus();
     422            9 :     } else if (dumpType == DumpType::EXCEPTION) {
     423            3 :         return exceptionDumper_.GetExceptionStatus();
     424            6 :     } else if (dumpType == DumpType::AIC_ERR_DETAIL_DUMP) {
     425            3 :         return exceptionDumper_.GetCoredumpStatus();
     426              :     } else {
     427            3 :         IDE_LOGW("Dump type is not support.");
     428              :     }
     429              : 
     430            3 :     return false;
     431          161 : }
     432              : 
     433           39 : int32_t DumpManager::GetInputOutputTensors(
     434              :     const std::string& opType, const std::string& opName, const std::vector<TensorInfoV2>& tensors,
     435              :     std::vector<DumpTensor>& inputTensors, std::vector<DumpTensor>& outputTensors)
     436              : {
     437           75 :     for (const auto& tensorInfo : tensors) {
     438           36 :         if (tensorInfo.tensorAddr == nullptr || tensorInfo.tensorSize == 0) {
     439            6 :             IDE_LOGW("Tensor of op=%s[%s] is empty, addr=%p, size=%zu, skip it.",
     440              :                 opName.c_str(), opType.c_str(), tensorInfo.tensorAddr, tensorInfo.tensorSize);
     441            6 :             continue;
     442              :         }
     443              : 
     444           30 :         if (tensorInfo.placement != TensorPlacement::kOnDeviceHbm) {
     445            6 :             IDE_LOGW("Tensor of op=%s[%s] is not on device, skip it.", opName.c_str(), opType.c_str());
     446            6 :             continue;
     447              :         }
     448              : 
     449           24 :         if (tensorInfo.type == TensorType::INPUT) {
     450           21 :             inputTensors.emplace_back(tensorInfo);
     451            3 :         } else if (tensorInfo.type == TensorType::OUTPUT) {
     452            3 :             outputTensors.emplace_back(tensorInfo);
     453              :         }
     454              :     }
     455           39 :     return ADUMP_SUCCESS;
     456              : }
     457              : 
     458           24 : bool DumpManager::IsEnableDumpOperatorWithCapture(const std::string& opType, const std::string& opName,
     459              :     aclrtStream stream)
     460              : {
     461           24 :     rtStreamCaptureStatus status = RT_STREAM_CAPTURE_STATUS_MAX;
     462           24 :     rtModel_t* captureMdl = nullptr;
     463           24 :     int32_t ret = rtStreamGetCaptureInfo(stream, &status, captureMdl);
     464           24 :     if (ret != ACL_SUCCESS) {
     465            6 :         IDE_LOGW("Get stream capture info error: %d, will switch to common dump", ret);
     466            6 :         return false;
     467              :     }
     468           18 :     IDE_LOGI("%s[%s] : stream capture status: %d", opName.c_str(), opType.c_str(), status);
     469           18 :     return status == RT_STREAM_CAPTURE_STATUS_ACTIVE;
     470              : }
     471              : 
     472           27 : int32_t DumpManager::DumpOperatorWithCfg(const std::string &opType, const std::string &opName,
     473              :     const std::vector<TensorInfo> &tensors, aclrtStream stream, const DumpCfg &dumpCfg)
     474              : {
     475           27 :     std::lock_guard<std::mutex> lk(resourceMtx_);
     476           27 :     if (!dumpSetting_.GetDumpStatusEx() && !dumpSetting_.GetDumpDebugStatus()) {
     477            3 :         IDE_LOGW("Operator or overflow dump is not enable, can't dump data.");
     478            3 :         return ADUMP_SUCCESS;
     479              :     }
     480              : 
     481           24 :     bool isInvalid = dumpCfg.numAttrs != 0UL && dumpCfg.attrs == nullptr;
     482           24 :     IDE_CTRL_VALUE_FAILED(!isInvalid, return ADUMP_FAILED,
     483              :         "The dump cfg attrs is null pointer! op=%s[%s].", opName.c_str(), opType.c_str());
     484              : 
     485           21 :     std::vector<DumpTensor> inputTensors;
     486           21 :     std::vector<DumpTensor> outputTensors;
     487           21 :     int32_t ret = GetInputOutputTensors(opType, opName, ConvertTensorInfoToDumpTensorV2(tensors),
     488              :         inputTensors, outputTensors);
     489           21 :     IDE_CTRL_VALUE_FAILED(ret == ADUMP_SUCCESS, return ADUMP_FAILED,
     490              :         "Get input and output tensors failed! op=%s[%s].", opName.c_str(), opType.c_str());
     491           21 :     IDE_CTRL_VALUE_WARN(!inputTensors.empty() || !outputTensors.empty(), return ADUMP_SUCCESS,
     492              :         "No tensor need to dump. op=%s[%s].", opName.c_str(), opType.c_str());
     493              : 
     494            6 :     if (IsEnableDumpOperatorWithCapture(opType, opName, stream)) {
     495            3 :         if (dumpSetting_.GetDumpDebugStatus() || dumpSetting_.IsDumpDataStats()) {
     496            0 :             IDE_LOGI("overflow or stats is not allow in capture stream");
     497            0 :             return ADUMP_SUCCESS;
     498              :         }
     499            3 :         return DumpOperatorWithCapture(opType, opName, inputTensors, outputTensors, stream);
     500              :     }
     501              :     
     502            3 :     OperatorDumper opDumper(opType, opName);
     503            3 :     ret = opDumper.SetDumpSetting(dumpSetting_)
     504            3 :               .RuntimeStream(stream)
     505            3 :               .InputDumpTensor(inputTensors)
     506            3 :               .OutputDumpTensor(outputTensors)
     507            3 :               .LaunchWithCfg(dumpCfg);
     508            3 :     IDE_CTRL_VALUE_FAILED(ret == ADUMP_SUCCESS, return ret,
     509              :         "Launch dump operator with dump cfg failed! op=%s[%s].", opName.c_str(), opType.c_str());
     510            0 :     return ADUMP_SUCCESS;
     511           27 : }
     512              : 
     513            6 : int32_t DumpManager::DumpOperator(
     514              :     const std::string& opType, const std::string& opName, const std::vector<TensorInfo>& tensors, aclrtStream stream)
     515              : {
     516            6 :     return DumpOperatorV2(opType, opName, ConvertTensorInfoToDumpTensorV2(tensors), stream);
     517              : }
     518              : 
     519           24 : int32_t DumpManager::DumpOperatorV2(
     520              :     const std::string& opType, const std::string& opName, const std::vector<TensorInfoV2>& tensors, aclrtStream stream)
     521              : {
     522           24 :     std::lock_guard<std::mutex> lk(resourceMtx_);
     523           24 :     if (!dumpSetting_.GetDumpStatus() && !dumpSetting_.GetDumpDebugStatus()) {
     524            6 :         IDE_LOGW("Operator or overflow dump is not enable, can't dump.");
     525            6 :         return ADUMP_SUCCESS;
     526              :     }
     527              : 
     528           18 :     std::vector<DumpTensor> inputTensors;
     529           18 :     std::vector<DumpTensor> outputTensors;
     530           18 :     int32_t ret = GetInputOutputTensors(opType, opName, tensors, inputTensors, outputTensors);
     531           18 :     IDE_CTRL_VALUE_FAILED(ret == ADUMP_SUCCESS, return ADUMP_FAILED,
     532              :         "Get input and output tensors failed! opName: %s, opType: %s", opName.c_str(), opType.c_str());
     533              : 
     534           18 :     if (IsEnableDumpOperatorWithCapture(opType, opName, stream)) {
     535           12 :         if (dumpSetting_.GetDumpDebugStatus() || dumpSetting_.IsDumpDataStats()) {
     536            9 :             IDE_LOGI("overflow or stats is not allow in capture stream");
     537            9 :             return ADUMP_SUCCESS;
     538              :         }
     539            3 :         return DumpOperatorWithCapture(opType, opName, inputTensors, outputTensors, stream);
     540              :     }
     541              : 
     542            6 :     OperatorDumper opDumper(opType, opName);
     543            6 :     ret = opDumper.SetDumpSetting(dumpSetting_)
     544            6 :               .RuntimeStream(stream)
     545            6 :               .InputDumpTensor(inputTensors)
     546            6 :               .OutputDumpTensor(outputTensors)
     547            6 :               .Launch();
     548            6 :     IDE_CTRL_VALUE_FAILED(ret == ADUMP_SUCCESS, return ret,
     549              :         "Launch dump operator failed! op=%s[%s].", opName.c_str(), opType.c_str());
     550            3 :     return ADUMP_SUCCESS;
     551           24 : }
     552              : 
     553            9 : int32_t DumpManager::DumpOperatorWithCapture(
     554              :     const std::string& opType, const std::string& opName, const std::vector<DumpTensor>& inputTensors,
     555              :     const std::vector<DumpTensor>& outputTensors, aclrtStream mainStream)
     556              : {
     557            9 :     if (mainStream == nullptr) {
     558            9 :         IDE_LOGE("mainStream is nullptr.");
     559            9 :         return ADUMP_FAILED;
     560              :     }
     561              : 
     562            0 :     if (!isCaptureDumpServerInit_) {
     563            0 :         IDE_CTRL_VALUE_FAILED(StartDataDumpServer(), return ADUMP_FAILED, "Start data dump server failed!");
     564            0 :         isCaptureDumpServerInit_ = true;
     565              :     }
     566              : 
     567            0 :     uint32_t streamId = 0;
     568            0 :     uint32_t taskId = 0;
     569            0 :     uint32_t deviceId = 0;
     570            0 :     std::string dumpPath;
     571            0 :     int32_t ret = CollectStreamContextInfo(mainStream, opName, opType, streamId, taskId, deviceId, dumpPath);
     572            0 :     if (ret != ADUMP_SUCCESS) {
     573            0 :         IDE_LOGE("%s(%s) collect stream context info failed.", opName.c_str(), opType.c_str());
     574            0 :         return ret;
     575              :     }
     576              : 
     577            0 :     std::string mainStreamKey = std::to_string(streamId) + "_" + std::to_string(taskId);
     578            0 :     DumpInfoParams params = {
     579            0 :         mainStreamKey, inputTensors, outputTensors, opType, opName, streamId, taskId, deviceId, 0, 0, dumpPath};
     580            0 :     ret = GetDumpInfoFromMap(params);
     581            0 :     std::shared_ptr<DumpStreamInfo> dumpInfoPtr = DumpResourceSafeMap::Instance().get(mainStreamKey);
     582            0 :     if (ret != ADUMP_SUCCESS || dumpInfoPtr == nullptr) {
     583            0 :         IDE_LOGE("%s(%s) get dump info failed.", opName.c_str(), opType.c_str());
     584            0 :         return ADUMP_FAILED;
     585              :     }
     586            0 :     IDE_LOGI("%s(%s) dump data : create DumpStreamInfo success", opName.c_str(), opType.c_str());
     587              : 
     588            0 :     ret = SetupAsyncDump(dumpInfoPtr, opName, opType, mainStream);
     589            0 :     if (ret != ADUMP_SUCCESS) {
     590            0 :         return ret;
     591              :     }
     592            0 :     IDE_LOGI("%s(%s) set main stream %u, dump stream %u, callback function success", 
     593              :         opName.c_str(), opType.c_str(), dumpInfoPtr->streamId, dumpInfoPtr->dumpStmId);
     594              : 
     595            0 :     return ADUMP_SUCCESS;
     596            0 : }
     597              : 
     598            4 : void DumpManager::AddExceptionOp(const OperatorInfo& opInfo)
     599              : {
     600            4 :     exceptionDumper_.AddDumpOperator(opInfo);
     601            4 : }
     602              : 
     603            4 : void DumpManager::AddExceptionOpV2(const OperatorInfoV2& opInfo)
     604              : {
     605            4 :     exceptionDumper_.AddDumpOperatorV2(opInfo);
     606            4 : }
     607              : 
     608            4 : void DumpManager::ConvertOperatorInfo(const OperatorInfo& opInfo, OperatorInfoV2& operatorInfoV2) const
     609              : {
     610            4 :     operatorInfoV2.agingFlag = opInfo.agingFlag;
     611            4 :     operatorInfoV2.taskId = opInfo.taskId;
     612            4 :     operatorInfoV2.streamId = opInfo.streamId;
     613            4 :     operatorInfoV2.deviceId = opInfo.deviceId;
     614            4 :     operatorInfoV2.contextId = opInfo.contextId;
     615            4 :     operatorInfoV2.opType = opInfo.opType;
     616            4 :     operatorInfoV2.opName = opInfo.opName;
     617            4 :     operatorInfoV2.tensorInfos = ConvertTensorInfoToDumpTensorV2(opInfo.tensorInfos);
     618            4 :     operatorInfoV2.deviceInfos = opInfo.deviceInfos;
     619            4 :     operatorInfoV2.additionalInfo = opInfo.additionalInfo;
     620            4 : }
     621              : 
     622           31 : std::vector<TensorInfoV2> DumpManager::ConvertTensorInfoToDumpTensorV2(const std::vector<TensorInfo>& tensorInfos) const
     623              : {
     624           31 :     std::vector<TensorInfoV2> tensors;
     625           31 :     tensors.reserve(tensorInfos.size());
     626           55 :     for (const auto& tensorInfo : tensorInfos) {
     627           24 :         TensorInfoV2 tensor = {};
     628           24 :         ConvertTensorInfo(tensorInfo, tensor);
     629           24 :         tensors.emplace_back(tensor);
     630           24 :     }
     631           31 :     return tensors;
     632            0 : }
     633              : 
     634           96 : void DumpManager::ConvertTensorInfo(const TensorInfo& tensorInfo, TensorInfoV2& tensor) const
     635              : {
     636           96 :     tensor.dataType = tensorInfo.dataType;
     637           96 :     tensor.format = tensorInfo.format;
     638           96 :     tensor.placement = tensorInfo.placement;
     639           96 :     tensor.tensorAddr = tensorInfo.tensorAddr;
     640           96 :     tensor.tensorSize = tensorInfo.tensorSize;
     641           96 :     tensor.type = tensorInfo.type;
     642           96 :     tensor.addrType = tensorInfo.addrType;
     643           96 :     tensor.argsOffSet = tensorInfo.argsOffSet;
     644           96 :     std::vector<int64_t> shape = tensorInfo.shape;
     645          171 :     for (auto dim : shape) {
     646           75 :         tensor.shape.emplace_back(static_cast<uint64_t>(dim));
     647              :     }
     648           96 :     std::vector<int64_t> originShape = tensorInfo.originShape;
     649          171 :     for (auto dim : originShape) {
     650           75 :         tensor.originShape.emplace_back(static_cast<uint64_t>(dim));
     651              :     }
     652           96 : }
     653              : 
     654            6 : int32_t DumpManager::DelExceptionOp(uint32_t deviceId, uint32_t streamId)
     655              : {
     656            6 :     return exceptionDumper_.DelDumpOperator(deviceId, streamId);
     657              : }
     658              : 
     659           52 : int32_t DumpManager::DumpExceptionInfo(const rtExceptionInfo& exception)
     660              : {
     661           52 :     return exceptionDumper_.DumpException(exception);
     662              : }
     663              : 
     664           17 : uint64_t DumpManager::AdumpGetDumpSwitch()
     665              : {
     666           17 :     std::lock_guard<std::mutex> lk(resourceMtx_);
     667           34 :     return dumpSetting_.GetDumpSwitch();
     668           17 : }
     669              : 
     670           47 : bool DumpManager::RegsiterExceptionCallback()
     671              : {
     672           47 :     if (!registered_ && rtRegTaskFailCallbackByModule(EXCEPTION_CB_MODULE, ExceptionCallback) == RT_ERROR_NONE) {
     673           37 :         registered_ = true;
     674              :     }
     675           47 :     IDE_LOGI("Register exception callback, registered: %d", static_cast<int32_t>(registered_));
     676           47 :     return registered_;
     677              : }
     678              : 
     679           24 : DumpSetting DumpManager::GetDumpSetting() const
     680              : {
     681           24 :     return dumpSetting_;
     682              : }
     683              : 
     684            3 : void DumpManager::ExceptionModeDowngrade()
     685              : {
     686            3 :     exceptionDumper_.ExceptionModeDowngrade();
     687            3 : }
     688              : 
     689           60 : bool DumpManager::IsEnabledExceptionDump()
     690              : {
     691           60 :     std::lock_guard<std::mutex> lk(resourceMtx_);
     692          120 :     return exceptionDumper_.IsEnabledExceptionDump();
     693           60 : }
     694              : 
     695           30 : int32_t DumpManager::RegisterCallback(uint32_t moduleId, AdumpCallback enableFunc, AdumpCallback disableFunc)
     696              : {
     697           30 :     if (enableFunc == nullptr) {
     698            6 :         IDE_LOGE("Register callback failed: enableFunc is null for module %u", moduleId);
     699            6 :         return ADUMP_FAILED;
     700              :     }
     701           24 :     if (disableFunc == nullptr) {
     702            6 :         IDE_LOGE("Register callback failed: disableFunc is null for module %u", moduleId);
     703            6 :         return ADUMP_FAILED;
     704              :     }
     705           18 :     std::lock_guard<std::mutex> lk(resourceMtx2_);
     706           18 :     enableCallbackFunc_[moduleId] = enableFunc;
     707           18 :     disableCallbackFunc_[moduleId] = disableFunc;
     708           18 :     IDE_LOGI("Registered callback for module %u", moduleId);
     709           18 :     return HandleDumpEvent(moduleId, DumpEnableAction::AUTO);
     710           18 : }
     711              : 
     712           33 : int32_t DumpManager::StartDumpArgs(const std::string& dumpPath)
     713              : {
     714           33 :     uint64_t dumpSwitch = 0;
     715              :     {
     716           33 :         std::lock_guard<std::mutex> lk(resourceMtx_);
     717           33 :         dumpSwitch = dumpSetting_.GetDumpSwitch();
     718           33 :         if ((dumpSwitch & OP_INFO_RECORD_DUMP) == OP_INFO_RECORD_DUMP) {
     719          144 :             REPORT_EP0008_API_CALL_SEQUENCE(
     720              :                 FUNC_NAME_ACL_OP_START_DUMP_ARGS, ADUMP_REASON_API_CALLED_REPEATEDLY);
     721            9 :             return -1;
     722              :         }
     723              : 
     724           24 :         Adx::Path path(dumpPath);
     725           24 :         if (path.Empty()) {
     726           72 :             REPORT_EP0006_INVALID_ARGUMENT(
     727              :                 FUNC_NAME_ACL_OP_START_DUMP_ARGS, dumpPath, FUNC_ACL_OP_START_DUMP_ARGS_PARAM_PATH,
     728              :                 ADUMP_REASON_PARAM_PATH_EMPTY);
     729            3 :             return -1;
     730              :         }
     731           21 :         if (!path.Exist()) {
     732           18 :             if (!path.CreateDirectory(true)) {
     733            3 :                 std::string reason = StrUtils::Format(ADUMP_REASON_PARAM_PATH_CREATE_DIR_ERROR, strerror(errno));
     734           69 :                 REPORT_EP0006_INVALID_ARGUMENT(
     735              :                     FUNC_NAME_ACL_OP_START_DUMP_ARGS, dumpPath, FUNC_ACL_OP_START_DUMP_ARGS_PARAM_PATH, reason);
     736            3 :                 return -1;
     737            3 :             }
     738              :         }
     739           18 :         if (!path.IsDirectory()) {
     740           72 :             REPORT_EP0006_INVALID_ARGUMENT(
     741              :                 FUNC_NAME_ACL_OP_START_DUMP_ARGS, dumpPath, FUNC_ACL_OP_START_DUMP_ARGS_PARAM_PATH,
     742              :                 ADUMP_REASON_PARAM_PATH_NOT_DIRECTORY);
     743            3 :             return -1;
     744              :         }
     745           15 :         constexpr uint32_t accessMode = static_cast<uint32_t>(M_R_OK) | static_cast<uint32_t>(M_W_OK);
     746           15 :         if (!path.Asccess(accessMode)) {
     747           72 :             REPORT_EP0006_INVALID_ARGUMENT(
     748              :                 FUNC_NAME_ACL_OP_START_DUMP_ARGS, dumpPath, FUNC_ACL_OP_START_DUMP_ARGS_PARAM_PATH,
     749              :                 ADUMP_REASON_PATH_NO_PERMISSION);
     750            3 :             return -1;
     751              :         }
     752              : 
     753           12 :         dumpSwitch |= OP_INFO_RECORD_DUMP;
     754           12 :         dumpSetting_.InitDumpSwitch(dumpSwitch);
     755           12 :         opInfoRecordPath_ = path.GetString();
     756           45 :     }
     757           33 :     for (auto& item : enableCallbackFunc_) {
     758           21 :         item.second(dumpSwitch, dumpConfigInfo_.data(), dumpConfigInfo_.size());
     759              :     }
     760           12 :     IDE_RUN_LOGI("OpInfoRecord start success!");
     761           12 :     return 0;
     762           42 : }
     763              : 
     764           15 : int32_t DumpManager::StopDumpArgs()
     765              : {
     766           15 :     uint64_t dumpSwitch = 0;
     767              :     {
     768           15 :         std::lock_guard<std::mutex> lk(resourceMtx_);
     769           15 :         dumpSwitch = dumpSetting_.GetDumpSwitch();
     770           15 :         if ((dumpSwitch & OP_INFO_RECORD_DUMP) != OP_INFO_RECORD_DUMP) {
     771            6 :             return 0;
     772              :         }
     773            9 :         IDE_RUN_LOGI("OpInfoRecord Stop Entry!");
     774            9 :         dumpSwitch &= ~OP_INFO_RECORD_DUMP;
     775            9 :         dumpSetting_.InitDumpSwitch(dumpSwitch);
     776           15 :     }
     777           21 :     for (auto& item : disableCallbackFunc_) {
     778           12 :         item.second(dumpSwitch, dumpConfigInfo_.data(), dumpConfigInfo_.size());
     779              :     }
     780            9 :     IDE_RUN_LOGI("OpInfoRecord success!");
     781            9 :     return 0;
     782              : }
     783              : 
     784            6 : const char* DumpManager::GetExtraExceptionDumpPath()
     785              : {
     786            6 :     std::lock_guard<std::mutex> lk(resourceMtx_);
     787            6 :     exceptionDumper_.CreateExtraDumpPath();
     788           12 :     return exceptionDumper_.GetExtraDumpCPath();
     789            6 : }
     790              : 
     791           36 : const char* DumpManager::GetDataDumpPath()
     792              : {
     793           36 :     std::lock_guard<std::mutex> lk(resourceMtx_);
     794           72 :     return dumpSetting_.GetDumpCPath();
     795           36 : }
     796              : 
     797            9 : int32_t DumpManager::GetExceptionDumpPath(std::string &path)
     798              : {
     799            9 :     std::lock_guard<std::mutex> lk(resourceMtx_);
     800           18 :     return exceptionDumper_.GetExceptionDumpPath(path);
     801            9 : }
     802              : 
     803           15 : int32_t DumpManager::SaveExceptionInfo(const std::string& fileName, const std::string& userTag,
     804              :     const std::vector<TensorInfo>& tensors)
     805              : {
     806           15 :     std::lock_guard<std::mutex> lk(resourceMtx_);
     807           30 :     return exceptionDumper_.SaveExceptionInfo(fileName, userTag, tensors);
     808           15 : }
     809              : 
     810           27 : int32_t DumpManager::SaveFile(const char* data, size_t dataLen, const char* fileName, SaveType type)
     811              : {
     812           27 :     std::string canonicalPath;
     813           54 :     if (!Adx::Path::BuildFullPathUnderRoot(opInfoRecordPath_, fileName, canonicalPath)) {
     814           12 :         IDE_LOGE("invalid fileName[%s], may escape root path.", fileName);
     815           12 :         return -1;
     816              :     }
     817           15 :     int32_t openFlag = 0;
     818           15 :     if (type == SaveType::OVERWRITE) {
     819            9 :         openFlag = O_CREAT | O_WRONLY | O_TRUNC;
     820              :     } else {
     821            6 :         openFlag = O_CREAT | O_WRONLY | O_APPEND;
     822              :     }
     823           15 :     File file(canonicalPath, openFlag);
     824              : 
     825           15 :     if (file.IsFileOpen() != 0) {
     826            6 :         IDE_LOGE("open file[%s] failed!", fileName);
     827            6 :         return -1;
     828              :     }
     829            9 :     int64_t ret = file.Write(data, dataLen);
     830            9 :     IDE_CTRL_VALUE_FAILED(ret >= 0, return -1, "Save file %s failed!", fileName);
     831              : 
     832            9 :     IDE_LOGI("DumpJsonToFile %s success!", fileName);
     833            9 :     return 0;
     834           27 : }
     835              : 
     836           48 : int32_t DumpManager::CallbackEnvExceptionDumpEvent(AdumpCallback callbackFunc)
     837              : {
     838           48 :     if (isEnvExceptionDump_) {
     839            0 :         IDE_LOGI("Callback module when exception dump enabled with env.");
     840            0 :         if (exceptionDumper_.GetArgsExceptionStatus() || exceptionDumper_.GetCoredumpStatus()) {
     841            0 :             return callbackFunc(DUMP_SWITCH_L0_MACK, nullptr, 0);
     842            0 :         } else if (exceptionDumper_.GetExceptionStatus()) {
     843            0 :             return callbackFunc(DUMP_SWITCH_L1_MACK, nullptr, 0);
     844              :         }
     845              :     }
     846           48 :     return ADUMP_SUCCESS;
     847              : }
     848              : 
     849              : // DUMP 配置变化时,触发dump事件,同步回调用户接口
     850           96 : int32_t DumpManager::HandleDumpEvent(uint32_t moduleId, DumpEnableAction action)
     851              : {
     852           96 :     const uint64_t dumpSwitch = dumpSetting_.GetDumpSwitch();
     853           96 :     auto callbackFunc = disableCallbackFunc_[moduleId];
     854           96 :     if (action == DumpEnableAction::ENABLE) {
     855           27 :         callbackFunc = enableCallbackFunc_[moduleId];
     856              :         // 回调环境变量开启exception dump
     857           27 :         (void)CallbackEnvExceptionDumpEvent(callbackFunc);
     858              :     }
     859           96 :     if (action == DumpEnableAction::AUTO) {
     860              :         // 回调环境变量开启exception dump
     861           18 :         (void)CallbackEnvExceptionDumpEvent(enableCallbackFunc_[moduleId]);
     862           18 :         if (dumpConfigInfo_.data() == nullptr || dumpConfigInfo_.size() == 0U) {
     863            3 :             IDE_LOGW("Config data is null or empty. Not trigger HandleDumpEvent.");
     864            3 :             return ADUMP_SUCCESS;
     865              :         }
     866           15 :         if (dumpSwitch > 0U) {
     867           15 :             callbackFunc = enableCallbackFunc_[moduleId];
     868              :         }
     869              :     }
     870              : 
     871           93 :     if (!callbackFunc) {
     872           15 :         IDE_LOGE("No registered callback for module %u", moduleId);
     873           15 :         return ADUMP_FAILED;
     874              :     }
     875              : 
     876           78 :     IDE_LOGI("HandleDumpEvent callbackFunc start for module [%zu]", moduleId);
     877           78 :     IDE_LOGI("HandleDumpEvent callbackFunc switch [%" PRIu64 "]", dumpSwitch);
     878           78 :     IDE_LOGI(
     879              :         "HandleDumpEvent callbackFunc Dump config info: addr=%p, size=%zu", dumpConfigInfo_.data(),
     880              :         dumpConfigInfo_.size());
     881           78 :     int32_t result = callbackFunc(dumpSwitch, dumpConfigInfo_.data(), dumpConfigInfo_.size());
     882           78 :     IDE_LOGI("callbackFunc returned: %d", result);
     883           78 :     return result;
     884              : }
     885              : 
     886              : #ifdef __ADUMP_LLT
     887          644 : void DumpManager::Reset()
     888              : {
     889          644 :     registered_ = false;
     890          644 :     exceptionDumper_.Reset();
     891          644 : }
     892              : 
     893            9 : bool DumpManager::GetKFCInitStatus()
     894              : {
     895            9 :     return isKFCInit_;
     896              : }
     897              : 
     898            6 : void DumpManager::SetKFCInitStatus(bool status)
     899              : {
     900            6 :     isKFCInit_ = status;
     901            6 : }
     902              : #endif
     903              : 
     904           18 : int32_t DumpManager::RegisterExceptionDumpCallback(ExceptionDumpCallback callback)
     905              : {
     906           18 :     return exceptionDumper_.RegisterExceptionDumpCallback(callback);
     907              : }
     908              : 
     909           18 : int32_t DumpManager::UnregisterExceptionDumpCallback(ExceptionDumpCallback callback)
     910              : {
     911           18 :     return exceptionDumper_.UnregisterExceptionDumpCallback(callback);
     912              : }
     913              : 
     914              : } // namespace Adx
        

Generated by: LCOV version 2.0-1