Always invoke binary reply callback when message handler throws#20
Merged
Merged
Conversation
If the FlutterBinaryMessageHandler throws, the reply callback was never called, leaving the Flutter engine's MallocMapping-owned message buffer permanently retained. This matches the pattern described in flutter/flutter#159363 where every unacknowledged platform message leaks ~96–192 bytes. Fix both FlutterPlatformMessenger (Darwin/iOS/Android) and FlutterDesktopMessenger (Linux/eLinux) to always call the reply with nil on error, so the engine can release the allocation regardless of handler outcome. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
FlutterPlatformMessenger.setMessageHandler(Darwin/iOS/Android) andFlutterDesktopMessenger.setMessageHandler(Linux/eLinux) both spawn aTaskto call the user-suppliedFlutterBinaryMessageHandler. If that handler throws, the task exits without ever calling the reply callback (FlutterBinaryReply/sendResponse).MallocMapping-owned message buffer until the reply callback is invoked. When it is never called, the buffer leaks permanently — one per unacknowledged message.oca/property_eventandoca/set_propertyplatform channels in InfernoUI (PADL/inferno_ui#52): 90 leaks (~3.7 KB) after 22 seconds of normal operation, growing without bound.Fix
Wrap the
try await handler(message)call in ado/catchin both messenger implementations and callcallback(nil)/sendResponse(..., response: nil)in the catch block, ensuring the reply is always delivered regardless of handler outcome.Test plan
leaks <pid>after 2+ hours of operation; confirm zero leaks attributed tooca/property_eventoroca/set_property🤖 Generated with Claude Code