Home > Developer Guide > iOS > Testing > KMP GC Crash


KMP GC Crash Investigation

Status: Known Limitation (not a bug in our code)

Impact: Post-test crash during XCTest cleanup - all tests pass successfully

Upstream Issue: KT-68156

Summary

A Kotlin Native memory crash occurs during iOS XCTest execution, manifesting as:

malloc: *** error for object 0x262c5a6f0: pointer being freed was not allocated

Key Finding: This is a known limitation of Kotlin Native with XCTest, not a bug in our code. All 123 tests pass successfully - the crash occurs during test host cleanup/restart.


What Happens

┌─────────────────────────────────────────────────────────────┐
│  1. XCTest launches app as test host                        │
│  2. Kotlin Native framework initializes, creates GC threads │
│  3. Tests execute successfully (all 123 pass)               │
│  4. XCTest terminates/restarts test host                    │
│  5. Kotlin Native GC cleanup triggers double-free  ← CRASH  │
└─────────────────────────────────────────────────────────────┘

Why It Happens

The crash address (0x262c5a6f0) is deterministic - it’s a static allocation in the Kotlin Native runtime. When XCTest restarts the test host, framework static initializers run again, conflicting with previously allocated memory that wasn’t properly cleaned up.


Test Results

Despite the crash, tests execute correctly:

MetricValue
Total iOS Tests123
Pass Rate100%
Test Execution Time~0.6 seconds
Crash TimingAfter all tests complete

Configurations Tested

None of the following configurations resolved the crash:

ConfigurationResult
kotlin.native.binary.gc=noopSame crash
kotlin.native.binary.gc=stwmsSame crash
kotlin.native.binary.objcDisposeOnMain=falseSame crash
kotlin.native.binary.gcMarkSingleThreaded=trueSame crash
Serial test execution (-parallel-testing-enabled NO)Same crash
Clean simulator (erase all content)Same crash
Clear DerivedDataSame crash

Workarounds

For Xcode IDE Testing

  1. Continue on debugger break: Press Cmd+Ctrl+Y when debugger stops on the malloc error
  2. Disable malloc breakpoints: In Xcode debugger, don’t set breakpoint on malloc_error_break
  3. Use command line: xcodebuild test works perfectly for automation

For CI/CD

The command-line test runner handles this gracefully:

# xcodebuild returns exit code 0 when all tests pass
xcodebuild -workspace ArcheryApprentice.xcworkspace \
  -scheme ArcheryApprentice \
  -destination 'platform=iOS Simulator,name=iPhone 16e' \
  test
 
# Check actual test results (ignoring post-test crash)
echo $?  # Returns 0 if all tests passed

Parsing Test Results

For explicit verification in CI scripts:

# Extract test summary
xcodebuild test ... 2>&1 | grep -E "Executed \d+ tests, with \d+ failures"
 
# Expected output for passing tests:
# Executed 123 tests, with 0 failures (0 unexpected) in 0.612 (0.654) seconds

Stack Trace Analysis

Typical crash stack trace:

* thread #4, name = 'FinalizerThread main', stop reason = signal SIGABRT
  * frame #0: libsystem_kernel.dylib`__pthread_kill
    frame #1: libsystem_pthread.dylib`pthread_kill
    frame #2: libsystem_c.dylib`abort
    frame #3: libsystem_malloc.dylib`malloc_vreport
    frame #4: libsystem_malloc.dylib`malloc_zone_error
    frame #5: Shared`_ZN6kotlin2gc10FinalizerThreadE...

The crash originates in Kotlin Native’s FinalizerThread, indicating it occurs during garbage collection cleanup, not during test execution.


Impact Assessment

AspectImpact
Test ReliabilityNone - all tests pass
CI/CDNone - exit code 0 on success
Developer ExperienceMinor - debugger breaks on crash
Production CodeNone - runtime-only issue

  1. Don’t try to fix it - This is an upstream Kotlin Native issue
  2. Use command-line testing - More reliable than Xcode IDE for KMP projects
  3. Monitor upstream - JetBrains is aware of the issue
  4. Document for team - Ensure developers know this is expected behavior

References



Last Updated: 2025-12-06 Investigation completed during iOS XCTest infrastructure documentation