Files
Alexandru Dima ba2a3ee737 ci: pre-initialize fontconfig to fix Pango threaded-FcInit crash in smoke tests (#323015)
Symbolizing the intermittent Electron-startup SIGSEGV crash dumps (Ubuntu debug
symbols + frame-pointer walk) shows the fault is an upstream Pango concurrency
bug, not a VS Code bug:

    pango:      fc_thread_func -> init_in_thread -> FcInit()   (pangofc-fontmap.c)
    fontconfig: FcInit -> FcConfigParseAndLoadFromMemory -> _FcConfigParse
    libexpat:   XML_ParseBuffer -> libc  (NULL deref, SIGSEGV)

Pango >= 1.52's pango_fc_font_map_init() unconditionally spawns a
"[pango] fontconfig" thread that runs FcInit(); that races with the
Electron/Chromium main thread's own fontconfig use during startup and corrupts
fontconfig's global config while it is being parsed. The threaded design is a
known-bad area upstream (pango#784 "single fontconfig thread introduces a hang
... seems to be due to a race condition", pango#872), and there is no env var to
disable it (still present in Pango 1.56).

It only manifests in our CI because the race window is microscopic: it needs a
cold process, two threads hitting first-time FcInit() simultaneously, and a slow
machine. Our smoke job is a near-perfect trigger — fresh contended runners, a
wiped fontconfig cache + custom FONTCONFIG_FILE (so FcInit re-parses cold), and
~25 cold Electron starts per run. (This also explains why the expat version was
irrelevant and why dropping the config DOCTYPE made it worse: it is pure timing,
not parser/content.)

Fix: initialize fontconfig once, single-threaded, from an ELF constructor that
runs before main() (and thus before any thread exists), via a tiny LD_PRELOAD
shim. Pango's later threaded FcInit() then finds fontconfig already initialized
and returns immediately, so the concurrent parse never happens and the race is
eliminated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-25 22:53:43 +00:00
..
2026-04-07 11:40:24 +02:00