dart-lang / dart-lang/native

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

Open
#1,505 0 comments 0 reactions 0 assignees View on GitHub
lang-objective_c package:ffigen
Dominant language
Dart
Stars
275
Forks
144
Avg merge
2d 10h
Merged PRs (30d)
47

Description

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 #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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.