Skip to content

Fix Linux ARM64 crash caused by missing fontconfig in cross-compile sysroot#3494

Merged
mattleibow merged 5 commits intomainfrom
copilot/issue-3369-linux-arm64-crash
Feb 3, 2026
Merged

Fix Linux ARM64 crash caused by missing fontconfig in cross-compile sysroot#3494
mattleibow merged 5 commits intomainfrom
copilot/issue-3369-linux-arm64-crash

Conversation

@mattleibow
Copy link
Collaborator

@mattleibow mattleibow commented Feb 3, 2026

Summary

This PR fixes the hard crash on Linux ARM64 (issue #3369) by adding the fontconfig runtime library to ALL cross-compile Docker sysroots.

Root Cause Analysis

The ARM64 cross-compile Docker was only downloading libfontconfig1-dev which provides:

  • Headers (fontconfig.h, etc.)
  • Static library (libfontconfig.a)

The actual shared library (libfontconfig.so.1.12.0) is in the runtime package (libfontconfig1), not the dev package.

Why the build succeeded but runtime failed

  1. The ninja build includes -lfontconfig in the link command
  2. The linker finds libfontconfig.so symlink, but it points to a non-existent file
  3. The resulting libSkiaSharp.so is missing libfontconfig.so.1 from its DT_NEEDED entries
  4. At runtime, fontconfig is loaded implicitly via freetype
  5. fontconfig calls uuid_generate_random() which requires libuuid
  6. CRASH: undefined symbol: uuid_generate_random

Comparison: x64 vs ARM64 before fix

x64 (native build) - has fontconfig:

DT_NEEDED: libpthread.so.0, libfontconfig.so.1, libdl.so.2, libm.so.6, libc.so.6

ARM64 (cross-compile) - missing fontconfig:

DT_NEEDED: libpthread.so.0, libdl.so.2, libm.so.6, libc.so.6

ARM64 after fix

DT_NEEDED: libpthread.so.0, libfontconfig.so.1, libdl.so.2, libm.so.6, libc.so.6

The Fix

Download both packages when setting up the cross-compile sysroot:

  • libfontconfig1-dev - headers and static library
  • libfontconfig1 - actual shared library

Files changed:

  • scripts/Docker/debian/clang-cross/10/Dockerfile (arm, arm64, x86, riscv64)
  • scripts/Docker/debian/clang-cross/11/Dockerfile (same fix for consistency)
  • scripts/Docker/debian/clang-cross/12/Dockerfile (same fix for consistency)
  • scripts/Docker/debian/clang-cross/13/Dockerfile (loongarch64)

Testing

✅ Built ARM64 with fix - fontconfig now appears in DT_NEEDED
✅ Tested font operations (SKTypeface.FromFamilyName, DrawText) on ARM64 Docker
✅ No more undefined symbol: uuid_generate_random crash

Related Issues

This fix also resolves:

Fixes #3369
Fixes #3272
Fixes #3436

@github-actions
Copy link

github-actions bot commented Feb 3, 2026

Triage Summary

Labels will be applied to indicate issues related to reliability on Linux ARM64, the SkiaSharp library, and its backend functionalities.

This issue does not appear to be marked as a regression, but it highlights a critical reliability issue.

Additional remarks:

  • The severity of the hard crash on Linux ARM64 could potentially impact users significantly.
Detailed Summary and Actions

Summary of the triage:

  • The issue signifies a hard crash on the Linux ARM64 platform.
  • It is relevant to the reliability of the application, particularly in the SkiaSharp library.
  • The problem reflects aspects of both the SkiaSharp backend and its association with Android due to shared architecture.

Summary of the actions that will be performed:

Action Item Description
Apply Label tenet/reliability The issue describes a hard crash on Linux ARM64, indicating a reliability problem.
Apply Label os/Linux The issue mentions a hard crash occurring specifically on Linux ARM64.
Apply Label area/SkiaSharp The specifics of the issue relate to a hard crash in the SkiaSharp library.
Apply Label backend/SkiaSharp The issue references the SkiaSharp 3.119.0 version, marking it relevant to that specific backend.
Apply Label backend/Android The investigation involves Linux ARM64, relevant to the Android platform as they share architecture.

This entire triage process was automated by AI and mistakes may have been made. Please let us know so we can continue to improve.

@github-actions github-actions bot added area/SkiaSharp Issues that relate to the C# binding of SkiaSharp. backend/Android os/Linux tenet/reliability Issues relating to crashes or unexpected behaviors labels Feb 3, 2026
@mattleibow mattleibow changed the title Investigating #3369: Hard crash on Linux ARM64 Fix Linux ARM64 crash caused by missing fontconfig in cross-compile sysroot Feb 3, 2026
@mattleibow mattleibow marked this pull request as ready for review February 3, 2026 01:52
@mattleibow mattleibow force-pushed the copilot/issue-3369-linux-arm64-crash branch from 1b84ef3 to fe4fec0 Compare February 3, 2026 02:25
@mattleibow mattleibow added the copilot Created by GitHub Copilot label Feb 3, 2026
…e sysroot

The cross-compile Docker for ARM64 was missing the fontconfig runtime library
(libfontconfig1), causing the linker to silently skip linking -lfontconfig
because the .so symlink pointed to a non-existent file.

Root cause: The -dev package only provides headers and a symlink
(libfontconfig.so -> libfontconfig.so.1.12.0), but the actual shared library
(.so.1.12.0) comes from the runtime package (libfontconfig1).

This resulted in:
- ARM64 libSkiaSharp.so missing libfontconfig.so.1 in DT_NEEDED
- Runtime crash: 'undefined symbol: uuid_generate_random' (fontconfig's dependency)
- Also affected: 'undefined symbol: FT_Get_BDF_Property' (freetype via fontconfig)

Fix: Download both libfontconfig1-dev (headers, .a, symlink) AND libfontconfig1
(actual .so) when setting up the cross-compile sysroot.

Fixes #3369
Fixes #3272
Fixes #3436
The same broken symlink issue exists in all cross-compile Dockerfiles.
This commit ensures fontconfig is properly linked on all architectures
using any of the Debian-based cross-compile images.
- Add --verifyIncluded argument to native/linux/build.cake (inverse of verifyExcluded)
- Update build scripts to pass through extra arguments
- Only apply verifyIncluded check to libSkiaSharp (not HarfBuzz)

This allows CI to verify that fontconfig is properly linked on cross-compiled builds.
This ensures fontconfig is properly linked on all cross-compiled Linux builds:
- Dockerfile 10: arm, arm64, x86, riscv64
- Dockerfile 13: loongarch64

Alpine builds don't use fontconfig (skia_use_fontconfig=false) so they're excluded.
@mattleibow mattleibow force-pushed the copilot/issue-3369-linux-arm64-crash branch from 5e331c4 to ef22ab9 Compare February 3, 2026 03:34
The verifyIncluded=fontconfig should only apply to the regular build,
not to the 'nodeps' build which uses skia_use_fontconfig=false.

Moving it to the builds level ensures:
- Regular builds: verify fontconfig IS included
- Nodeps builds: verify fontconfig is NOT included (existing behavior)
@mattleibow mattleibow merged commit fe569ef into main Feb 3, 2026
2 checks passed
@mattleibow mattleibow deleted the copilot/issue-3369-linux-arm64-crash branch February 3, 2026 10:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/SkiaSharp Issues that relate to the C# binding of SkiaSharp. copilot Created by GitHub Copilot os/Linux tenet/reliability Issues relating to crashes or unexpected behaviors

Projects

Status: Done

1 participant