Skip to content

[ffigen] Ref leak in very specific edge case in ObjC blocks #1505

Open
@liamappelbe

Description

@liamappelbe

ObjC blocks with ns_consumed arguments that are implemented using .listener(dartFunc) leak a reference to their consumed arguments, but only when invoked from Dart.

This is very specific because:

  • It's hard to even get one of these blocks, due to [ffigen] Parse ns_returns_retained and ns_consumed for blocks #1490. You have to write a dummy protocol with methods that consume arguments, which will codegen a block with the same signature (plus an extra void* arg).
  • Args marked explicitly with ns_consumed are rare.
  • Calling blocks defined in Dart from Dart is rare.

This edge case may become slightly more common when we allow protocol methods to be invoked, depending on how that is implemented. Then if you implement a method marked with ns_consumed as a .listener, and then invoke that method from Dart, it may leak a reference.

The reason this is tricky to fix is that all other code paths (ObjC invoking a Dart listener, Dart invoking an ObjC block) are counting the refs correctly, so if I insert a release or remove a retain, it will mess up the other code paths. I need to investigate more, but I don't want to delay other important fixes for this super niche edge case.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions