Task-Debugging

Is there a way to debug the state of tasks?

I'd really love to have something like the memory debugger ­that I can use to show me leaks, only for async execution units. I.e. wouldn't it be helpful to see "hanging" continuations (streams), or to see which tasks are waiting to be scheduled next on the executor.

2 Likes

sudo swift inspect dump-concurrency <pid>

gives outputs like these:

sudo swift inspect dump-concurrency 58979
TASKS

      Task 0x1 - flags=future|running enqueuePriority=0x15 maxPriority=0x0 address=0x122e04640
        current task on thread 0xb01ee7
        waiting on thread: port=0x1907 id=0xb01ee7
        resume function: closure #4 in ClusterSystem.init(settings:) in SampleDiningPhilosophers
        task allocator: 46016 bytes in 14 chunks

      Task 0x4 - flags=future enqueuePriority=0x15 maxPriority=0x0 address=0x125009360
        async backtrace: withUnsafeContinuation<A>(_:)
                         closure #2 in AsyncStream._Storage.next()
                         partial apply for closure #2 in AsyncStream._Storage.next()
                         withTaskCancellationHandler<A>(operation:onCancel:)
                         withTaskCancellationHandler<A>(operation:onCancel:)
                         withTaskCancellationHandler<A>(handler:operation:)
                         AsyncStream._Storage.next()
                         implicit closure #2 in implicit closure #1 in AsyncStream.init(_:bufferingPolicy:_:)
                         partial apply for implicit closure #2 in implicit closure #1 in AsyncStream.init(_:bufferingPolicy:_:)
                         AsyncStream.Iterator.next()
                         ClusterEventStream.AsyncIterator.next()
                         closure #1 in OpLogDistributedReceptionist.init(settings:system:)
                         partial apply for closure #1 in OpLogDistributedReceptionist.init(settings:system:)
                         completeTaskWithClosure(swift::AsyncContext*, swift::SwiftError*)
        resume function: withUnsafeContinuation<A>(_:) in libswift_Concurrency.dylib
        task allocator: 5288 bytes in 8 chunks

ACTORS
  0x600003170010 Swift.MainActor state=idle flags=distributedRemote maxPriority=0xcd
    no jobs queued

  0x600000678480 DistributedCluster.ClusterControl.(MembershipHolder in _A40769ABF8C8C2BF1A954F963A45EF9B) state=idle flags=0 maxPriority=0x0
    no jobs queued

  0x122e05380 SampleDiningPhilosophers.Fork state=idle flags=0 maxPriority=0x0
    no jobs queued
...

  0x12482c000 DistributedCluster.SWIMActor state=idle flags=0 maxPriority=0x0
    no jobs queued

Discussion about bringing it to Linux here: [tool] Implement initial support for `swift-inspect` under Linux 64-bit by mikolasstuchlik · Pull Request #63576 · apple/swift · GitHub

9 Likes

Wow, that's more than I had hoped for. Will keep an eye on it, thanks @ktoso !

I lists both actors and tasks and their status.

We hope to keep working on this tool and improving its usefulness. Bringing it to linux would be an important step for that as well ofc.

Glad this helps

3 Likes