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

lldb: Unable to bind generic parameters in context with weakly captured self #9194

Open
mikolasstuchlik opened this issue Aug 29, 2024 · 0 comments

Comments

@mikolasstuchlik
Copy link

mikolasstuchlik commented Aug 29, 2024

This issue was originally observed in codebase with async sequence, but I strongly suspect this was the underlying issue.

LLDB seems to be unable to bind generic variables, when suspended in weakly captured context. See example code below.

LLDB version

This example was tested using Xcode toolchain in both Xcode and VSCode:

(lldb) version
lldb-1500.0.404.7
Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)

Behavior

For context, where self was captured either strongly or as unowned, following expression will be evaluated successfully, referencing example 3, 4 and 5:

(lldb) e -- T.self
(Int.Type) $R0 = Int

However, example 1 results in following output:

(lldb) e -- T.self
error: <EXPR>:2:43: error: cannot find type '$__lldb_context' in scope
extension Swift.Optional where Wrapped == $__lldb_context {
                                          ^~~~~~~~~~~~~~~

error: <EXPR>:19:27: error: instance method '$__lldb_user_expr_0' requires the types 'Bridge<Int>' and '<<error type>>' be equivalent
    $__lldb_injected_self.$__lldb_user_expr_0(
                          ^

<EXPR>:4:17: note: where 'Wrapped' = 'Bridge<Int>'
  mutating func $__lldb_user_expr_0(_ $__lldb_arg : UnsafeMutablePointer<Any>) {
                ^

Meanwhile, example 2 produces slightly different output:

(lldb) e -- T.self
error: Expression evaluation failed. Retrying without binding generic parameters
error: Could not evaluate the expression without binding generic types.

Notice, that for examples 1 and 2 any expression calls (even interpretable expressions like e -- 1 + 1) end in errors described above.

Example code

import Dispatch

final class Bridge<T> {
    var current: T

    init(c: T) { current = c }

    func foo() {
        // does not work
        DispatchQueue.global(qos: .userInitiated).async { [weak self] in
            print(self?.current) // example 1
        }
        Task { [weak self] in
            print(self?.current) // example 2
        }

        // works
        DispatchQueue.global(qos: .userInitiated).async {
            print(self.current) // example 3
        }
        Task {
            print(self.current) // example 4
        }
        
        // also works
        Task { [unowned self] in
            print(self.current) // example 5
        }
    } 
}
let a = Bridge(c: 1)
a.foo()

readLine()
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