Summary
My app crashed after a few minutes due to a memory leak, while open and idle on my iPad and laptop
Steps to reproduce
I do not know how to reproduce this yet in an isolated way.
Disabling .crashManager and .console during DebugSwift's setup fixed this for me.
Here is the analysis from Codex LLM, Sol, that I reviewed.
Expected behavior
Idle memory should stabilize, and stderr capture should not accumulate an unbounded number of pending dispatch blocks.
Actual behavior
After opening the app and then leaving it idle, memory continued growing
without any user interaction.
A 111-second Instruments capture reported:
- 126.26 MiB persistent heap and anonymous VM
- 2,704,061 persistent allocations
- 890,181 persistent 64-byte allocations (54.33 MiB)
- 892,073 persistent 48-byte allocations (40.84 MiB)
- 890,084 persistent unknown objects (27.20 MiB)
Representative 48-byte allocations appeared only microseconds apart and had
the following allocation stack:
closure #1 in StderrCapture.startCapturingInternal()
closure #1 in closure #1 in StderrCapture.startCapturingInternal()
_Block_copy
_malloc_type_malloc_outlined
No app interaction intervals occurred during the relevant idle period.
The debug session later ended with signal 9.
A separate Mac Catalyst Debug run also grew to 139.45 GB while idle, although
that process was not captured with an allocation trace, so its cause has not
been independently confirmed.
Affected version
rc-1.18.16
Platform
iPadOS 27 beta 4
Logs or stack trace
### DebugSwift version
rc-1.18.16
Commit: b66e92c625c8308a91082b9b53cc5af6d4035db7
### Environment
- Physical iPad Pro 11-inch (3rd generation)
- iPadOS 27 beta
- Instruments 27
- Debug build
- DebugSwift initialized with:
`.setup(disable: [.leaksDetector, .network, .webSocket])`
### Potential implementation concerns
StderrCapture's readability handler schedules work onto captureQueue before
`availableData` is consumed. Could repeated readability callbacks enqueue work
faster than captureQueue drains it?
StderrCapture also stores the numeric stderr file descriptor and later replaces
that descriptor with dup2. The stored value does not appear to be a duplicated,
separately owned reference to the original stderr destination.
These are hypotheses based on source inspection; the trace directly confirms
only that repeated retained allocations originate in
StderrCapture.startCapturingInternal().
Summary
My app crashed after a few minutes due to a memory leak, while open and idle on my iPad and laptop
Steps to reproduce
I do not know how to reproduce this yet in an isolated way.
Disabling
.crashManagerand.consoleduring DebugSwift's setup fixed this for me.Here is the analysis from Codex LLM, Sol, that I reviewed.
Expected behavior
Idle memory should stabilize, and stderr capture should not accumulate an unbounded number of pending dispatch blocks.
Actual behavior
After opening the app and then leaving it idle, memory continued growing
without any user interaction.
A 111-second Instruments capture reported:
Representative 48-byte allocations appeared only microseconds apart and had
the following allocation stack:
closure #1 in StderrCapture.startCapturingInternal()
closure #1 in closure #1 in StderrCapture.startCapturingInternal()
_Block_copy
_malloc_type_malloc_outlined
No app interaction intervals occurred during the relevant idle period.
The debug session later ended with signal 9.
A separate Mac Catalyst Debug run also grew to 139.45 GB while idle, although
that process was not captured with an allocation trace, so its cause has not
been independently confirmed.
Affected version
rc-1.18.16
Platform
iPadOS 27 beta 4
Logs or stack trace