grpc / grpc-swift

The Swift language implementation of gRPC.
Apache License 2.0
2.03k stars 420 forks source link

threading issue in/shown by GRPCTests.ClientConnectionBackoffTests testClientEventuallyConnects #756

Closed weissi closed 4 years ago

weissi commented 4 years ago

New Issue Checklist

Issue Description

I ran

swift test --sanitize=thread --disable-index-store

and got

Complete output when running grpc-swift, including the stack trace and command used
[...]
Test Case '-[GRPCTests.ClientConnectionBackoffTests testClientEventuallyConnects]' started.
==================
WARNING: ThreadSanitizer: data race (pid=16913)
  Write of size 8 at 0x7b4c00005298 by thread T18:
    #0 ClientConnection.channel.setter <compiler-generated> (grpc-swiftPackageTests:x86_64+0x33036a)
    #1 closure #3 in ClientConnection.willSetChannel(to:) ClientConnection.swift:191 (grpc-swiftPackageTests:x86_64+0x336ab7)
    #2 partial apply for closure #3 in ClientConnection.willSetChannel(to:) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x3477df)
    #3 thunk for @escaping @callee_guaranteed (@guaranteed Result<(), Error>) -> () <compiler-generated> (grpc-swiftPackageTests:x86_64+0x337037)
    #4 partial apply for thunk for @escaping @callee_guaranteed (@guaranteed Result<(), Error>) -> () <compiler-generated> (grpc-swiftPackageTests:x86_64+0x347880)
    #5 closure #1 in EventLoopFuture.whenComplete(_:) EventLoopFuture.swift:738 (grpc-swiftPackageTests:x86_64+0x73f475)
    #6 partial apply for closure #1 in EventLoopFuture.whenComplete(_:) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x74366f)
    #7 CallbackList._run() EventLoopFuture.swift:88 (grpc-swiftPackageTests:x86_64+0x733560)
    #8 EventLoopPromise._resolve(value:) EventLoopFuture.swift:226 (grpc-swiftPackageTests:x86_64+0x734b75)
    #9 EventLoopPromise.succeed(_:) EventLoopFuture.swift:171 (grpc-swiftPackageTests:x86_64+0x734964)
    #10 closure #4 in BaseSocketChannel.close0(error:mode:promise:) BaseSocketChannel.swift:851 (grpc-swiftPackageTests:x86_64+0x63e922)
    #11 partial apply for closure #4 in BaseSocketChannel.close0(error:mode:promise:) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x64c3bd)
    #12 thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (grpc-swiftPackageTests:x86_64+0x7e0777)
    #13 partial apply for thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (grpc-swiftPackageTests:x86_64+0x7e6bfd)
    #14 thunk for @escaping @callee_guaranteed () -> (@out ()) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x7e07c7)
    #15 partial apply for thunk for @escaping @callee_guaranteed () -> (@out ()) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x7e544b)
    #16 closure #3 in SelectableEventLoop.run() SelectableEventLoop.swift:430 (grpc-swiftPackageTests:x86_64+0x7e0844)
    #17 partial apply for closure #3 in SelectableEventLoop.run() <compiler-generated> (grpc-swiftPackageTests:x86_64+0x7e533b)
    #18 thunk for @callee_guaranteed () -> (@error @owned Error) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x4ae19f)
    #19 thunk for @callee_guaranteed () -> (@error @owned Error)partial apply <compiler-generated> (grpc-swiftPackageTests:x86_64+0x7e53a7)
    #20 closure #1 in withAutoReleasePool<A>(_:) SelectableEventLoop.swift:23 (grpc-swiftPackageTests:x86_64+0x7d72e8)
    #21 partial apply for closure #1 in withAutoReleasePool<A>(_:) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x7d73ba)
    #22 autoreleasepool<A>(invoking:) <null>:3203040 (libswiftObjectiveC.dylib:x86_64+0x3f4d)
    #23 SelectableEventLoop.run() SelectableEventLoop.swift:429 (grpc-swiftPackageTests:x86_64+0x7de607)
    #24 closure #1 in static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:selectorFactory:initializer:) EventLoop.swift:753 (grpc-swiftPackageTests:x86_64+0x725103)
    #25 partial apply for closure #1 in static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:selectorFactory:initializer:) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x7309c8)
    #26 thunk for @escaping @callee_guaranteed (@guaranteed NIOThread) -> () <compiler-generated> (grpc-swiftPackageTests:x86_64+0x725dfb)
    #27 partial apply for thunk for @escaping @callee_guaranteed (@guaranteed NIOThread) -> () <compiler-generated> (grpc-swiftPackageTests:x86_64+0x84aac8)
    #28 closure #1 in static ThreadOpsPosix.run(handle:args:detachThread:) ThreadPosix.swift:97 (grpc-swiftPackageTests:x86_64+0x850433)
    #29 @objc closure #1 in static ThreadOpsPosix.run(handle:args:detachThread:) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x8504f0)

  Previous read of size 8 at 0x7b4c00005298 by main thread:
    #0 ClientConnection.channel.getter <compiler-generated> (grpc-swiftPackageTests:x86_64+0x3301e4)
    #1 ClientConnection.close() ClientConnection.swift:150 (grpc-swiftPackageTests:x86_64+0x3353a4)
    #2 ClientConnectionBackoffTests.tearDown() ClientConnectionBackoffTests.swift:112 (grpc-swiftPackageTests:x86_64+0x4c6e74)
    #3 @objc ClientConnectionBackoffTests.tearDown() <compiler-generated> (grpc-swiftPackageTests:x86_64+0x4c7e84)
    #4 __51-[XCTestCase _performTearDownSequenceWithSelector:]_block_invoke_2 <null>:3203040 (XCTest:x86_64+0x31c8b)

  Location is heap block of size 416 at 0x7b4c00005240 allocated by main thread:
    #0 malloc <null>:3203072 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x4defa)
    #1 swift_slowAlloc <null>:3203072 (libswiftCore.dylib:x86_64+0x2cb288)
    #2 ClientConnection.Builder.connect(host:port:) GRPCChannelBuilder.swift:53 (grpc-swiftPackageTests:x86_64+0x36962c)
    #3 ClientConnectionBackoffTests.testClientEventuallyConnects() ClientConnectionBackoffTests.swift:150 (grpc-swiftPackageTests:x86_64+0x4c9899)
    #4 @objc ClientConnectionBackoffTests.testClientEventuallyConnects() <compiler-generated> (grpc-swiftPackageTests:x86_64+0x4cabf7)
    #5 __invoking___ <null>:3203072 (CoreFoundation:x86_64h+0x65a6b)

  Thread T18 (tid=2585161, running) created by main thread at:
    #0 pthread_create <null>:3203120 (libclang_rt.tsan_osx_dynamic.dylib:x86_64h+0x2a26d)
    #1 sysPthread_create(handle:destructor:args:) ThreadPosix.swift:40 (grpc-swiftPackageTests:x86_64+0x84eab3)
    #2 static ThreadOpsPosix.run(handle:args:detachThread:) ThreadPosix.swift:82 (grpc-swiftPackageTests:x86_64+0x84f6df)
    #3 static NIOThread.spawnAndRun(name:detachThread:body:) Thread.swift:94 (grpc-swiftPackageTests:x86_64+0x84a820)
    #4 static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:selectorFactory:initializer:) EventLoop.swift:739 (grpc-swiftPackageTests:x86_64+0x7249b6)
    #5 closure #1 in MultiThreadedEventLoopGroup.init(threadInitializers:selectorFactory:) EventLoop.swift:793 (grpc-swiftPackageTests:x86_64+0x7268bf)
    #6 partial apply for closure #1 in MultiThreadedEventLoopGroup.init(threadInitializers:selectorFactory:) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x72ce60)
    #7 thunk for @callee_guaranteed (@guaranteed @escaping @callee_guaranteed (@guaranteed NIOThread) -> ()) -> (@owned SelectableEventLoop, @error @owned Error) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x726a50)
    #8 partial apply for thunk for @callee_guaranteed (@guaranteed @escaping @callee_guaranteed (@guaranteed NIOThread) -> ()) -> (@owned SelectableEventLoop, @error @owned Error) <compiler-generated> (grpc-swiftPackageTests:x86_64+0x72ced2)
    #9 Collection.map<A>(_:) <null>:3203120 (libswiftCore.dylib:x86_64+0xfefe)
    #10 MultiThreadedEventLoopGroup.__allocating_init(threadInitializers:selectorFactory:) EventLoop.swift (grpc-swiftPackageTests:x86_64+0x725f6f)
    #11 MultiThreadedEventLoopGroup.__allocating_init(numberOfThreads:selectorFactory:) EventLoop.swift:779 (grpc-swiftPackageTests:x86_64+0x725c9c)
    #12 MultiThreadedEventLoopGroup.__allocating_init(numberOfThreads:) EventLoop.swift:772 (grpc-swiftPackageTests:x86_64+0x725a6e)
    #13 ClientConnectionBackoffTests.setUp() ClientConnectionBackoffTests.swift:95 (grpc-swiftPackageTests:x86_64+0x4c652d)
    #14 @objc ClientConnectionBackoffTests.setUp() <compiler-generated> (grpc-swiftPackageTests:x86_64+0x4c6624)
    #15 __70-[XCTestCase _shouldContinueAfterPerformingSetUpSequenceWithSelector:]_block_invoke_2 <null>:3203120 (XCTest:x86_64+0x318ba)

SUMMARY: ThreadSanitizer: data race <compiler-generated> in ClientConnection.channel.setter
==================
Test Case '-[GRPCTests.ClientConnectionBackoffTests testClientEventuallyConnects]' passed (0.488 seconds).
[...]

Environment

swift-nio: a27a07719ca785bcaca019a5b9fe1814b981b4a2
swift-nio-extras: 4a71e8ad6eb44a5074551c83de16b17d47de6202
swift-nio-http2: 6970de5512cb3b3d094986f0f80e87fe6a1110a0
swift-nio-ssl: 7add274f6ecac28be9c8ed2a678371f0868836ad
swift-nio-transport-services: fc80bf018b778da32663e1acbf24416d0ff5e63c
grpc-swift: ec809b75721de0e42aebd92a48129573e644f373

  
glbrntt commented 4 years ago

Should be resolved by #798