anthropics / anthropics/claude-code

iOS Simulator panel crash-loops on macOS 27 beta: seatbelt profile denies Metal's new cache-dir writes

Đang mở
#88,504 3 bình luận 1 reaction 0 người được giao Xem trên GitHub
area:sandbox bug has repro platform:macos
Ngôn ngữ chính
Python
Star
145k
Fork
23.1k
Chỉ số merge pull request
Chỉ số pull request đang chờ

Mô tả

## 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.

Hướng dẫn đóng góp

Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
macos, swift
Lĩnh vực
desktop, operating-systems, security
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Đặc tả rõ ràng
Mức phù hợp với người mới
74/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.