Skip to content

[code-review] daemon_bridge daemonSessionTurnIndex bare-reads UsageHistory/Metrics instead of snapshot accessors (low) #3091

Closed

Description

@topcheer

初筛 sa-215 + 独立复核 sa-216 确认(V1 读侧缺口被复核推翻——#3087 修复实际完整;V2 真实但低危)。

文件与行号

internal/im/daemon_bridge.go L1237-1241(daemonSessionTurnIndex)

问题描述

if n := len(ses.UsageHistory); n > 0 && ses.UsageHistory[n-1].TurnIndex > last {
...
if n := len(ses.Metrics); n > 0 && ses.Metrics[n-1].TurnIndex > last {

裸读共享切片,未持 endpointStatsMu——而 #3087/#3086 已为跨 goroutine 读提供持锁快照访问器 UsageHistorySnapshot()(endpoint_stats.go L68)/MetricsSnapshot()(L84),此处未使用。与 append 并发时 -race 可报,极端下 torn view。

触发场景

daemonSessionTurnIndex 唯一调用点为 NewDaemonBridge L120(bridge 构造期一次性),早于 collector 注册(L133)——实际并发窗口接近零,故低危。属 #3087 收尾遗漏的一致性缺口而非可复现故障。

预期 vs 实际

预期:跨 goroutine 读走快照访问器(访问器注释明言此用途);实际:裸读。

修复建议

两行替换:ses.UsageHistorySnapshot() / ses.MetricsSnapshot() 后取末元素(或 len==0 跳过)。

严重程度

low(构造期一次性读、窗口近零;一致性收尾)

Activity

  1. added a commit that references this issue on Oct 2, 2026
  2. topcheer commented on Oct 2, 2026

    @topcheer
    OwnerAuthor

    已复核确认并修复(PR #3092,已合并,CI 全绿)。

    根因

    daemonSessionTurnIndex(daemon_bridge.go L1237-1241)在 #3087 引入持锁快照访问器后仍保留两处裸读(len(ses.UsageHistory)+末元素、s.Metrics 同型)——访问器注释明言的跨 goroutine 读用途未在此处落地。唯一调用点为 bridge 构造期一次性(早于 collector 注册),窗口近零,属 #3087 收尾遗漏的一致性缺口(issue 内 V1 读侧缺口主张已被复核正确推翻——#3087 修复本身完整)。

    修复

    两处裸读替换为 UsageHistorySnapshot()/MetricsSnapshot()(#3086/#3087 同一锁域),max-TurnIndex 语义不变。

    验证

    • go build -tags goolm ./... + internal/im 包测试 -race 模式绿
    • 新探针 zz_issue3091_test.go:nil 会话/空会话/usage 末项最大/metric 末项最大四态
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions