Bug 2542946

Summary: WebKitGTK 2.54: WebProcess burns 100% CPU in SkFontMgr_fontconfig::GetFamilyNames and never paints with a large user font set
Product: [Fedora] Fedora Reporter: orisgo111
Component: webkitgtkAssignee: Michael Catanzaro <mcatanza>
Status: CLOSED UPSTREAM QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 44CC: daniel, gnome-sig, mcatanza, suraj.ghimire7, tpopela
Target Milestone: ---Keywords: Desktop
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: ---
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2026-09-29 14:37:41 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Attachments:
Description Flags
gdb backtrace of hung WebKitWebProcess main thread: 99% CPU in SkFontMgr_fontconfig::GetFamilyNames
none
File names of the 538 Windows fonts (757 MB) installed in ~/.local/share/fonts when the hang occurs
none
Minimal PyGObject/WebKit2 4.1 reproducer (prints LOAD FINISHED on success, hangs with large font set) none

Description orisgo111 2026-09-29 05:49:01 UTC
# WebKitGTK 2.54: WebProcess burns 100% CPU in SkFontMgr_fontconfig::GetFamilyNames and never paints with a large user font set

**Product:** Fedora
**Component:** webkitgtk
**Version:** 44
**Package:** webkit2gtk4.1-2.54.0-2.fc44 (same symptom also observed with 2.52.5-1.fc44)
**Environment:** Fedora 44 Workstation, GNOME Shell 50.5, Wayland (X11 session also affected), kernel 7.2.7-200.fc44.x86_64, mesa 26.2.3, AMD Radeon 780M (amdgpu), fontconfig-2.17.0-4.fc44

## Summary

A WebKitGTK-based application (Tauri v2 / wry: Clash Verge Rev 2.5.6) opens a blank/gray
window that never paints. The `WebKitWebProcess` main thread stays at ~99% CPU for many
minutes inside `SkFontMgr_fontconfig::GetFamilyNames(FcConfig*)`, entered from
`WebCore::FontCache::fontManager()` during initial style resolution. Removing a large user
font collection (646 user fonts, 757 MB, 538 of them from a Windows font pack; `fc-list`
reported 1486 families) immediately restores rendering (856 families).

## Steps to reproduce

1. Fedora 44 with webkit2gtk4.1-2.54.0-2.fc44.
2. Copy a large font collection into `~/.local/share/fonts/` (here: 538 Windows TTF/TTC
   files, 757 MB; many of them carry dozens of localized family/style names).
3. `fc-cache -f` (`fc-list | wc -l` -> 1486).
4. Run the minimal reproducer `repro.py` (PyGObject + WebKit2 4.1, loads a `load_html`
   page with Chinese text), or any webkit2gtk-4.1 app (tested with Clash Verge Rev 2.5.6).
5. Expected: the page renders in well under a second; `LOAD FINISHED` is printed.
   Actual: nothing is painted; `WebKitWebProcess` sits at ~100% CPU indefinitely and
   `LOAD FINISHED` is never printed.

## Evidence

gdb backtrace of the live hung WebProcess main thread (`gdb -p <WebKitWebProcess>`,
thread 1; symbols resolved from libwebkit2gtk-4.1.so.0):

```
#0  __strcmp_evex
#1  FcObjectTypeLookup
#2  FcPatternGetString
#3  SkFontMgr_fontconfig::GetFamilyNames(FcConfig*)
#4  WebCore::FontCache::fontManager() const
#5  WebCore::FontCache::createFontPlatformData(...)
#6  WebCore::FontCache::cachedFontPlatformData(...)
#7  WebCore::FontCache::fontForFamily(...)
#8  WebCore::CSSFontSelector::fontRangesForFamily(...)
#9  WebCore::realizeNextFallback(...)
#10 WebCore::FontCascadeFonts::realizeFallbackRangesAt(...)
#11 WebCore::FontCascadeFonts::primaryFont(...)
#12 WebCore::FontCascade::primaryFont() const
#13 WebCore::Style::TreeResolver::resolveComposedTree()
#14 WebCore::Style::TreeResolver::resolve()
#15 WebCore::Document::resolveStyle(...)
#16 WebCore::Document::updateStyleIfNeeded()
#17 ... Document constructor timer
#24 WTF::RunLoop::run()
#25 WebKit::WebProcessMain
```

- `ps` shows `WebKitWebProcess` at 99.6% CPU for 5+ minutes and counting.
- Sampling `$pc` between gdb attachments shows the thread progressing through
  `FcPatternObjectPosition` / `FcPatternGetString` (not a deadlock): the enumeration is
  pathologically slow rather than blocked on a lock.
- `WebCore::FontCache::fontManager()` is the caller on every `createFontPlatformData()`,
  suggesting the family enumeration is re-done per font lookup instead of being
  cached once for the process.
- `coredumpctl` entries captured when the app was later closed show the same main-thread
  stack, i.e. the process was still in `GetFamilyNames` at shutdown.

## Workarounds tried (do not help)

- `WEBKIT_DISABLE_DMABUF_RENDERER=1`
- `WEBKIT_DISABLE_COMPOSITING_MODE=1`
- `LIBGL_ALWAYS_SOFTWARE=1`
- GNOME X11 session instead of Wayland

So this is not the well-known DMABUF / accelerated-compositing issue.

## Workaround that works

Move the large user font collection out of `~/.local/share/fonts`, run `fc-cache -f`,
then (re)launch the application. Rendering is immediate with ~856 font families.

## Notes / possibly related

- Fontconfig-level instability is also visible on this machine: quickshell (Qt6)
  repeatedly SIGSEGVs in `FcCharSetFindLeafForward` while laying out text. It may share
  a root cause with large / malformed font catalogs.
- Arch packaging report with similar symptoms ("fontconfig 2:2.18.0-2 leads to 100%
  CPU-Load, Missing UI-Elements ... in webkit2gtk-4.1-applications"):
  https://gitlab.archlinux.org/archlinux/packaging/packages/fontconfig/-/work_items/8
- Not bisected yet: whether one specific font or the sheer number / localized-name
  volume triggers this. The font pack is retained and can be bisected on request.

## Attachments

- `backtrace.txt` - full gdb backtrace of the hung process
- `repro.py` - minimal PyGObject + WebKit2 4.1 reproducer
- `win-font-list.txt` - names of the 538 Windows font files that were installed

Reproducible: Always

Steps to Reproduce:
1. Fedora 44 with webkit2gtk4.1-2.54.0-2.fc44.
2. Copy a large font collection into `~/.local/share/fonts/` (here: 538 Windows TTF/TTC
   files, 757 MB; many of them carry dozens of localized family/style names).
3. `fc-cache -f` (`fc-list | wc -l` -> 1486).
4. Run the minimal reproducer `repro.py` (PyGObject + WebKit2 4.1, loads a `load_html`
   page with Chinese text), or any webkit2gtk-4.1 app (tested with Clash Verge Rev 2.5.6).
5. Expected: the page renders in well under a second; `LOAD FINISHED` is printed.
   Actual: nothing is painted; `WebKitWebProcess` sits at ~100% CPU indefinitely and
   `LOAD FINISHED` is never printed.
Actual Results:
The window stays blank/gray and never paints. WebKitWebProcess runs at ~99-100%
CPU indefinitely (observed >10 minutes) with its main thread inside
SkFontMgr_fontconfig::GetFamilyNames(FcConfig*) called from
WebCore::FontCache::fontManager() during Document::updateStyleIfNeeded, so the
first layout never completes. The minimal reproducer never prints "LOAD
FINISHED". The UI is unresponsive to input while the rest of the process
(including non-WebKit app logic) stays healthy, and no crash or error is logged.

Expected Results:
The page is painted normally: after launch, WebKitWebProcess finishes initial
style/layout and the window renders in well under a second, regardless of how
many fonts are installed in the user font directories. WebKitWebProcess returns
to idle CPU after load, and the minimal reproducer prints "LOAD FINISHED".

Additional Information:
Environment: Fedora 44 Workstation, GNOME Shell 50.5, Wayland (also reproduced in an
X11 session), kernel 7.2.7-200.fc44.x86_64, mesa 26.2.3, AMD Radeon 780M (amdgpu),
webkit2gtk4.1-2.54.0-2.fc44, fontconfig-2.17.0-4.fc44. The same symptom was already
present with webkit2gtk4.1-2.52.5-1.fc44.

Scope: affects any webkit2gtk-4.1 app, not one specific application. Reproduced with
the attached 15-line PyGObject/WebKit2 4.1 script and with a Tauri v2 / wry app
(Clash Verge Rev 2.5.6).

Captured evidence:
- Live gdb backtrace of the hung WebProcess main thread (attached, backtrace.txt):
  __strcmp_evex -> FcObjectTypeLookup -> FcPatternGetString ->
  SkFontMgr_fontconfig::GetFamilyNames(FcConfig*) -> WebCore::FontCache::fontManager()
  -> createFontPlatformData -> cachedFontPlatformData -> fontForFamily ->
  fontRangesForFamily -> realizeNextFallback -> realizeFallbackRangesAt -> primaryFont
  -> Style::TreeResolver::resolveComposedTree -> Document::updateStyleIfNeeded.
- Captured with:
  gdb -p $(pgrep -f WebKitWebProcess) -batch -ex "set pagination off" -ex "thread 1" -ex "bt 25"
- Sampling $pc a few seconds apart showed progress through FcPatternObjectPosition /
  FcPatternGetString, so the thread is not deadlocked; it just never finishes (>10 min).
- WebCore::FontCache::fontManager() appears on every createFontPlatformData() call, i.e.
  the font-family list appears to be re-enumerated per font lookup instead of being
  cached once per process.
- coredumpctl entries recorded when the app was closed later show the same main-thread
  stack, confirming the process was still inside GetFamilyNames at exit time.

Workarounds that do NOT help: WEBKIT_DISABLE_DMABUF_RENDERER=1,
WEBKIT_DISABLE_COMPOSITING_MODE=1, LIBGL_ALWAYS_SOFTWARE=1, using an X11 session.

Workaround that works: move the large user font collection out of ~/.local/share/fonts
(538 Windows TTF/TTC files, 757 MB) and run `fc-cache -f`. With ~856 font families the
same apps render immediately.

Possibly related: quickshell (Qt6) on the same machine repeatedly SIGSEGVs in
FcCharSetFindLeafForward / FcCharSetHasChar while laying out text. An Arch packaging
report describes similar symptoms with webkit2gtk-4.1:
https://gitlab.archlinux.org/archlinux/packaging/packages/fontconfig/-/work_items/8

Not yet bisected: whether a specific font or the total number of fonts (many with dozens
of localized family/style names) triggers this. The font pack is retained and can be
bisected on request.

Attachments: backtrace.txt (gdb backtrace), repro.py (minimal reproducer),
win-font-list.txt (installed Windows font file names).

Comment 1 orisgo111 2026-09-29 05:50:58 UTC
Created attachment 2159012 [details]
gdb backtrace of hung WebKitWebProcess main thread: 99% CPU in SkFontMgr_fontconfig::GetFamilyNames

Comment 2 orisgo111 2026-09-29 05:51:40 UTC
Created attachment 2159013 [details]
File names of the 538 Windows fonts (757 MB) installed in ~/.local/share/fonts when the hang occurs

Comment 3 orisgo111 2026-09-29 05:52:06 UTC
Created attachment 2159014 [details]
Minimal PyGObject/WebKit2 4.1 reproducer (prints LOAD FINISHED on success, hangs with large font set)

Comment 4 Michael Catanzaro 2026-09-29 14:39:51 UTC
Hi, please report this on WebKit Bugzilla, WebKitGTK component. Thanks.

Comment 5 Michael Catanzaro 2026-09-29 16:56:38 UTC
Actually I think this is https://bugs.webkit.org/show_bug.cgi?id=325185