Skip to content

fix: prevent isolated deinit crashes during Markdown rendering - #17

Merged
gtokman merged 2 commits into
mainfrom
codex/markdown-block-processor-deinit
Oct 19, 2026
Merged

gtokman merged 2 commits into
mainfrom
codex/markdown-block-processor-deinit

Conversation

@gtokman

@gtokman gtokman commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Prevent synchronous Markdown rendering from aborting during helper teardown on older Swift runtimes, extending the lifetime fix in #16.

Problem

BlockProcessor, TextBuilder, and ReusableViewProvider still receive implicit isolated deinitializers under the package's default MainActor isolation. Releasing them synchronously outside a Swift task can enter swift_task_deinitOnExecutorMainActorBackDeploy → swift_task_deinitOnExecutorImpl → TaskLocal::StopLookupScope and abort with “pointer being freed was not allocated.” This matches Swift issue #88036.

The unmodified library reproduced this crash independently for all three classes on the iOS 26.2 simulator.

Solution

Add explicit empty nonisolated deinit implementations to those three classes, preserving MainActor isolation for their rendering operations. Extend the existing synchronous task-local lifetime tests to cover each helper and complete full/incremental renders, including release of the owned view provider.

Validation

  • swift test --filter RenderingLifetimeTests: seven tests passed on macOS.
  • SwiftPM build of the MarkdownView target for the iOS simulator passed.
  • Linked a standalone synchronous harness against the actual iOS library, using the seven lifetime test bodies with precondition assertions: all seven passed on iOS 26.2, with 100 iterations per case.
  • Original-source comparison harness reproduced SIGABRT independently in each of the three helper deinitializers; crash reports contained the same invalid-free / task-local / isolated-deinit stack.
  • git diff --check passed. No xcodebuild or full app build was run.

The consuming app's dependency pin must be updated separately after this fix is available.

CI follow-up

The initial Swift workflow compiled successfully but failed two existing highlighting assertions: their Python/Swift grammars are optional and excluded from the default package traits. Use JavaScript fixtures for those tests and the highlight-cache test, and require a nonempty map before checking cache reuse. This preserves highlighting coverage under the default configuration.

Validation after the fixture correction: swift build and the full swift test suite pass locally (166 tests, zero failures).

@vercel

vercel Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
markdown-view Ready Ready Preview, v0 Oct 19, 2026 4:54pm UTC

Request Review

@gtokman
gtokman marked this pull request as ready for review October 19, 2026 16:29
@gtokman
gtokman merged commit 44c4746 into main Oct 19, 2026
6 checks passed

This branch was successfully deployed

1 active deployment
Preview — f1d72c63 Deployed Oct 19, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant