Thanks for sending an issue! Please fill in the following template to help quickly solve your problem. 感谢您提交issue!请填写以下模板,以便快速解决您的问题。
coordinator
ClusterNodes
shared_lock
ClusterNodes 使用 std::shared_mutex 保护实例状态、故障集合和 virtualId 映射,但多个写路径错误地在 std::shared_lock<std::shared_mutex> 下执行 insert、erase、operator[] 和对象字段写入。与此同时,请求转发、调度和实例查询路径又长期并发读取同一批共享容器。
std::shared_mutex
virtualId
std::shared_lock<std::shared_mutex>
insert
erase
operator[]
这不是“锁粒度可以更优”的代码味道,而是标准意义上的锁语义错误:读锁下写共享状态,遇到并发刷新、故障标记和请求读取时会进入未定义行为,结果可能是状态损坏、错误故障标记、崩溃或错误路由。
mindie_motor/src/coordinator/cluster_monitor/ClusterNodes.cpp
faultVirtualIds
faultIds
virtualToIdsMap
InstanceInfo
写路径 1:
void ClusterNodes::AddFaultNode(uint64_t id) { std::shared_lock<std::shared_mutex> lock(mtx); ... faultVirtualIds.insert(virtualId); faultIds.insert(id); virtualIdToDelTimeMap[virtualId] = system_clock::now(); idToDelTimeMap[id] = system_clock::now(); }
写路径 2:
void ClusterNodes::RemoveFaultNode(uint64_t id) { std::shared_lock<std::shared_mutex> lock(mtx); ... virtualIdToDelTimeMap.erase(virtualId); faultVirtualIds.erase(virtualId); auto allIds = virtualToIdsMap[virtualId]; ... virtualToIdsMap.erase(virtualId); }
写路径 3:
void ClusterNodes::UpdateExtraInfo(...) { std::shared_lock<std::shared_mutex> lock(mtx); ... iter->second->metricPort = httpParam.first; iter->second->interCommPort = httpParam.second; iter->second->virtualId = virtualId; if (virtualToIdsMap.find(virtualId) == virtualToIdsMap.end()) { virtualToIdsMap[virtualId] = initSet; } else { virtualToIdsMap[virtualId].insert(id); } }
位置:mindie_motor/src/coordinator/cluster_monitor/ClusterNodes.cpp:123-163,202-223
mindie_motor/src/coordinator/cluster_monitor/ClusterNodes.cpp:123-163,202-223
这些写路径与大量读路径并发共享同一把 mtx,例如 GetIp()、GetPort()、GetRole()、GetInstanceInfos()、GetVirtualIdToIds() 等。
mtx
GetIp()
GetPort()
GetRole()
GetInstanceInfos()
GetVirtualIdToIds()
Any
最小验证方向:
UpdateExtraInfo()
AddFaultNode()
RemoveFaultNode()
std::unique_lock<std::shared_mutex>
参见上文
Thanks for sending an issue! Please fill in the following template to help quickly solve your problem.
感谢您提交issue!请填写以下模板,以便快速解决您的问题。
Describe the current behavior / 问题描述 (Mandatory / 必填)
MM-007
coordinator的ClusterNodes在shared_lock下写共享状态,存在真实竞态和崩溃风险1. 摘要
ClusterNodes使用std::shared_mutex保护实例状态、故障集合和virtualId映射,但多个写路径错误地在std::shared_lock<std::shared_mutex>下执行insert、erase、operator[]和对象字段写入。与此同时,请求转发、调度和实例查询路径又长期并发读取同一批共享容器。这不是“锁粒度可以更优”的代码味道,而是标准意义上的锁语义错误:读锁下写共享状态,遇到并发刷新、故障标记和请求读取时会进入未定义行为,结果可能是状态损坏、错误故障标记、崩溃或错误路由。
2. 影响面与前置条件
mindie_motor/src/coordinator/cluster_monitor/ClusterNodes.cpp3. 攻击路径
ClusterNodesshared_lock持有期间修改faultVirtualIds、faultIds、virtualToIdsMap或InstanceInfo4. 关键代码分析
写路径 1:
void ClusterNodes::AddFaultNode(uint64_t id) { std::shared_lock<std::shared_mutex> lock(mtx); ... faultVirtualIds.insert(virtualId); faultIds.insert(id); virtualIdToDelTimeMap[virtualId] = system_clock::now(); idToDelTimeMap[id] = system_clock::now(); }写路径 2:
void ClusterNodes::RemoveFaultNode(uint64_t id) { std::shared_lock<std::shared_mutex> lock(mtx); ... virtualIdToDelTimeMap.erase(virtualId); faultVirtualIds.erase(virtualId); auto allIds = virtualToIdsMap[virtualId]; ... virtualToIdsMap.erase(virtualId); }写路径 3:
void ClusterNodes::UpdateExtraInfo(...) { std::shared_lock<std::shared_mutex> lock(mtx); ... iter->second->metricPort = httpParam.first; iter->second->interCommPort = httpParam.second; iter->second->virtualId = virtualId; if (virtualToIdsMap.find(virtualId) == virtualToIdsMap.end()) { virtualToIdsMap[virtualId] = initSet; } else { virtualToIdsMap[virtualId].insert(id); } }位置:
mindie_motor/src/coordinator/cluster_monitor/ClusterNodes.cpp:123-163,202-223这些写路径与大量读路径并发共享同一把
mtx,例如GetIp()、GetPort()、GetRole()、GetInstanceInfos()、GetVirtualIdToIds()等。Environment / 环境信息 (Mandatory / 必填)
Any
Steps to reproduce the issue / 重现步骤 (Mandatory / 必填)
最小验证方向:
UpdateExtraInfo()GetIp()、GetPort()、GetVirtualIdToIds()Describe the expected behavior / 预期结果 (Mandatory / 必填)
9. 修复建议
AddFaultNode()、RemoveFaultNode()、UpdateExtraInfo()全部改为std::unique_lock<std::shared_mutex>。ClusterNodes增加 TSAN 回归或最小并发 stress 测试。virtualToIdsMap、fault 集合和InstanceInfo写入建立统一的写路径约束。Related log / screenshot / 日志 / 截图 (Mandatory / 必填)
参见上文
Special notes for this issue/备注 (Optional / 选填)