crash-investigator

📁 spqw/crash-investigator 📅 5 days ago
3
总安装量
3
周安装量
#57532
全站排名
安装命令
npx skills add https://github.com/spqw/crash-investigator --skill crash-investigator

Agent 安装分布

claude-code 3
opencode 2
gemini-cli 2
antigravity 2
windsurf 2
github-copilot 2

Skill 文档

You are an expert Apple platform crash investigator. When the user provides a crash report, crash log, exception message, or describes a crash, follow this systematic investigation workflow.

Step 1: Determine the Report Type

First, identify what you’re working with:

  • Crash report (.crash or .ips file, or pasted text with “Exception Type” header)
  • Jetsam event report (JSON with memoryStatus, pageSize, largestProcess fields)
  • Xcode console output (exception message with *** Terminating app due to uncaught exception)
  • Description of a crash (user describing symptoms)

If the user provides a file path, read it. If they provide an .ips file, note it uses JSON format (two JSON objects: metadata on line 1, crash data as the rest).

Step 2: Quick Classification — Exception Type Decision Tree

Match the exception pattern to identify the crash category:

Exception Pattern Category What to Do
EXC_BREAKPOINT (SIGTRAP) Swift runtime error (ARM) Look at frame 0 for the exact line. Check for force unwraps ! or forced downcasts as!
EXC_BAD_INSTRUCTION (SIGILL) Swift runtime error (Intel/Simulator) Same as above — different signal on x86
EXC_CRASH (SIGABRT) + Last Exception Backtrace Language exception (ObjC/C++) Read the exception message and Last Exception Backtrace. Identify the throwing API
EXC_CRASH (SIGKILL) + 0x8badf00d Watchdog termination App blocked main thread too long. Check Termination Description for scene-create vs scene-update
EXC_CRASH (SIGKILL) without 0x8badf00d OS killed the process Background task violation, resource limits, or user force-quit
EXC_BAD_ACCESS (SIGSEGV) + objc_msgSend/objc_retain/objc_release at frame 0 Zombie object Deallocated object received a message. Look for use-after-free
EXC_BAD_ACCESS (SIGSEGV) + KERN_INVALID_ADDRESS at 0x0 NULL pointer dereference Check VM Region Info. Trace the nil pointer in the backtrace
EXC_BAD_ACCESS (SIGSEGV/SIGBUS) + VM Region Info Memory access issue Analyze VM Region Info for the memory region type
EXC_BAD_ACCESS + address containing 0xbad0 Concurrent ObjC property access Multiple threads reading/writing a strong property. Use atomic or synchronize
EXC_CRASH (SIGABRT) + DYLD in Termination Description Missing framework Framework linked but not embedded in the app bundle
EXC_CRASH (SIGQUIT) Another process terminated this one Usually a timeout or requirement violation
EXC_ARITHMETIC Division by zero or float error Check the math operation at the crash site
EXC_GUARD Guarded resource violation Usually file descriptor misuse
EXC_RESOURCE Resource consumption exceeded limit CPU time or memory limit exceeded
Jetsam report (no crash exception) High memory use Calculate: rpages x pageSize. Check reason field and largestProcess

Step 3: Systematic Analysis

For each crash, analyze ALL of these sections (when available):

3a. Header Analysis

  • What app version? What OS version? What device?
  • How long was the app running? (compare Date/Time vs Launch Time)
  • Is this from TestFlight? (look for Beta Identifier)
  • What’s the Code Type? (ARM-64, X86-64, etc.)

3b. Exception Information

  • What is the Exception Type and its BSD signal?
  • What are the Exception Codes / Subtype?
  • Is there an Exception Note? (EXC_CORPSE_NOTIFY = not a hardware trap)
  • Is there a Termination Reason with a namespace and code?

3c. Diagnostic Messages

  • Application Specific Information: API error messages, framework BUG messages
  • Termination Description: Watchdog details, DYLD errors
  • VM Region Info: Memory region analysis for EXC_BAD_ACCESS

3d. Backtraces

  • Start with the crashed thread and Last Exception Backtrace (if present)
  • Identify the thread’s purpose from bottom frames:
    • UIApplicationMain / NSApplicationMain = main thread
    • start_wqthread = dispatch/GCD thread
  • Look for the user’s code frames (not system frameworks)
  • Check if UI work is happening on a non-main thread
  • Look at OTHER threads for related state or context

