Post

Replies

Boosts

Views

Activity

PDFKit: -[PDFTileSurface releaseSurface] over-release crash (CFRelease.cold.2 / EXC_BREAKPOINT) on iPadOS 26.x, no PencilKit involved
Recurring fatal crash inside PDFKit's private tile-rendering pool. Exception is EXC_BREAKPOINT trapped inside CFRelease.cold.2, called from -[PDFTileSurface releaseSurface], reached via -[PDFTilePool releasePDFTileSurface:] <- -[PDFPageLayerTile dealloc]. Symptom matches an over-release / stale-reference bug in PDFTilePool's internal bookkeeping, not app-level misuse. This is a DIFFERENT app/codebase than the one already reported in Developer Forums thread 837282 (https://developer.apple.com/forums/thread/837282?answerId=896871022#896871022), hitting the identical 3-frame private call chain. That report used PDFView + a PKCanvasView overlay and speculated PencilKit/DYDisplayLinkInterposer overlay timing might be a factor. Our app uses a plain PDFView with NO PencilKit/PKCanvasView overlay of any kind, which rules that out as a necessary trigger -- the bug reproduces on stock PDFKit alone. Crash signature (symbolicated, from production Crashlytics): #0 CFRelease.cold.2 #1 CFEqual (also seen as plain CFRelease in the other report -- same release path) #2 -[PDFTileSurface releaseSurface] #3 -[PDFTilePool releasePDFTileSurface:] #4 -[PDFPageLayerTile dealloc] ... (see "Independent trigger paths" below for what appears above frame #4) blameFrame: CFRelease.cold.2, CoreFoundation, owner: PLATFORM (Crashlytics-attributed, no app frames anywhere in the crashing thread across any sample). Independent trigger paths observed (all converge on the same 3-frame chain above): Async tile-render completion (our most common variant, ~57% of our occurrences): -[PDFPageLayerTile recievePDFTileSurface:] -> -[PDFPageLayer tileDrawingComplete:] -> old tiles array dealloc -> -[PDFPageLayerTile dealloc] -> ... -> CFRelease.cold.2 Page-turn animation completion: -[PDFDocumentViewController pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:] -> -[PDFPageView clearTiles] -> -[PDFPageLayer _releaseTiles] -> -[__NSArrayM removeAllObjects] -> -[PDFPageLayerTile dealloc] -> ... -> CFRelease.cold.2 CATransaction commit / layer teardown: CA::Transaction::commit() -> CA::release_root_if_unused(...) -> CA::release_objects(...) -> -[PDFPageLayerTile dealloc] -> ... -> CFRelease.cold.2 (from forum thread 837282, different app) UIScrollView content-offset smooth scroll: -[UIScrollView setContentOffset:] -> smooth-scroll display link -> autorelease pool drain -> -[PDFPageLayerTile dealloc] -> ... -> CFRelease.cold.2 Four independent call sites funneling into the same release path strongly suggests the bug is inside PDFTilePool/PDFTileSurface's own reference counting, not any one caller's usage pattern. Diagnostic instrumentation (our own investigation, not yet submitted anywhere): We swizzled -[PDFTileSurface releaseSurface] in a debug build and logged every call (thread, surface pointer identity, re-entrancy count via a weak-keyed NSMapTable) during normal PDF navigation (page turns, scroll, zoom) on an affected device model. Across all observed calls: every surface was released exactly once, always on the main thread -- no Objective-C-level double-call or cross-thread race was observed at the releaseSurface entry point itself. This suggests the over-release is not "PDFTilePool calling release twice" but more likely a race between PDFTilePool's single, correctly-ordered release call and a separate system-level reclaim of the tile's backing store (e.g. IOSurface/purgeable memory eviction under memory pressure) that PDFTilePool's bookkeeping doesn't account for -- consistent with the device skew below. Device / OS distribution (production Crashlytics, 90-day window, 51 events, ~37 impacted users): iPad12,1 (iPad 9th gen): 45 events (88%) iPad11,7 (iPad 8th gen): 4 events iPad15,4 (iPad Air 11" M3): 1 event iPad11,4 (iPad Air 3rd gen): 1 event 100% on iPadOS 26.5.0 within this window This matches forum thread 837282's own report of "iPad 8, iPad 9 ... lower-end devices heavily affected" on iOS 26.4.2/26.5, "not affected on iOS 18.x" -- independent corroboration from two unrelated codebases of a regression concentrated on lower-RAM iPads specifically on 26.x. Expected Result: PDFKit's internal tile pool releases each rendered tile surface exactly once and does not trap inside CFRelease regardless of memory pressure, device tier, or which internal code path (render-complete, page-turn, layer-commit, scroll) triggers the release. Actual Result: App crashes with EXC_BREAKPOINT inside CFRelease.cold.2 during ordinary PDF viewing (page turns, scrolling, or async tile-render completion), concentrated on lower-RAM iPads (iPad 8th/9th gen) running iPadOS 26.4.2/26.5. Configuration: Plain PDFView (paged, .singlePage, displayDirection .horizontal), no PKCanvasView/PencilKit Affected iPadOS versions: 26.4.2, 26.5 (not reproduced on iOS 18.x per forum thread) Most affected devices: iPad 8th/9th generation (3GB RAM tier) Related report: https://developer.apple.com/forums/thread/837282?answerId=896871022#896871022 (same 3-frame private call chain, different app, DTS could not reproduce with vanilla PDFKit+PencilKit under stress testing as of that thread; no FB filed there yet)
1
0
715
Jul ’26
PDFKit: -[PDFTileSurface releaseSurface] over-release crash (CFRelease.cold.2 / EXC_BREAKPOINT) on iPadOS 26.x, no PencilKit involved
Recurring fatal crash inside PDFKit's private tile-rendering pool. Exception is EXC_BREAKPOINT trapped inside CFRelease.cold.2, called from -[PDFTileSurface releaseSurface], reached via -[PDFTilePool releasePDFTileSurface:] <- -[PDFPageLayerTile dealloc]. Symptom matches an over-release / stale-reference bug in PDFTilePool's internal bookkeeping, not app-level misuse. This is a DIFFERENT app/codebase than the one already reported in Developer Forums thread 837282 (https://developer.apple.com/forums/thread/837282?answerId=896871022#896871022), hitting the identical 3-frame private call chain. That report used PDFView + a PKCanvasView overlay and speculated PencilKit/DYDisplayLinkInterposer overlay timing might be a factor. Our app uses a plain PDFView with NO PencilKit/PKCanvasView overlay of any kind, which rules that out as a necessary trigger -- the bug reproduces on stock PDFKit alone. Crash signature (symbolicated, from production Crashlytics): #0 CFRelease.cold.2 #1 CFEqual (also seen as plain CFRelease in the other report -- same release path) #2 -[PDFTileSurface releaseSurface] #3 -[PDFTilePool releasePDFTileSurface:] #4 -[PDFPageLayerTile dealloc] ... (see "Independent trigger paths" below for what appears above frame #4) blameFrame: CFRelease.cold.2, CoreFoundation, owner: PLATFORM (Crashlytics-attributed, no app frames anywhere in the crashing thread across any sample). Independent trigger paths observed (all converge on the same 3-frame chain above): Async tile-render completion (our most common variant, ~57% of our occurrences): -[PDFPageLayerTile recievePDFTileSurface:] -> -[PDFPageLayer tileDrawingComplete:] -> old tiles array dealloc -> -[PDFPageLayerTile dealloc] -> ... -> CFRelease.cold.2 Page-turn animation completion: -[PDFDocumentViewController pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:] -> -[PDFPageView clearTiles] -> -[PDFPageLayer _releaseTiles] -> -[__NSArrayM removeAllObjects] -> -[PDFPageLayerTile dealloc] -> ... -> CFRelease.cold.2 CATransaction commit / layer teardown: CA::Transaction::commit() -> CA::release_root_if_unused(...) -> CA::release_objects(...) -> -[PDFPageLayerTile dealloc] -> ... -> CFRelease.cold.2 (from forum thread 837282, different app) UIScrollView content-offset smooth scroll: -[UIScrollView setContentOffset:] -> smooth-scroll display link -> autorelease pool drain -> -[PDFPageLayerTile dealloc] -> ... -> CFRelease.cold.2 Four independent call sites funneling into the same release path strongly suggests the bug is inside PDFTilePool/PDFTileSurface's own reference counting, not any one caller's usage pattern. Diagnostic instrumentation (our own investigation, not yet submitted anywhere): We swizzled -[PDFTileSurface releaseSurface] in a debug build and logged every call (thread, surface pointer identity, re-entrancy count via a weak-keyed NSMapTable) during normal PDF navigation (page turns, scroll, zoom) on an affected device model. Across all observed calls: every surface was released exactly once, always on the main thread -- no Objective-C-level double-call or cross-thread race was observed at the releaseSurface entry point itself. This suggests the over-release is not "PDFTilePool calling release twice" but more likely a race between PDFTilePool's single, correctly-ordered release call and a separate system-level reclaim of the tile's backing store (e.g. IOSurface/purgeable memory eviction under memory pressure) that PDFTilePool's bookkeeping doesn't account for -- consistent with the device skew below. Device / OS distribution (production Crashlytics, 90-day window, 51 events, ~37 impacted users): iPad12,1 (iPad 9th gen): 45 events (88%) iPad11,7 (iPad 8th gen): 4 events iPad15,4 (iPad Air 11" M3): 1 event iPad11,4 (iPad Air 3rd gen): 1 event 100% on iPadOS 26.5.0 within this window This matches forum thread 837282's own report of "iPad 8, iPad 9 ... lower-end devices heavily affected" on iOS 26.4.2/26.5, "not affected on iOS 18.x" -- independent corroboration from two unrelated codebases of a regression concentrated on lower-RAM iPads specifically on 26.x. Expected Result: PDFKit's internal tile pool releases each rendered tile surface exactly once and does not trap inside CFRelease regardless of memory pressure, device tier, or which internal code path (render-complete, page-turn, layer-commit, scroll) triggers the release. Actual Result: App crashes with EXC_BREAKPOINT inside CFRelease.cold.2 during ordinary PDF viewing (page turns, scrolling, or async tile-render completion), concentrated on lower-RAM iPads (iPad 8th/9th gen) running iPadOS 26.4.2/26.5. Configuration: Plain PDFView (paged, .singlePage, displayDirection .horizontal), no PKCanvasView/PencilKit Affected iPadOS versions: 26.4.2, 26.5 (not reproduced on iOS 18.x per forum thread) Most affected devices: iPad 8th/9th generation (3GB RAM tier) Related report: https://developer.apple.com/forums/thread/837282?answerId=896871022#896871022 (same 3-frame private call chain, different app, DTS could not reproduce with vanilla PDFKit+PencilKit under stress testing as of that thread; no FB filed there yet)
Replies
1
Boosts
0
Views
715
Activity
Jul ’26