Skip to content

Keep assistantd enabled: without it the simulator's Spotlight app leaks memory without bound - #59

Merged
Interlap01 merged 1 commit into
MobAI-App:mainfrom
Filsommer:fix/spotlight-dictation-leak
Oct 9, 2026
Merged

Interlap01 merged 1 commit into
MobAI-App:mainfrom
Filsommer:fix/spotlight-dictation-leak

Conversation

@Filsommer

Copy link
Copy Markdown
Contributor

Problem

On a fresh iOS 26.4 simulator slimmed with simslim on <udid> --except photos (simslim 0.11.0, iPhone 17 Pro, runtime 23E254a), the system Spotlight app (RuntimeRoot/Applications/Spotlight.app/Spotlight, which SpringBoard launches in the background at boot) grows without limit:

  • in the background, about 20-40 MB/s, starting about 15 s after boot;
  • in the foreground (xcrun simctl launch <udid> com.apple.Spotlight), about 115 MB/s;
  • we once saw a single simulator's Spotlight at 138 GB before anything stopped it.

A stock simulator on the same Mac stays flat at about 285-306 MB.

Repro

UDID=$(xcrun simctl create spot-repro com.apple.CoreSimulator.SimDeviceType.iPhone-17-Pro com.apple.CoreSimulator.SimRuntime.iOS-26-4)
simslim on $UDID --except photos          # offline slim, first boot is already slim
xcrun simctl launch $UDID com.apple.Spotlight
while sleep 2; do ps -axo rss=,command= | grep "Devices/$UDID" -m0; ps -axo pid=,rss=,command= | grep '[S]potlight.app/Spotlight'; done
# kill it before it eats the Mac: xcrun simctl terminate $UDID com.apple.Spotlight

What we measured. Peak RSS is in MB. Each run used a fresh device. "Background" is the 75 s after boot. "Foreground" is simctl launch plus 25 s.

Profile Background peak Foreground peak Loop log lines*
stock 285-300 (flat) 306 (flat) 0
--except photos 922-1042, then killed 1192 (17 → 1192 in 10 s) 38k-145k
--except photos,search (search kept) 1139 1191 127,162
--except photos,siri (siri kept) 298 301 0
--except photos --keep com.apple.assistantd 298 287 0
only com.apple.assistantd disabled (1/170) 882 1105 113,332
one stock boot first, then --except photos 302 303 0

* [com.apple.siri:Client] -[AFPreferences _languageCodeWithFallback:] No language code saved, but Assistant is enabled, from Spotlight's main thread, up to 2,300 lines/s.

Root cause

com.apple.assistantd is the only job that vends the com.apple.assistant.dictation mach service. Without it, Spotlight's main queue gets stuck in a loop. A 2 s sample of the leaking process shows all 1583/1583 main-thread samples inside this cycle:

  1. -[AFDictationConnection _tellSpeechDelegateAvailabilityChanged] fires.
  2. -[UIDictationController dictationConnnectionDidChangeAvailability:] posts a notification.
  3. Spotlight's search bar observers run: -[SPUISearchHeader updateDictationButtonEnabledStatus] and -[SPUISearchHeader enableDictationIfRequired].
  4. They synchronously re-query dictation availability, through -[UIKeyboardInputMode dictationLanguage], -[AFDictationConnection dictationIsAvailableForLanguage:synchronous:] and AFOfflineDictationLanguageForKeyboardLanguage into AFPreferences.
  5. That produces another availability-changed callback, and the cycle repeats.

The leak only happens when the device has never booted with assistantd running. That is the normal case for simslim on against a shutdown, never-booted device since the offline fast path (#49), because the very first boot is already slim. A device that booted stock once does not loop, even with assistantd disabled afterwards. This is probably why the bug went unnoticed.

The flood of Siri language errors is a symptom, not the cause. Seeding com.apple.assistant.backedup → Session Language removes the log lines, but Spotlight still reached 1183 MB.

The search category is not involved: keeping it enabled still leaks.

Stopping Spotlight.app is not a viable fix. It is a FrontBoard-launched app (UIKitApplication:com.apple.Spotlight[…]), not a launchd label. It comes back on pull-down search or on simctl launch.

Fix

Move com.apple.assistantd out of the siri category's Labels and into its AlwaysEnabled, the same mechanism #57 used for gamed and that sharingd uses:

  • No profile disables it any more.
  • It stays in the managed set, so running simslim on again re-enables it on devices slimmed by earlier versions.
  • verify reports it as extra drift until that happens.
  • simslim profiles siri explains why it is always on.

The other 28 Siri and Intelligence daemons are still slimmed.

Cost: assistantd measures about 22-23 MiB phys_footprint (simslim top) on iOS 26.4, on both stock and slim devices. The siri estimate (265 MB, measured on iOS 26.5) probably drops by about that much and should be remeasured. I left the number unchanged because I don't have a 26.5 runtime here.

Other changes:

  • service_descriptions.go: removed assistantd's description, which the coverage test requires once it is no longer a Label.
  • status_test.go and cmd/simslim/wizard_test.go: they used assistantd as "a siri label" and now use com.apple.assistant_cdmd.

Test

  • New TestAssistantdStaysEnabledForSpotlight, modelled on the gamed regression test. It checks that assistantd is not slimmable, that the siri category gives a reason for keeping it, that a legacy disabled assistantd gets re-enabled, and that the other Siri daemons stay slimmable. It fails on the current profile (3 assertions) and passes with the patch.

  • make check passes with Go 1.27.1 (go test, go vet, swift-format lint, zsh -n, plutil); gofmt is clean.

  • Built binary (go build ./cmd/simslim from this branch) vs the released 0.11.0, each on a fresh iPhone 17 Pro / iOS 26.4 device with simslim on <udid> --except photos, Spotlight forced to the foreground and sampled every 2 s for 60 s, same session:

    Spotlight RSS over 60 s loop log lines assistantd
    this branch flat at 305 MB 0 enabled
    0.11.0 679 → 1192 MB in ~6 s (then killed by our watchdog, relaunched, leaked again) 111,831 disabled
  • Earlier runs with the released binary and the equivalent --keep com.apple.assistantd:

    • Fresh device: Spotlight stays flat at 298 MB in the background and 287 MB in the foreground, with 0 loop log lines.
    • Legacy repair: a device that had leaked on two separate boots re-enabled just that one label (161/170) and then stayed flat at 280-308 MB, 289 MB in the foreground, with 0 loop log lines.

🤖 Generated with Claude Code

On a never-booted simulator slimmed offline, disabling com.apple.assistantd
(the only vendor of com.apple.assistant.dictation) makes Spotlight's search
header loop on dictation availability and leak memory without bound
(~20-115 MB/s). Keep it enabled via the siri category's AlwaysEnabled, like
gamed in MobAI-App#57; re-running `simslim on` repairs devices slimmed earlier.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Interlap01

Copy link
Copy Markdown
Contributor

Whoa, that's unexpected! Thanks for finding this, merging right away.

@Interlap01
Interlap01 merged commit 2830b5d into MobAI-App:main Oct 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants