ghostty: link against system fontconfig to fix crashes#476
Open
maxib0n wants to merge 1 commit into
Open
Conversation
Ghostty statically bundles its own copy of fontconfig, and because the resulting binary is a PIE executable built without hiding those symbols, it globally exports ~27 Fc* functions. GTK4/Pango load the system libfontconfig.so.1 into the same process. Due to ELF symbol interposition, calls made from inside libfontconfig.so.1 (and other GTK-side consumers, e.g. glycin's SVG loader per ghostty-org/ghostty discussion #12555) get redirected to Ghostty's bundled copy instead, corrupting state shared between the two fontconfig instances. This causes reproducible SIGSEGV/SIGABRT crashes (double free / invalid free in FcPatternDestroy, FcFontSetDestroy, or segfaults in FcFontSort), most easily triggered by moving a Ghostty window between monitors with different scale factors, which forces a font grid rebuild through fontconfig. Passing -fsys=fontconfig makes Ghostty dynamically link the system fontconfig instead of statically bundling its own, leaving a single fontconfig instance in the process. Verified locally: the resulting binary exports zero Fc* symbols (down from 27), lists libfontconfig.so.1 as a proper NEEDED entry, and no longer crashes under repeated monitor moves that reliably crashed the unpatched build.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Ghostty statically bundles its own copy of fontconfig. Because the resulting binary is a PIE executable built without hiding those symbols, it globally exports ~27
Fc*functions. GTK4/Pango load the systemlibfontconfig.so.1into the same process, and due to ELF symbol interposition, calls made from insidelibfontconfig.so.1(and other GTK-side consumers, e.g. glycin's SVG loader, see ghostty-org/ghostty#12555) get redirected to Ghostty's bundled copy instead, corrupting state shared between the two fontconfig instances.This causes reproducible
SIGSEGV/SIGABRTcrashes (invalid free inFcPatternDestroy/FcFontSetDestroy, or segfaults inFcFontSort). The easiest reliable trigger is moving a Ghostty window between two monitors with different scale factors, which forces a font grid rebuild through fontconfig (Surface.contentScaleCallback→setFontSize→SharedGridSet.ref→Fontconfig.discover).Passing
-fsys=fontconfigtozig buildmakes Ghostty dynamically link the system fontconfig instead of statically bundling its own, so there's a single fontconfig instance in the process.Verification
On the currently published
ghostty-1.3.1-2.fc44build:8 coredumps collected over the past week, 6 with matching stack traces through
contentScaleCallback → setFontSize → SharedGridSet.ref → FcFontSetDestroy/FcPatternDestroyorFcFontSort.Rebuilt locally with
-fsys=fontconfigadded (same Zig 0.15.2, same build flags otherwise):Ran the patched binary and repeatedly moved the window between the two monitors that reliably crashed the unpatched build (scale 1.25 vs scale 1) — no crash.
Test plan
zig buildsucceeds with-fsys=fontconfigadded (209/209 steps)Fc*symbols vs 27 beforelibfontconfig.so.1is a properNEEDEDentry