Repository navigation
Disable LLDB async mode to fix breakpoint race on Xcode 26.4+ - #184907
realmeylisdev wants to merge 2 commits into
Conversation
…#184254) Xcode 26.4's LLDB has a race condition where breakpoints randomly fail to rearm after firing, causing EXC_BAD_ACCESS crashes on DartWorker threads (~80% failure rate). This disables LLDB's async mode via SetAsync(False) so breakpoint events are processed sequentially, eliminating the race. This re-lands the approach from flutter#184768 (reverted in flutter#184868 due to test failures) with corrected tests that expect synchronous mode output ('location added to breakpoint' instead of 'Process X resuming'). Also removes the manual stop/continue workaround from flutter#184690 and the Xcode version dependency from the LLDB class, since SetAsync(False) is safe on all LLDB versions. Upstream bug: llvm/llvm-project#190956
There was a problem hiding this comment.
Code Review
This pull request removes the Xcode dependency from IOSCoreDeviceLauncher and LLDB, simplifying the initialization and breakpoint logic. It switches LLDB to synchronous mode using SetAsync(False) to address rearming issues and updates the process resumption detection to match breakpoint location additions. Feedback suggests refining the new resumption regex to be more specific and removing redundant blank lines in test files to maintain code cleanliness.
| /// to be added, which indicates the process is running. | ||
| /// | ||
| /// Example: (lldb) 1 location added to breakpoint 1 | ||
| static final _lldbProcessResuming = RegExp(r'location added to breakpoint'); |
There was a problem hiding this comment.
The regex _lldbProcessResuming has been updated to match location added to breakpoint. While this works as a signal that the attach sequence is progressing in synchronous mode, it is quite broad. If multiple breakpoints are ever used, this might match prematurely or multiple times. Consider if a more specific pattern (e.g., matching the specific breakpoint ID or function name) would be more robust for future-proofing.
|
|
||
| coreDeviceControl: fakeCoreDeviceControl, |
There was a problem hiding this comment.
The removal of the xcode parameter has left an unnecessary blank line (likely containing indentation whitespace). This pattern repeats throughout the file (e.g., lines 108, 137, 162, etc.). Removing these extra lines will improve code cleanliness and better align with dart format expectations.
| coreDeviceControl: fakeCoreDeviceControl, | |
| coreDeviceControl: fakeCoreDeviceControl, |
References
- Optimize for readability: Code is read more often than it is written. (link)
- Make _lldbProcessResuming regex more specific (\d+ location added to breakpoint \d+) to match the specificity already used in _ignorePatterns - Remove 20 stray blank lines in core_devices_test.dart left from xcode parameter removal
|
Thank you for the contribution. This issue has already been fixed in #184970. |
Summary
Re-lands the
SetAsync(False)fix for the LLDB breakpoint race condition on Xcode 26.4+ that causesEXC_BAD_ACCESScrashes on DartWorker threads (~80% failure rate on USB debug launches).Xcodeversion dependency from theLLDBclass sinceSetAsync(False)is safe on all versions_lldbProcessResumingpattern to match synchronous mode output (location added to breakpointinstead ofProcess X resuming)Root cause (confirmed by @mraleph): Xcode 26.4's LLDB randomly fails to rearm the scripted breakpoint on
NOTIFY_DEBUGGER_ABOUT_RX_PAGESafter it fires. Upstream bug: llvm/llvm-project#190956Fixes #184254
Files changed
lldb.dartSetAsync(False), revert to simple log forwarding, update resume patterncore_devices.dartxcodeparam fromIOSCoreDeviceLauncherxcdevice.dartxcodearg fromIOSCoreDeviceLauncher()calllldb_test.dartSetAsync(False)verification, remove obsolete testscore_devices_test.dartxcode: FakeXcode()from all launcher callsTest plan
dart analyzeclean on all modified filesflutter runlaunches on physical iOS device via USB with Xcode 26.4