1 开发平台
Win11、VS2022、Fedora39。
2 作业目的
通过VS2022跨平台Linux构建openbmc/intel-ipmi-oem的x64可执行模块。
3 问题描述
该模块启动后,在执行subprojects\phosphor-host-ipmid\user_channel\channel_mgmt.cpp
中的函数convertToMediumTypeIndex出现异常:
if (it == mediumTypeMap.end())
{
log<level::ERR>("Invalid medium type.",
entry("MEDIUM_STR=%s", value.c_str()));
throw std::invalid_argument("Invalid medium type.");
}
经检查,此时的全局变量mediumTypeMap内容为空。
在channel_mgmt.cpp的名字空间ipmi中定义了mediumTypeMap:
static std::unordered_map<std::string, EChannelMediumType> mediumTypeMap = {
{"reserved", EChannelMediumType::reserved},
{"ipmb", EChannelMediumType::ipmb},
{"icmb-v1.0", EChannelMediumType::icmbV10},
{"icmb-v0.9", EChannelMediumType::icmbV09},
{"lan-802.3", EChannelMediumType::lan8032},
{"serial", EChannelMediumType::serial},
{"other-lan", EChannelMediumType::otherLan},
{"pci-smbus", EChannelMediumType::pciSmbus},
{"smbus-v1.0", EChannelMediumType::smbusV11},
{"smbus-v2.0", EChannelMediumType::smbusV20},
{"usb-1x", EChannelMediumType::usbV1x},
{"usb-2x", EChannelMediumType::usbV2x},
{"system-interface", EChannelMediumType::systemInterface},
{"oem", EChannelMediumType::oem},
{"unknown", EChannelMediumType::unknown}};
调用convertToMediumTypeIndex的函数loadChannelConfig定义在名字空间ChannelConfig中
,因此可推断在调用发生时mediumTypeMap还未初始化。
4 解决方法
通过搜索确认,mediumTypeMap只被convertToMediumTypeIndex访问,因此可把前者的定义移到后者之中:
EChannelMediumType
ChannelConfig::convertToMediumTypeIndex(const std::string& value)
{
static std::unordered_map<std::string, EChannelMediumType> mediumTypeMap = {
{"reserved", EChannelMediumType::reserved},
{"ipmb", EChannelMediumType::ipmb},
{"icmb-v1.0", EChannelMediumType::icmbV10},
{"icmb-v0.9", EChannelMediumType::icmbV09},
{"lan-802.3", EChannelMediumType::lan8032},
{"serial", EChannelMediumType::serial},
{"other-lan", EChannelMediumType::otherLan},
{"pci-smbus", EChannelMediumType::pciSmbus},
{"smbus-v1.0", EChannelMediumType::smbusV11},
{"smbus-v2.0", EChannelMediumType::smbusV20},
{"usb-1x", EChannelMediumType::usbV1x},
{"usb-2x", EChannelMediumType::usbV2x},
{"system-interface", EChannelMediumType::systemInterface},
{"oem", EChannelMediumType::oem},
{"unknown", EChannelMediumType::unknown} };
std::unordered_map<std::string, EChannelMediumType>::iterator it =
mediumTypeMap.find(value);
if (it == mediumTypeMap.end())
{
log<level::ERR>("Invalid medium type.",
entry("MEDIUM_STR=%s", value.c_str()));
throw std::invalid_argument("Invalid medium type.");
}
return static_cast<EChannelMediumType>(it->second);
}
这样就能确保mediumTypeMap在被访问之前已经完成了初始化。
channel_mgmt.cpp中的以下变量也要进行类似处理:
- protocolTypeMap
- accessModeList
- sessionSupportList