ios-chaos-monkey
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseiOS Chaos Monkey — Crash-Hunter Best Practices
iOS Chaos Monkey — 崩溃排查最佳实践
Adversarial crash-hunting guide for iOS and Swift applications. Contains 47 rules across 8 categories, prioritized by crash severity. Every rule follows TDD: dangerous code first, a failing test that proves the bug, then the fix that makes the test pass.
这是一份针对iOS和Swift应用的对抗式崩溃排查指南。包含8个分类下的47条规则,按崩溃严重程度排序。每条规则均遵循TDD流程:先展示危险代码,再给出可证明问题的失败测试,最后提供能让测试通过的修复方案。
When to Apply
适用场景
Reference these guidelines when:
- Hunting data races, deadlocks, and concurrency crashes in Swift
- Auditing memory management for retain cycles and use-after-free
- Reviewing async/await code for cancellation and continuation leaks
- Stress-testing file I/O and CoreData/SwiftData persistence layers
- Writing proof-of-crash tests before implementing fixes
在以下场景中可参考本指南:
- 排查Swift中的数据竞争、死锁及并发崩溃问题
- 审计内存管理,排查循环引用和野指针问题
- 检查async/await代码中的取消逻辑和续体泄漏问题
- 对文件I/O和CoreData/SwiftData持久化层进行压力测试
- 在实现修复前编写可复现崩溃的测试用例
Rule Categories by Priority
按优先级划分的规则分类
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Data Races & Thread Safety | CRITICAL | |
| 2 | Memory Corruption & Leaks | CRITICAL | |
| 3 | Deadlocks & Thread Starvation | HIGH | |
| 4 | Async/Await & Structured Concurrency | HIGH | |
| 5 | File I/O & Persistence Corruption | MEDIUM-HIGH | |
| 6 | Collection & State Mutation | MEDIUM | |
| 7 | Resource Exhaustion | MEDIUM | |
| 8 | Objective-C Interop Traps | LOW-MEDIUM | |
| 优先级 | 分类 | 影响等级 | 前缀 |
|---|---|---|---|
| 1 | 数据竞争与线程安全 | 严重(CRITICAL) | |
| 2 | 内存损坏与泄漏 | 严重(CRITICAL) | |
| 3 | 死锁与线程饥饿 | 高(HIGH) | |
| 4 | Async/Await与结构化并发 | 高(HIGH) | |
| 5 | 文件I/O与持久化损坏 | 中高(MEDIUM-HIGH) | |
| 6 | 集合与状态修改 | 中(MEDIUM) | |
| 7 | 资源耗尽 | 中(MEDIUM) | |
| 8 | Objective-C互操作陷阱 | 中低(LOW-MEDIUM) | |
Quick Reference
快速参考
1. Data Races & Thread Safety (CRITICAL)
1. 数据竞争与线程安全(严重)
- - Concurrent Dictionary mutation crashes with EXC_BAD_ACCESS
race-dictionary-concurrent-write - - Concurrent Array append corrupts internal buffer
race-array-concurrent-append - - Unsynchronized property read-write across threads
race-property-access - - Lazy property double-initialization under concurrency
race-lazy-initialization - - Non-atomic singleton exposes partially constructed state
race-singleton-initialization - - Non-atomic Bool flag creates check-then-act race
race-bool-flag - - Closure captures mutable reference across threads
race-closure-capture-mutation - - Delegate set to nil during active callback
race-delegate-nilification
- - 并发修改Dictionary会导致EXC_BAD_ACCESS崩溃
race-dictionary-concurrent-write - - 并发向Array添加元素会破坏内部缓冲区
race-array-concurrent-append - - 跨线程未同步的属性读写操作
race-property-access - - 并发场景下懒加载属性的重复初始化问题
race-lazy-initialization - - 非原子性单例暴露部分构造完成的状态
race-singleton-initialization - - 非原子性Bool标志引发的检查-执行竞争问题
race-bool-flag - - 闭包在跨线程场景下捕获可变引用
race-closure-capture-mutation - - 回调执行期间将Delegate设为nil
race-delegate-nilification
2. Memory Corruption & Leaks (CRITICAL)
2. 内存损坏与泄漏(严重)
- - Strong self capture in escaping closures creates retain cycle
mem-closure-retain-cycle - - Timer retains target creating undiscoverable retain cycle
mem-timer-retain-cycle - - Strong delegate reference prevents deallocation
mem-delegate-strong-reference - - Unowned reference crashes after owner deallocation
mem-unowned-crash - - NotificationCenter observer retains closure after removal needed
mem-notification-observer-leak - - Combine sink retains self without cancellable storage
mem-combine-sink-retain - - Task captures self extending lifetime beyond expected scope
mem-async-task-self-capture
- - 逃逸闭包中强引用self导致循环引用
mem-closure-retain-cycle - - Timer持有目标对象导致难以发现的循环引用
mem-timer-retain-cycle - - 强引用Delegate导致对象无法释放
mem-delegate-strong-reference - - 无主引用在宿主对象释放后引发崩溃
mem-unowned-crash - - NotificationCenter观察者未移除导致闭包泄漏
mem-notification-observer-leak - - Combine Sink强引用self且未存储取消句柄
mem-combine-sink-retain - - Task捕获self导致对象生命周期超出预期范围
mem-async-task-self-capture
3. Deadlocks & Thread Starvation (HIGH)
3. 死锁与线程饥饿(高)
- - DispatchQueue.main.sync from main thread deadlocks instantly
dead-sync-on-main - - Recursive lock acquisition on same serial queue
dead-recursive-lock - - Actor reentrancy produces unexpected interleaving
dead-actor-reentrancy - - Semaphore.wait() inside async context deadlocks thread pool
dead-semaphore-in-async - - Dispatch queue target hierarchy inversion deadlocks
dead-queue-hierarchy - - Blocking MainActor with synchronous heavy work
dead-mainactor-blocking
- - 在主线程调用DispatchQueue.main.sync会立即引发死锁
dead-sync-on-main - - 在同一串行队列上递归获取锁
dead-recursive-lock - - Actor重入导致意外的执行交错
dead-actor-reentrancy - - 在异步上下文调用Semaphore.wait()会导致线程池死锁
dead-semaphore-in-async - - 调度队列目标层级反转引发死锁
dead-queue-hierarchy - - 用同步重操作阻塞MainActor
dead-mainactor-blocking
4. Async/Await & Structured Concurrency (HIGH)
4. Async/Await与结构化并发(高)
- - Missing Task.isCancelled check wastes resources after navigation
async-missing-cancellation - - Detached task without cancellation handle leaks work
async-detached-task-leak - - TaskGroup silently drops child task errors
async-task-group-error - - CheckedContinuation never resumed leaks awaiting task
async-continuation-leak - - Excessive MainActor hops in hot loop starve UI updates
async-actor-hop-starvation - - @unchecked Sendable hides data race from compiler
async-unsafe-sendable
- - 缺少Task.isCancelled检查导致页面跳转后资源浪费
async-missing-cancellation - - 未持有取消句柄的Detached Task导致任务泄漏
async-detached-task-leak - - TaskGroup会静默丢弃子任务错误
async-task-group-error - - CheckedContinuation从未恢复导致等待任务泄漏
async-continuation-leak - - 热循环中过度切换MainActor导致UI更新停滞
async-actor-hop-starvation - - @unchecked Sendable会向编译器隐藏数据竞争问题
async-unsafe-sendable
5. File I/O & Persistence Corruption (MEDIUM-HIGH)
5. 文件I/O与持久化损坏(中高)
- - Concurrent file writes corrupt data without coordination
io-concurrent-file-write - - CoreData NSManagedObject accessed from wrong thread
io-coredata-cross-thread - - SwiftData model accessed from wrong ModelContext
io-swiftdata-background - - UserDefaults concurrent read-write produces stale values
io-plist-concurrent-mutation - - FileManager existence check then use is a TOCTOU race
io-filemanager-race - - Keychain access from multiple threads returns unexpected errors
io-keychain-thread-safety
- - 无协调的并发文件写入会导致数据损坏
io-concurrent-file-write - - 在错误线程访问CoreData的NSManagedObject
io-coredata-cross-thread - - 在错误的ModelContext中访问SwiftData模型
io-swiftdata-background - - UserDefaults的并发读写会产生过期值
io-plist-concurrent-mutation - - FileManager的存在性检查后使用存在TOCTOU竞争问题
io-filemanager-race - - 多线程访问Keychain会返回意外错误
io-keychain-thread-safety
6. Collection & State Mutation (MEDIUM)
6. 集合与状态修改(中)
- - Collection mutation during enumeration crashes at runtime
mut-enumerate-and-mutate - - KVO observer not removed before deallocation crashes
mut-kvo-dealloc-crash - - Array index access without bounds check crashes
mut-index-out-of-bounds - - Force unwrapping optional in production crashes on nil
mut-force-unwrap - - Non-exhaustive switch crashes on unknown enum case
mut-enum-future-cases
- - 枚举期间修改集合会在运行时崩溃
mut-enumerate-and-mutate - - 释放前未移除KVO观察者会引发崩溃
mut-kvo-dealloc-crash - - 未做边界检查的数组索引访问会崩溃
mut-index-out-of-bounds - - 生产环境中强制解包可选值会在nil时崩溃
mut-force-unwrap - - 非穷举switch会在遇到未知枚举case时崩溃
mut-enum-future-cases
7. Resource Exhaustion (MEDIUM)
7. 资源耗尽(中)
- - Unbounded task spawning in loop exhausts memory
exhaust-unbounded-task-spawn - - GCD creates unbounded threads under concurrent load
exhaust-thread-explosion - - URLSession not invalidated leaks delegate and connections
exhaust-urlsession-leak - - File handle not closed leaks file descriptors
exhaust-file-descriptor-leak - - Low memory warning ignored triggers Jetsam kill
exhaust-memory-warning-ignored
- - 循环中无限制创建任务会耗尽内存
exhaust-unbounded-task-spawn - - 并发负载下GCD会创建无限制线程
exhaust-thread-explosion - - URLSession未失效会导致代理和连接泄漏
exhaust-urlsession-leak - - 文件句柄未关闭会导致文件描述符泄漏
exhaust-file-descriptor-leak - - 忽略低内存警告会触发Jetsam终止
exhaust-memory-warning-ignored
8. Objective-C Interop Traps (LOW-MEDIUM)
8. Objective-C互操作陷阱(中低)
- - Missing @objc annotation crashes with unrecognized selector
objc-unrecognized-selector - - NSNull in decoded JSON collection crashes on access
objc-nsnull-in-json - - Swift/ObjC bridge type mismatch crashes at runtime
objc-bridge-type-mismatch - - Missing dynamic keyword breaks method swizzling
objc-dynamic-dispatch
- - 缺少@objc注解会引发未识别选择器崩溃
objc-unrecognized-selector - - 解码后的JSON集合中包含NSNull会在访问时崩溃
objc-nsnull-in-json - - Swift/ObjC桥接类型不匹配会在运行时崩溃
objc-bridge-type-mismatch - - 缺少dynamic关键字会破坏方法交换
objc-dynamic-dispatch
How to Use
使用方法
Read individual reference files for detailed explanations and code examples:
- Section definitions - Category structure and impact levels
- Rule template - Template for adding new rules
阅读单个参考文件获取详细说明和代码示例:
- 章节定义 - 分类结构与影响等级说明
- 规则模板 - 添加新规则的模板
Reference Files
参考文件
| File | Description |
|---|---|
| references/_sections.md | Category definitions and ordering |
| assets/templates/_template.md | Template for new rules |
| metadata.json | Version and reference information |
| 文件 | 描述 |
|---|---|
| references/_sections.md | 分类定义与排序规则 |
| assets/templates/_template.md | 新规则模板 |
| metadata.json | 版本与参考信息 |