Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TCPThroughputBenchmark has a crashing race #2649

Open
gmilos opened this issue Feb 14, 2024 · 0 comments
Open

TCPThroughputBenchmark has a crashing race #2649

gmilos opened this issue Feb 14, 2024 · 0 comments

Comments

@gmilos
Copy link
Contributor

gmilos commented Feb 14, 2024

Expected behavior

Test runs reliably.

Actual behavior

Test crashes occasionally with Unexpectedly found nil while implicitly unwrapping an Optional value

Steps to reproduce

  1. Build NIOPerformanceTester in release mode
  2. Run, potentially multiple times, observe the crash[1]

If possible, minimal yet complete reproducer code (or URL to code)

I can do one better, and explain the crash:

_ = self.context.writeAndFlush(self.wrapOutboundOut(message.slice()))

is invoked before the channel is active (and sets the implicitly unwrapping optional context)

public func channelActive(context: ChannelHandlerContext) {
self.context = context
}

SwiftNIO version/commit hash

https://github.com/apple/swift-nio/tree/82fd942745b11ccebbf0db3e9e4bf150b60e5e44

System & version information

An internal 23E macOS build, with an internal 15A Xcode / toolchain build.

Crash details

$ lldb ./NIOPerformanceTester tcp_100k_messages_throughput
(lldb) target create "./NIOPerformanceTester"
Current executable set to '/Users/gmilos/Library/Developer/Xcode/DerivedData/swift-nio-fjkfolkpoxtsaocgwcamnzdfgyrw/Build/Products/Release/NIOPerformanceTester' (arm64).
(lldb) settings set -- target.run-args  "tcp_100k_messages_throughput"
(lldb) run
Process 92876 launched: '/Users/gmilos/Library/Developer/Xcode/DerivedData/swift-nio-fjkfolkpoxtsaocgwcamnzdfgyrw/Build/Products/Release/NIOPerformanceTester' (arm64)
skipping 'write_http_headers', limit set = ["tcp_100k_messages_throughput"]
skipping 'http_headers_canonical_form', limit set = ["tcp_100k_messages_throughput"]
skipping 'http_headers_canonical_form_trimming_whitespace', limit set = ["tcp_100k_messages_throughput"]
...
skipping 'udp_10k_vector_reads', limit set = ["tcp_100k_messages_throughput"]
skipping 'udp_10k_vector_reads_and_writes', limit set = ["tcp_100k_messages_throughput"]
measuring: tcp_100k_messages_throughput: Process 92876 stopped
* thread #24, name = 'NIO-ELT-12-#3', stop reason = Swift runtime failure: Unexpectedly found nil while implicitly unwrapping an Optional value
    frame #1: 0x00000001000387d4 NIOPerformanceTester`closure #2 in TCPThroughputBenchmark.run() [inlined] NIOPerformanceTester.TCPThroughputBenchmark.ServerHandler.send(message=NIOCore.ByteBuffer @ 0x00006000002f2520, count=<unavailable>, self=<unavailable>) -> () at TCPThroughputBenchmark.swift:0 [opt]
   155 	        let message = self.message!
   156 	        let messages = self.messages
   157
-> 158 	        self.serverEventLoop.execute {
   159 	            serverHandler.send(message, times: messages)
   160 	        }
   161 	        try isDonePromise.futureResult.wait()
Note: this address is compiler-generated code in function NIOPerformanceTester.TCPThroughputBenchmark.ServerHandler.send(_: NIOCore.ByteBuffer, times: Swift.Int) -> () that has no source code associated with it.
Target 0: (NIOPerformanceTester) stopped.
warning: NIOPerformanceTester was compiled with optimization - stepping may behave oddly; variables may not be available.
(lldb) bt
* thread #24, name = 'NIO-ELT-12-#3', stop reason = Swift runtime failure: Unexpectedly found nil while implicitly unwrapping an Optional value
    frame #0: 0x00000001000387d4 NIOPerformanceTester`closure #2 in TCPThroughputBenchmark.run() [inlined] Swift runtime failure: Unexpectedly found nil while implicitly unwrapping an Optional value at <compiler-generated>:0 [opt]
  * frame #1: 0x00000001000387d4 NIOPerformanceTester`closure #2 in TCPThroughputBenchmark.run() [inlined] NIOPerformanceTester.TCPThroughputBenchmark.ServerHandler.send(message=NIOCore.ByteBuffer @ 0x00006000002ec100, count=<unavailable>, self=<unavailable>) -> () at TCPThroughputBenchmark.swift:0 [opt]
    frame #2: 0x00000001000387c4 NIOPerformanceTester`closure #2 in TCPThroughputBenchmark.run(serverHandler=0x0000600001ae48c0, message=NIOCore.ByteBuffer @ 0x00006000002b0180, messages=<unavailable>) at TCPThroughputBenchmark.swift:159:27 [opt]
    frame #3: 0x00000001001517f0 NIOPerformanceTester`SelectableEventLoop.run() at SelectableEventLoop.swift:534:29 [opt]
    frame #4: 0x00000001001517e8 NIOPerformanceTester`SelectableEventLoop.run() [inlined] generic specialization <()> of closure #1 () throws -> τ_0_0 in NIOPosix.withAutoReleasePool<τ_0_0>(() throws -> τ_0_0) throws -> τ_0_0 at SelectableEventLoop.swift:26:13 [opt]
    frame #5: 0x00000001001517e8 NIOPerformanceTester`SelectableEventLoop.run() [inlined] generic not re-abstracted specialization <()> of ObjectiveC.autoreleasepool<τ_0_0>(invoking: () throws -> τ_0_0) throws -> τ_0_0 at <compiler-generated>:0 [opt]
    frame #6: 0x00000001001517e8 NIOPerformanceTester`SelectableEventLoop.run() [inlined] generic specialization <()> of NIOPosix.withAutoReleasePool<τ_0_0>(() throws -> τ_0_0) throws -> τ_0_0 at SelectableEventLoop.swift:25:16 [opt]
    frame #7: 0x00000001001517e8 NIOPerformanceTester`SelectableEventLoop.run(self=0x00006000023bc2d0) at SelectableEventLoop.swift:531:21 [opt]
    frame #8: 0x000000010012e8d4 NIOPerformanceTester`closure #1 in static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(name:parentGroup:selectorFactory:initializer:) at MultiThreadedEventLoopGroup.swift:93:22 [opt]
    frame #9: 0x000000010012e8bc NIOPerformanceTester`closure #1 in static MultiThreadedEventLoopGroup.setupThreadAndEventLoop(t=<unavailable>, parentGroup=<unavailable>, selectorFactory=<unavailable>, initializer=<unavailable>, lock=0x0000600000543ea0) at MultiThreadedEventLoopGroup.swift:111:41 [opt]
    frame #10: 0x0000000100135410 NIOPerformanceTester`thunk for @escaping @callee_guaranteed (@guaranteed NIOThread) -> () at <compiler-generated>:0 [opt]
    frame #11: 0x000000010016c478 NIOPerformanceTester`closure #1 in static ThreadOpsPosix.run($0=0x600000543f00) at ThreadPosix.swift:116:13 [opt]
    frame #12: 0x0000000188002fa0 libsystem_pthread.dylib`_pthread_start + 136
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant