ileitch
December 24, 2024, 6:32pm
1
I'm experiencing RunLoop.run hanging on ppol in a containerized Linux environment. Swift version doesn't appear to be a factor (I tried as far back as 5.8). It's such a basic example, I'm suprised it's not working and that I must be missing something obvious. Does this example hang for anyone else?
FROM swift:latest
WORKDIR /workspace
RUN swift package init --name Example --type executable
RUN echo "import Foundation" > Sources/main.swift
RUN echo "print(\"BEGIN\")" >> Sources/main.swift
RUN echo "RunLoop.current.run(until: Date(timeIntervalSinceNow: 1))" >> Sources/main.swift
RUN echo "print(\"END\")" >> Sources/main.swift
RUN swift build
ENTRYPOINT [".build/debug/Example"]
Output:
BEGIN
<hang>
Thread dump:
* thread #1, name = 'RunLoopHang', stop reason = signal SIGSTOP
* frame #0: 0x0000ffff94d210c8 libc.so.6`ppoll + 184
frame #1: 0x0000ffff95bc1740 libFoundation.so`__CFRunLoopServiceFileDescriptors + 104
frame #2: 0x0000ffff95bbd524 libFoundation.so`__CFRunLoopRun + 1016
frame #3: 0x0000ffff95bbceac libFoundation.so`CFRunLoopRunSpecific + 476
frame #4: 0x0000ffff95b44d44 libFoundation.so`Foundation.RunLoop.run(until: FoundationEssentials.Date) -> () + 156
frame #5: 0x0000aaaac2ec10f0 RunLoopHang`RunLoopHang_main at main.swift:3:17
frame #6: 0x0000ffff94c684c4 libc.so.6`___lldb_unnamed_symbol3097 + 116
frame #7: 0x0000ffff94c68598 libc.so.6`__libc_start_main + 152
frame #8: 0x0000aaaac2ec0cf0 RunLoopHang`_start + 48
thread #2, name = 'RunLoopHang', stop reason = signal SIGSTOP
frame #0: 0x0000ffff94d2bd74 libc.so.6`epoll_pwait + 148
frame #1: 0x0000ffff95efd024 libdispatch.so`_dispatch_event_loop_drain + 64
frame #2: 0x0000ffff95ef1fdc libdispatch.so`_dispatch_mgr_invoke + 124
frame #3: 0x0000ffff95ef1f50 libdispatch.so`_dispatch_mgr_thread + 132
frame #4: 0x0000ffff95ef578c libdispatch.so`_dispatch_worker_thread + 432
frame #5: 0x0000ffff94cc597c libc.so.6`___lldb_unnamed_symbol3477 + 892
frame #6: 0x0000ffff94d2ba4c libc.so.6`___lldb_unnamed_symbol3850 + 12
Docker version 27.4.0, build bde2b89
macOS 15.2
Works for me, although I'm using Orbstack:
❯ docker build -t dtest -f Dockerfile .
[+] Building 50.8s (12/12) FINISHED docker:orbstack
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 423B 0.0s
=> [internal] load metadata for docker.io/library/swift:latest 2.9s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [1/8] FROM docker.io/library/swift:latest@sha256:816ca4a42c1ab5e3993060f8e8bbc80cf88ac82d7ad52ded90b814ab79def8 42.8s
=> => resolve docker.io/library/swift:latest@sha256:816ca4a42c1ab5e3993060f8e8bbc80cf88ac82d7ad52ded90b814ab79def8a 0.0s
=> => sha256:816ca4a42c1ab5e3993060f8e8bbc80cf88ac82d7ad52ded90b814ab79def8ad 2.62kB / 2.62kB 0.0s
=> => sha256:f5e223ed75fc01e11b6ec5a2f8c337b51121f9eef06c4a50eace4ea873f9e47e 1.73kB / 1.73kB 0.0s
=> => sha256:69fba260c0ad349a57791f941bf88edee6c75fe0b8501a3de756656dae4e3703 5.72kB / 5.72kB 0.0s
=> => extracting da0a385c983f 8.7s
=> => extracting 8ef7323a9954 0.0s
=> [2/8] WORKDIR /workspace 0.3s
=> [3/8] RUN swift package init --name Example --type executable 0.4s
=> [4/8] RUN echo "import Foundation" > Sources/main.swift 0.1s
=> [5/8] RUN echo "print("BEGIN")" >> Sources/main.swift 0.1s
=> [6/8] RUN echo "RunLoop.current.run(until: Date(timeIntervalSinceNow: 1))" >> Sources/main.swift 0.1s
=> [7/8] RUN echo "print("END")" >> Sources/main.swift 0.1s
=> [8/8] RUN swift build 3.7s
=> exporting to image 0.1s
=> => exporting layers 0.1s
=> => writing image sha256:fb21e7005d8317e791011877d78e77a4019969d0bcc12fe87669da3577c5ed01 0.0s
=> => naming to docker.io/library/dtest 0.0s
~/Downloads took 51s
❯ docker run --rm dtest
BEGIN
END
System info:
❯ sw_vers
ProductName: macOS
ProductVersion: 15.2
BuildVersion: 24C101
Orbstack Version 1.9.2 (18814)
Say goodbye to slow, clunky containers and VMs. The fast, light, and easy way to run containers and Linux. Develop at lightspeed with our Docker Desktop alternative.
ileitch
December 26, 2024, 11:25am
3
Thanks for trying it. OrbStack is also working as expected for me. I'll report this to the Docker team.
1 Like
lukeh
(Luke Howard)
September 29, 2025, 5:44pm
4
I’m seeing this occasionally, Swift 6.2 on Linux.
It appears a similar issue was reported back in 2017 .
(lldb) p fds[0]
(pollfd) (fd = 25, events = 1, revents = 0)
where FD 25 is:
InfernoUI 196501 lukeh 25u a_inode 0,15 0 66 [eventpoll:8,24,26]
which as far as I can tell is an epoll(7) file descriptor which in turn references IDs 8, 24 and 26:
InfernoUI 196501 lukeh 8u a_inode 0,15 0 66 [eventfd:281]
InfernoUI 196501 lukeh 24u a_inode 0,15 0 66 [eventfd:210]
InfernoUI 196501 lukeh 26u a_inode 0,15 0 66 [timerfd]
AFAICT the poll FD and event FDs are created by __CFRunLoopCreate() and _dispatch_runloop_queue_handle_init(), and the timer FD by __CFRunLoopCopyMode().
Unfortunately we need to use CFRunLoop in order to guarantee that the main thread (in the pthread) sense is also the main actor / main dispatch thread, as some third-party libraries we are scheduling need to be called from this. (When using dispatch_main(), the first thread is suspended.)
Edit: I think this may have been a bug on our end, with an incorrect (too large) value passed to a CFTimer.