anthropics / anthropics/claude-code
iOS Simulator panel crash-loops on macOS 27 beta: seatbelt profile denies Metal's new cache-dir writes
- 主要语言
- Python
- 星标
- 145k
- 派生
- 23.1k
- PR 合并指标
- PR 指标待抓取
描述
## Environment
- Claude desktop app **1.34493.1** (macOS), iOS Simulator panel (`claude-ios-sim` helper)
- **macOS 27.0 beta (26A5416b)**, Apple Silicon
- Xcode 26.6 release selected (`xcode-select`), iOS 26.0 simulator runtime booted
## Summary
On macOS 27 beta 26A5416b, the Claude Code iOS Simulator panel crashes within seconds of every attach — the sidecar exits, the supervisor relaunches it, and after a few cycles it gives up ("stopped retrying after repeated crashes"). The crash is an uncaught `NSInvalidArgumentException` inside Metal while CoreImage initializes, and the root cause is an interaction between the helper's seatbelt profile (`Claude.app/Contents/Resources/claude-ios-sim.sb`) and new Metal behavior in this macOS beta.
## Crash signature
Every `.ips` for `claude-ios-sim` shows the same last-exception backtrace:
```
*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[0]
CoreFoundation -[__NSPlaceholderArray initWithObjects:count:]
CoreFoundation +[NSArray arrayWithObjects:count:]
Metal __39-[_MTLDevice recordBinaryArchiveUsage:]_block_invoke
libdispatch _dispatch_once_callout
Metal -[_MTLDevice recordBinaryArchiveUsage:]
Metal -[_MTLBinaryArchive loadFromURL:error:]
Metal -[_MTLBinaryArchive initWithOptions:device:url:error:]
CoreImage +[CIKernelLibrary(Internal) internalBinaryArchiveWithName:device:]
CoreImage CI::PrecompiledUberFunctions::PrecompiledUberFunctions(CI::MetalContext const*)
```
It fires the moment the frame stream opens (first CoreImage/Metal context in the helper).
## Root cause
On 26A5416b, Metal's `recordBinaryArchiveUsage:` **writes usage data under `DARWIN_USER_CACHE_DIR`** (`/var/folders/.../C/`) when CoreImage loads its precompiled kernel archive. The seatbelt profile only allows writes to the CoreSimulator dirs, `DARWIN_TMP`, and `/private/var/tmp` — the user cache dir is denied. The denied handle surfaces as a `nil` in an `NSArray` literal inside the `dispatch_once` block, and the helper aborts.
Verified by bisection with a minimal repro:
```swift
// ci_repro.swift — crashes under the profile, renders fine without it
import CoreImage
import Metal
let dev = MTLCreateSystemDefaultDevice()!
let ctx = CIContext(mtlDevice: dev)
let img = CIImage(color: .red).cropped(to: CGRect(x: 0, y: 0, width: 8, height: 8))
_ = ctx.createCGImage(img, from: img.extent)
print("CI+Metal render OK")
```
- Run plain: **renders OK**.
- Run via `sandbox-exec -f claude-ios-sim.sb` (same `-D` params the app passes, binary placed inside `HELPER_BUNDLE` so `process-exec` allows it): **crashes with the exact signature above**.
- Same sandboxed run with one appended rule — `(allow file-write* (subpath ""))` — **renders OK**.
Narrower candidates were tested and do *not* fix it (so it's the cache-dir write, not a read): allowing full `$HOME` `file-read-data` doesn't help; `CI_USE_SOFTWARE_RENDERER=1` doesn't help (the helper creates its `CIContext` with an explicit Metal device).
## Suggested fix
Add the user cache directory to the profile's write allow-list, e.g.:
```scheme
;; macOS 27 beta: Metal records binary-archive usage under the user cache dir
(allow file-write* (subpath (param "DARWIN_CACHE")))
```
with `DARWIN_CACHE` resolved from `confstr(_CS_DARWIN_USER_CACHE_DIR)` alongside the existing `DARWIN_TMP` param in the sidecar spawn code. Cache-dir scratch seems consistent with the profile's stated intent ("CoreSimulator device state and scratch only").
## Notes for triage
- The failure is invisible in the app UI beyond generic "sidecar exited (code=134)" / crash-loop messages; the `.ips` files carry the signature.
- A second, related trap found while investigating: the profile's `process-exec` allow-list (helper bundle, `/usr/bin`, `/usr/libexec`, Xcode, `/Library/Developer`) means an exec of `/bin/zsh` etc. exits 71 with **no crash log at all** — worth a clearer supervisor message distinguishing "exec denied" from a real crash.
- Local workaround applied on this machine: the one-line profile addition above (byte-exact original preserved). Happy to test a fixed build.
贡献指南
这个仓库没有索引到贡献指南
调研方向
Start with Claude.app/Contents/Resources/claude-ios-sim.sb and the sidecar spawn code that supplies DARWIN_TMP; compare the existing sandbox parameters with confstr(_CS_DARWIN_USER_CACHE_DIR). Run ci_repro.swift under the profile, then verify the helper renders without crashing and the iOS Simulator panel no longer enters its crash loop.
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- macos, swift
- 领域
- desktop, operating-systems, security
- Issue 类型
- 缺陷
- 难度
- 3/5
- 预计耗时
- 1-2 天
- 活跃度
- 活跃
- 描述清晰度
- 描述清楚
- 新手友好度
- 74/100