You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ThreadSanitizer下Task.sleep触发数据竞争告警是否为误报

启用Thread Sanitizer运行单元测试时Task.sleep触发Data Race告警

问题现象

开启Thread Sanitizer运行单元测试时,执行以下语句会出现Data Race警告:

try? await Task.sleep(nanoseconds: 10_000_000)

更新说明

  • 仅使用Swift Combine与Swift Concurrency相关API即可稳定复现该数据竞争警告,已确认自身业务代码并非问题诱因,原有业务相关代码已移除。
  • 复现前置要求:复现前需在测试Scheme的「Diagnostics」配置项中开启Thread Sanitizer。测试逻辑为启动任务后等待10秒触发超时取消,循环中每0.01秒调用一次上述Task.sleep语句即可触发数据竞争,可独立运行的XCTest复现代码如下:
import XCTest
import Combine

extension Publisher {
    func asyncMap<T>(
        _ transform: @escaping @Sendable (Output) async -> T
    ) -> Publishers.FlatMap<Future<T, Never>, Self> where Output: Sendable {
        flatMap { value in
            Future { promise in
                Task {
                    let output = await transform(value)
                    promise(.success(output))
                }
            }
        }
    }
}

class ThreadSafetyTests: XCTestCase {

    func testExample() throws {

        let expectCompletion = expectation(description: "completion")
        expectCompletion.isInverted = true

        let cancellable = ["a", "b", "b"].publisher
        .asyncMap { (string: String) -> String  in
            while !Task.isCancelled {
                try? await Task.sleep(nanoseconds: 10_000_000)  // 0.01 second
            }
            return string.uppercased()
        }
        .sink { completion in
            expectCompletion.fulfill()  // it should never fullfill!
        } receiveValue: { string in
        }

        wait(for: [expectCompletion], timeout: 10)
        cancellable.cancel()
    }
}

Thread Sanitizer告警详情

控制台输出的ThreadSanitizer详细告警日志如下:

WARNING: ThreadSanitizer: data race (pid=40024)
  Read of size 8 at 0x7b6400040d30 by thread T3:
    #0 (1) await resume partial function for closure #1 in ThreadSafetyTests.testExample() ThreadSafetyTests.swift:29 (OakTests:x86_64+0x6846a)
    #1 swift::runJobInEstablishedExecutorContext(swift::Job*) <null>:2 (libswift_Concurrency.dylib:x86_64+0x2be53)

  Previous write of size 8 at 0x7b6400040d30 by thread T1:
    #0 (1) await resume partial function for closure #1 in ThreadSafetyTests.testExample() ThreadSafetyTests.swift:29 (OakTests:x86_64+0x6857e)
    #1 swift::runJobInEstablishedExecutorContext(swift::Job*) <null>:2 (libswift_Concurrency.dylib:x86_64+0x2be53)

  Location is heap block of size 1032 at 0x7b6400040b00 allocated by thread T6:
    #0 malloc <null>:3 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x532ec)
    #1 swift::StackAllocator<1000ul, &(swift::TaskAllocatorSlabMetadata)>::getSlabForAllocation(unsigned long) <null>:2 (libswift_Concurrency.dylib:x86_64+0x30c9a)
    #2 swift::runJobInEstablishedExecutorContext(swift::Job*) <null>:2 (libswift_Concurrency.dylib:x86_64+0x2be53)

  Thread T3 (tid=4063077, running) is a GCD worker thread

  Thread T1 (tid=4063076, running) is a GCD worker thread

  Thread T6 (tid=4063081, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: data race ThreadSafetyTests.swift:29 in (1) await resume partial function for closure #1 in ThreadSafetyTests.testExample()

当前判断

目前排查后认为业务代码侧无对应修复方案,怀疑该告警为ThreadSanitizer误报,欢迎提供相关参考意见。后续更新内容已删除。


内容的提问来源于stack exchange,提问作者CouchDeveloper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 08:09:23