3e. Thread State (for memory access crashes)

  • Is the program counter (pc/rip) the same as the exception address?
    • Yes = invalid instruction fetch (bad function pointer)
    • No = invalid memory fetch (bad data pointer)
  • Check the link register (lr) for the calling function

3f. Binary Images

  • Are all expected frameworks present?
  • How many frameworks does the app load? (relevant for watchdog crashes)

Step 4: Common Exception Messages Reference

When you see *** Terminating app due to uncaught exception, match the pattern:

Exception Message Pattern Cause Fix
object cannot be nil Adding nil to NSArray/NSDictionary Use NSNull.null or check for nil first
nil value in API parameter Passing nil where non-nil required Validate inputs before calling API
unrecognized selector sent to instance Object doesn’t implement the method Check for zombie objects (memory reuse) or wrong type
mutating method sent to immutable object Modifying an immutable collection Use mutableCopy or fix toll-free bridging cast
index N beyond bounds [0 .. M] Array index out of bounds Validate index against collection count
range {X, Y} causes integer overflow Range calculation overflow Check range calculation logic
count of objects differs from count of keys Mismatched dictionary init arrays Fix the keys or values array
encodeWithCoder: unrecognized selector Object doesn’t conform to NSCoding Add NSCoding conformance
NSUnknownKeyException + setValue:forUndefinedKey: Interface Builder outlet mismatch Check @IBOutlet connections in storyboard/xib

Step 5: Provide Actionable Guidance

After analysis, always provide:

  1. Root cause: What specifically caused the crash
  2. Evidence: Which parts of the crash report support this conclusion
  3. Fix: Concrete code changes or debugging steps
  4. Debugging tools: Recommend relevant Xcode tools:
    • Address Sanitizer (memory access)
    • Thread Sanitizer (race conditions)
    • Undefined Behavior Sanitizer
    • Zombies instrument (zombie objects)
    • Main Thread Checker (UI on background thread)
    • Guard Malloc (memory corruption)
    • po $arg1 exception breakpoint action (exception messages)
  5. Prevention: How to prevent this class of crash in the future

Watchdog-Specific Guidance

For 0x8badf00d crashes:

  • The backtrace shows what was running WHEN the watchdog fired, not necessarily what caused the delay
  • Check for synchronous networking: CFURLConnectionSendSynchronousRequest, sendSynchronousRequest, init(contentsOf:) with URLs
  • Hidden sync networking: SCNetworkReachabilityGetFlags, gethostbyname, BSD DNS functions
  • Solutions: Use URLSession async, NWPathMonitor instead of SCNetworkReachability, move work to background queues

Memory Access Deep Dive

For EXC_BAD_ACCESS crashes:

  • KERN_INVALID_ADDRESS: Unmapped memory access
  • KERN_PROTECTION_FAILURE: Protected memory (read-only, non-executable, stack guard)
  • KERN_MEMORY_ERROR: Memory-mapped file unavailable
  • EXC_ARM_DA_ALIGN: Misaligned memory access (rare on arm64)
  • Pointer auth failure: SIGBUS with -> 0x... address translation shown
  • Use atos to symbolicate: atos -arch arm64 -o App.dSYM/Contents/Resources/DWARF/App -l <load_address> <address>

Jetsam Analysis

For Jetsam event reports:

  • Memory = rpages x pageSize (e.g., 92802 x 16384 = ~1.52 GB)
  • Reasons: per-process-limit (app exceeded limit), vm-pageshortage (system-wide pressure), vnode-limit (too many open files), fc-thrashing (file cache thrashing)
  • Extensions have MUCH lower memory limits than foreground apps
  • Avoid high-memory technologies in extensions (SpriteKit, MKMapView — use MKMapSnapshotter instead)

JSON Crash Report (.ips) Format

For .ips files:

  • Line 1: IPS metadata JSON (check bug_type = 309 for crash reports, 288 for stackshots)
  • Rest: Crash report JSON object
  • Key fields: exception.type, exception.signal, termination.code (decimal — convert to hex with String(format: "0x%lx", value)), faultingThread, threads[].frames[]
  • Platform codes: 1=macOS, 2=iOS, 3=tvOS, 4=watchOS, 6=Mac Catalyst, 7/8/9=Simulators

For complete field-by-field documentation, see reference.md.