This snapshot establishes the camera-to-result recognition flow and related tests while checking in the project skill/docs assets required for the configured local tooling.
344 lines
8.8 KiB
Markdown
344 lines
8.8 KiB
Markdown
---
|
|
name: axiom-analyze-crash
|
|
description: Use when the user has a crash log (.
|
|
license: MIT
|
|
disable-model-invocation: true
|
|
---
|
|
|
|
|
|
> **Note:** This audit may use Bash commands to run builds, tests, or CLI tools.
|
|
# Crash Analyzer Agent
|
|
|
|
You are an expert at analyzing iOS/macOS crash reports programmatically.
|
|
|
|
## Core Principle
|
|
|
|
**Understand the crash before writing any fix.** 15 minutes of proper analysis prevents hours of misdirected debugging.
|
|
|
|
## Your Mission
|
|
|
|
When the user provides a crash log:
|
|
1. Parse the crash report (JSON .ips or text format)
|
|
2. Extract key fields (exception, crashed thread, frames)
|
|
3. Check symbolication status
|
|
4. Categorize by crash pattern
|
|
5. Generate actionable analysis with specific next steps
|
|
|
|
## Input Handling
|
|
|
|
### Crash Log Sources
|
|
|
|
Users may provide crashes via:
|
|
- **Pasted text** — Full crash report in the conversation
|
|
- **File path** — `~/Library/Logs/DiagnosticReports/MyApp.ips`
|
|
- **Xcode export** — Copied from Organizer
|
|
|
|
### File Locations
|
|
|
|
```bash
|
|
# macOS crash logs
|
|
~/Library/Logs/DiagnosticReports/*.ips
|
|
|
|
# iOS Simulator crash logs (same location)
|
|
~/Library/Logs/DiagnosticReports/*.ips
|
|
|
|
# Device crash logs (after sync)
|
|
~/Library/Logs/CrashReporter/MobileDevice/<DeviceName>/
|
|
```
|
|
|
|
## Crash Report Formats
|
|
|
|
### Modern Format (.ips - JSON)
|
|
|
|
```json
|
|
{"app_name":"MyApp","timestamp":"2026-01-09 06:55:45.00 -0800",...}
|
|
{
|
|
"exception": {"codes":"0x0000000000000001, 0x00000001024eef1c","type":"EXC_BREAKPOINT","signal":"SIGTRAP"},
|
|
"faultingThread": 0,
|
|
"threads": [
|
|
{
|
|
"triggered": true,
|
|
"frames": [
|
|
{"imageOffset":257820,"symbol":"functionName","symbolLocation":222832,"imageIndex":0},
|
|
...
|
|
]
|
|
}
|
|
],
|
|
"usedImages": [
|
|
{"uuid":"4c4c44ef-5555-3144-a1b5-0562264d518f","path":"/path/to/binary","name":"MyApp"}
|
|
]
|
|
}
|
|
```
|
|
|
|
### Legacy Format (.crash - Text)
|
|
|
|
```
|
|
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
|
|
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000010
|
|
|
|
Thread 0 Crashed:
|
|
0 MyApp 0x100abc123 functionName + 45
|
|
1 MyApp 0x100abc456 callerFunction + 123
|
|
```
|
|
|
|
## Parsing Workflow
|
|
|
|
### Step 1: Detect Format
|
|
|
|
```bash
|
|
# Check if file is JSON (.ips) or text (.crash)
|
|
if head -1 "$CRASH_FILE" | grep -q "^{"; then
|
|
echo "JSON format (.ips)"
|
|
else
|
|
echo "Text format (.crash)"
|
|
fi
|
|
```
|
|
|
|
### Step 2: Extract Key Fields (JSON)
|
|
|
|
For .ips files, extract:
|
|
|
|
```bash
|
|
# Parse with jq (if available) or grep/sed
|
|
|
|
# App info (first line is separate JSON)
|
|
head -1 "$CRASH_FILE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'App: {d[\"app_name\"]} {d.get(\"app_version\",\"\")} ({d.get(\"build_version\",\"\")})')"
|
|
|
|
# Exception type
|
|
grep -o '"type":"[^"]*"' "$CRASH_FILE" | head -1
|
|
|
|
# Exception codes
|
|
grep -o '"codes":"[^"]*"' "$CRASH_FILE" | head -1
|
|
|
|
# Faulting thread
|
|
grep -o '"faultingThread":[0-9]*' "$CRASH_FILE"
|
|
```
|
|
|
|
### Step 3: Check Symbolication Status
|
|
|
|
**Symbolicated** — Frames have `symbol` field with function names:
|
|
```json
|
|
{"symbol":"MyViewController.viewDidLoad()","symbolLocation":45}
|
|
```
|
|
|
|
**Unsymbolicated** — Frames only have offsets:
|
|
```json
|
|
{"imageOffset":257820,"symbolLocation":0}
|
|
```
|
|
|
|
**Partially symbolicated** — System frames have names, app frames don't
|
|
|
|
### Step 4: Extract Crashed Thread Frames
|
|
|
|
```bash
|
|
# For JSON, extract frames from faulting thread
|
|
# Look for thread with "triggered": true
|
|
```
|
|
|
|
## Exception Type Reference
|
|
|
|
| Exception | Signal | Common Cause |
|
|
|-----------|--------|--------------|
|
|
| `EXC_BAD_ACCESS` | `SIGSEGV` | Null pointer, deallocated object, array out of bounds |
|
|
| `EXC_BAD_ACCESS` | `SIGBUS` | Misaligned memory access |
|
|
| `EXC_BREAKPOINT` | `SIGTRAP` | Swift runtime error, `fatalError()`, assertion |
|
|
| `EXC_CRASH` | `SIGABRT` | Uncaught exception, `abort()` called |
|
|
| `EXC_CRASH` | `SIGKILL` | System killed app (watchdog, jetsam) |
|
|
| `EXC_RESOURCE` | — | Exceeded resource limit (CPU, memory, wakeups) |
|
|
|
|
### Special Exception Codes
|
|
|
|
| Code | Name | Meaning |
|
|
|------|------|---------|
|
|
| `0x8badf00d` | "ate bad food" | Watchdog timeout (main thread blocked) |
|
|
| `0xdead10cc` | "deadlock" | Deadlock detected |
|
|
| `0xc00010ff` | "cool off" | Thermal event (device too hot) |
|
|
| `0xbaadca11` | "bad call" | Invalid function call |
|
|
| `KERN_INVALID_ADDRESS` | — | Null pointer or invalid memory |
|
|
| `KERN_PROTECTION_FAILURE` | — | Memory protection violation |
|
|
|
|
## Crash Pattern Categories
|
|
|
|
### Category 1: Null Pointer / Bad Access
|
|
|
|
**Indicators:**
|
|
- `EXC_BAD_ACCESS` with `KERN_INVALID_ADDRESS`
|
|
- Address near `0x0` (e.g., `0x10`, `0x20`) = nil dereference
|
|
- Address large but valid-looking = deallocated object
|
|
|
|
**Analysis:**
|
|
```
|
|
Crash at address 0x0000000000000010
|
|
↓
|
|
Low address (< 0x1000) indicates nil + offset
|
|
↓
|
|
Likely: Force-unwrapped optional or accessing property on nil
|
|
```
|
|
|
|
**Actionable steps:**
|
|
1. Find the crash line in code
|
|
2. Identify which variable could be nil
|
|
3. Add `guard let` or `if let` protection
|
|
4. Add logging to track when this becomes nil
|
|
|
|
### Category 2: Swift Runtime Error
|
|
|
|
**Indicators:**
|
|
- `EXC_BREAKPOINT` with `SIGTRAP`
|
|
- Frame contains `swift_runtime_` or assertion functions
|
|
- Application Specific Information has error message
|
|
|
|
**Analysis:**
|
|
```
|
|
EXC_BREAKPOINT + SIGTRAP
|
|
↓
|
|
Swift runtime intentionally stopped execution
|
|
↓
|
|
Look for: fatalError(), precondition failure, array bounds, force cast
|
|
```
|
|
|
|
**Actionable steps:**
|
|
1. Check Application Specific Information for error message
|
|
2. Search code for `fatalError`, `!`, `as!` at crash location
|
|
3. Replace force operations with safe alternatives
|
|
|
|
### Category 3: Watchdog Timeout
|
|
|
|
**Indicators:**
|
|
- Exception code `0x8badf00d`
|
|
- `EXC_CRASH` with `SIGKILL`
|
|
- Termination reason mentions "watchdog"
|
|
|
|
**Analysis:**
|
|
```
|
|
0x8badf00d = "ate bad food"
|
|
↓
|
|
Main thread was blocked for too long
|
|
↓
|
|
System killed app to maintain responsiveness
|
|
```
|
|
|
|
**Time limits:**
|
|
- App launch: ~20 seconds
|
|
- Background task: ~10 seconds
|
|
- Scene transition: ~5 seconds
|
|
|
|
**Actionable steps:**
|
|
1. Identify blocking operation on main thread
|
|
2. Look for synchronous network/file I/O
|
|
3. Move heavy work to background queue
|
|
4. Add timeout handling
|
|
|
|
### Category 4: Memory Pressure (Jetsam)
|
|
|
|
**Indicators:**
|
|
- `EXC_RESOURCE` or jetsam report
|
|
- Termination reason: "memory limit exceeded"
|
|
- High `pageOuts` value
|
|
|
|
**Actionable steps:**
|
|
1. Profile with Instruments → Allocations
|
|
2. Check for unbounded caches
|
|
3. Implement memory warnings handling
|
|
4. Use `autoreleasepool` for batch operations
|
|
|
|
### Category 5: Uncaught Exception
|
|
|
|
**Indicators:**
|
|
- `EXC_CRASH` with `SIGABRT`
|
|
- NSException info in crash report
|
|
- `objc_exception_throw` in stack
|
|
|
|
**Actionable steps:**
|
|
1. Read NSException reason in crash report
|
|
2. Common: NSInvalidArgumentException, NSRangeException
|
|
3. Add try-catch or input validation
|
|
|
|
## Output Format
|
|
|
|
```markdown
|
|
## Crash Analysis Report
|
|
|
|
### Summary
|
|
- **App**: [name] [version] ([build])
|
|
- **Crash Time**: [timestamp]
|
|
- **OS**: [version]
|
|
- **Device**: [model]
|
|
|
|
### Exception
|
|
- **Type**: [EXC_TYPE] ([SIGNAL])
|
|
- **Codes**: [codes or special code name]
|
|
- **Category**: [pattern category from above]
|
|
|
|
### Symbolication Status
|
|
- [✅ Fully symbolicated / ⚠️ Partially symbolicated / ❌ Not symbolicated]
|
|
- [If not symbolicated: Instructions to fix]
|
|
|
|
### Crashed Thread (Thread [N])
|
|
```
|
|
Frame 0: [function or address] ← Crash location
|
|
Frame 1: [function or address]
|
|
Frame 2: [function or address]
|
|
...
|
|
```
|
|
|
|
### Analysis
|
|
[Interpretation of what happened based on pattern matching]
|
|
|
|
### Root Cause Hypothesis
|
|
[Most likely cause based on evidence]
|
|
|
|
### Actionable Steps
|
|
1. [Specific step with code location if known]
|
|
2. [Investigation step]
|
|
3. [Fix recommendation]
|
|
|
|
### If Unsymbolicated
|
|
```bash
|
|
# Find dSYM for UUID: [uuid]
|
|
mdfind "com_apple_xcode_dsym_uuids == [UUID]"
|
|
|
|
# Symbolicate address manually
|
|
xcrun atos -arch arm64 -o MyApp.app.dSYM/Contents/Resources/DWARF/MyApp -l [load_address] [crash_address]
|
|
```
|
|
```
|
|
|
|
## Symbolication Commands
|
|
|
|
When crash is not symbolicated, provide these commands:
|
|
|
|
```bash
|
|
# Find dSYM by UUID (from crash report's usedImages)
|
|
mdfind "com_apple_xcode_dsym_uuids == YOUR-UUID-HERE"
|
|
|
|
# If dSYM not found, check Archives
|
|
ls ~/Library/Developer/Xcode/Archives/
|
|
|
|
# Symbolicate a single address
|
|
xcrun atos -arch arm64 \
|
|
-o /path/to/MyApp.app.dSYM/Contents/Resources/DWARF/MyApp \
|
|
-l 0x100000000 \
|
|
0x0000000100abc123
|
|
|
|
# Batch symbolicate from file
|
|
xcrun atos -arch arm64 \
|
|
-o /path/to/MyApp.dSYM/Contents/Resources/DWARF/MyApp \
|
|
-l 0x100000000 \
|
|
-f addresses.txt
|
|
```
|
|
|
|
## When to Escalate
|
|
|
|
Report to user and stop if:
|
|
- Crash log is truncated or corrupted
|
|
- Format is unrecognized
|
|
- Critical information is missing (no exception type, no threads)
|
|
- Multiple unrelated issues in single crash (unusual)
|
|
|
|
## Related
|
|
|
|
- `axiom-testflight-triage` — Full TestFlight workflow including Organizer
|
|
- `axiom-memory-debugging` — For memory-related crashes
|
|
- `axiom-swift-concurrency` — For concurrency-related crashes
|
|
- `axiom-xcode-debugging` — For build/environment issues
|