Crash with trivial SkParagraph code on Linux

64 views
Skip to first unread message

Cedric

unread,
Jul 31, 2025, 8:56:51 AMJul 31
to skia-discuss
Hello,

We started to use SkParagraph in our code and everything was working properly on Windows. On Linux however, there is a crash which I was able to reproduce with a very minimalistic example:
SkParagraphCrash.jpg

At line 16, an instance of ParagraphStyle is created and this corrupts the memory. The address pointed by the collection smart ptr is overwritten, which causes a crash on line 17.

I have no idea what is causing this. I already tried with different build arguments but it always ends up with the same result.

Here are the content of my args.gn file:
is_debug=false
is_official_build=true
is_component_build=false
skia_use_harfbuzz=true
skia_use_system_expat=true
skia_use_system_libjpeg_turbo=false
skia_use_system_libpng=true
skia_use_system_libwebp=false
skia_use_system_zlib=true
skia_use_system_icu=false
skia_use_system_harfbuzz=false
skia_use_fontconfig=true
cc = "/usr/local/gcc-11.2/bin/gcc"
cxx = "/usr/local/gcc-11.2/bin/g++"

This simple example was created with Eclipse, and here are also the compiler and linker flags which were used:
Building file: ../src/my_test.cpp
Invoking: GCC C++ Compiler
/usr/local/gcc-11.2/bin/g++ -std=c++17 -D_GLIBCXX_USE_CXX11_ABI=0 -I/home/user123/eclipse-workspace/my_test/include/skia -O0 -g3 -Wall -c -fmessage-length=0 -Wno-comment -Wno-unknown-pragmas -Wno-unused-function -Wno-unused-variable -Wno-reorder -Wno-switch -MMD -MP -MF"src/my_test.d" -MT"src/my_test.o" -o "src/my_test.o" "../src/my_test.cpp"
Finished building: ../src/my_test.cpp
 
Building target: my_test
Invoking: GCC C++ Linker
/usr/local/gcc-11.2/bin/g++ -L/home/user123/eclipse-workspace/my_test/libs -R /home/eclipse-workspace/my_test -o "my_test" ./src/my_test.o    -lskia -lskparagraph -lskshaper -lskunicode_icu -lskunicode_core -licu -lfreetype -lfontconfig -lpng -lz -ljpeg
Finished building target: my_test


I tried on M128 and M139, same issue on both branches.

Any idea what the problem might be? This seems like a pretty straightforward usage of SkParagraph and I was wondering if I'm the only one experiencing the issue.

Thanks,
Cedric

jlav...@google.com

unread,
Jul 31, 2025, 10:26:10 AMJul 31
to skia-discuss
You said that you tried M139 but that would require changing your test significantly. I don't see it in your test file.
In that version we give a user a choice to work with FreeType or Fontations so you have to make that choice in the code.
(Check the release notes)
If you look at the skia example: example/external_client/src/svg_renderer.cpp you will see what I mean.
I guess that once you switch to the new version your issue should disappear. If not, it will be much easier for us to deal with it.

Cedric

unread,
Aug 4, 2025, 8:05:27 AMAug 4
to skia-discuss
Hello,

Thanks for your answer. The API was indeed modified, but the old API method is still available:
FontConfig.png
(I suppose that the SK_DISABLE_LEGACY_FONTCONFIG_FACTORY is not defined by default).

Anyway, I updated my code to use the new method:
code.png

The crash still occurs, but now the address inside the collection smart pointer is a "valid" address: it won't crash when calling enableFontFallback but it will crash at program end because of memory corruption. Here is a watch of the collection variable before and after line 17:
BeforeCrash.pngAfterCrash.png

And here is the source code in case you want to copy/paste in order to try:

#include <include/core/SkFontMgr.h>

#include <fontconfig/fontconfig.h>
#include <include/ports/SkFontMgr_fontconfig.h>
#include <include/ports/SkFontScanner_FreeType.h>

#include <modules/skparagraph/include/ParagraphBuilder.h>
#include <modules/skparagraph/include/FontCollection.h>

using namespace skia::textlayout;

int main() {
sk_sp<SkFontMgr> fontMgr = SkFontMgr_New_FontConfig((_FcConfig*)nullptr, SkFontScanner_Make_FreeType());

sk_sp<FontCollection> collection = sk_make_sp<FontCollection>();

ParagraphStyle paragraphStyle;
collection->enableFontFallback();
return 0;
}


Can you let me know if you can reproduce the issue as well?

jlav...@google.com

unread,
Aug 4, 2025, 10:33:36 AMAug 4
to skia-discuss
Thank you for moving to the current version of Skia. It does make things much easier.
I tried your example and I didn't reproduce the issue.
Now we need to find out what is so different between your building procedure/environment and mine 
that causes the problem.

First, below is my list gn args (not all of them needed but I would pay attention to freetype):

skia_use_freetype=true
skia_use_system_freetype2=false
skia_use_freetype_woff2=true
skia_compile_sksl_tests=false

is_debug=true
skia_use_client_icu=false
skia_use_bidi=false
skia_use_icu=true
skia_use_icu4x=false
skia_use_libgrapheme=false
skia_canvaskit_enable_bidi=false
skia_use_fontations=false
skia_enable_fontmgr_android=true
extra_cflags = [
     "-fomit-frame-pointer",
     "-mavx2",
     "-mfma",
     "-mf16c",
     "-DSK_USE_FREETYPE_EMBOLDEN",
]
cc="/usr/bin/clang"
cxx="/usr/bin/clang++"

Also, I used skia build system to build the test. It comes with some default list of settings that also could affect the result.
This is the part of ninja file that builds my test:
defines = -DSK_FONTMGR_FCI_AVAILABLE -DSK_FONTMGR_ANDROID_AVAILABLE -DSK_FONTMGR_FREETYPE_DIRECTORY_AVAILABLE -DSK_TYPEFACE_FACTORY_FREETYPE -DSK_FONTMGR_FREETYPE_EMBEDDED_AVAILABLE -DSK_FONTMGR_FREETYPE_EMPTY_AVAILABLE -DSK_FONTMGR_FONTCONFIG_AVAILABLE -DSK_CODEC_DECODES_ICO -DSK_CODEC_DECODES_PNG -DSK_CODEC_DECODES_PNG_WITH_LIBPNG -DSK_CODEC_ENCODES_PNG -DSK_CODEC_ENCODES_PNG_WITH_LIBPNG -DSK_GL -DSK_ENABLE_DUMP_GPU -DSK_CODEC_ENCODES_JPEG -DSK_SUPPORT_PDF -DSK_CODEC_DECODES_JPEG -DSK_CODEC_DECODES_JPEG_GAINMAPS -DSK_XML -DSK_CODEC_ENCODES_WEBP -DSK_ENABLE_ANDROID_UTILS -DSK_HAS_HEIF_LIBRARY -DSK_CODEC_DECODES_RAW -DSK_CODEC_DECODES_WEBP -DSK_HAS_WUFFS_LIBRARY -DSK_CODEC_DECODES_GIF -DSK_CODEC_DECODES_BMP -DSK_CODEC_DECODES_WBMP -DSK_R32_SHIFT=16 -DSK_ENABLE_PRECOMPILE -DSK_GANESH -DSK_USE_PERFETTO -DSK_ENABLE_PARAGRAPH -DSK_UNICODE_AVAILABLE -DSK_UNICODE_ICU_IMPLEMENTATION -DSK_SHAPER_PRIMITIVE_AVAILABLE -DSK_SHAPER_HARFBUZZ_AVAILABLE -DSK_SHAPER_UNICODE_AVAILABLE
framework_dirs =
include_dirs = -I../.. -Igen -I../../modules/skparagraph/include -I../../modules/skparagraph/utils -I../../modules/skshaper/include
cflags = -Wno-attributes -ffp-contract=off -fPIC -fvisibility=hidden -fstrict-aliasing -g -gdwarf-4 -fomit-frame-pointer -mavx2 -mfma -mf16c -DSK_USE_FREETYPE_EMBOLDEN -Wall -Wextra -Winit-self -Wpointer-arith -Wsign-compare -Wvla -Wno-deprecated-declarations -Wno-maybe-uninitialized -Wno-psabi -Wno-switch-default -Wno-unused-parameter -fcolor-diagnostics -Weverything -Wno-unknown-warning-option -Wno-weak-template-vtables -fno-lax-vector-conversions -Wno-nonportable-include-path -Wno-nonportable-system-include-path -Wno-cast-align -Wno-conversion -Wno-disabled-macro-expansion -Wno-documentation -Wno-documentation-unknown-command -Wno-double-promotion -Wno-exit-time-destructors -Wno-float-equal -Wno-global-constructors -Wno-missing-prototypes -Wno-missing-variable-declarations -Wno-pedantic -Wno-reserved-id-macro -Wno-reserved-identifier -Wno-shift-sign-overflow -Wno-signed-enum-bitfield -Wno-switch-enum -Wno-thread-safety-negative -Wno-undef -Wno-unreachable-code-break -Wno-unreachable-code-return -Wno-unused-macros -Wno-unused-member-function -Wno-non-c-typedef-for-linkage -Wno-cast-function-type-strict -Wno-covered-switch-default -Wno-deprecated -Wno-missing-noreturn -Wno-old-style-cast -Wno-newline-eof -Wno-padded -Wno-return-std-move-in-c++11 -Wno-shadow-field-in-constructor -Wno-shadow-uncaptured-local -Wno-zero-as-null-pointer-constant -Wno-declaration-after-statement -Wno-unsafe-buffer-usage -Wno-range-loop-analysis -Wrange-loop-construct -Wdeprecated-anon-enum-enum-conversion -Wdeprecated-array-compare -Wdeprecated-attributes -Wdeprecated-comma-subscript -Wdeprecated-copy -Wdeprecated-copy-dtor -Wdeprecated-dynamic-exception-spec -Wdeprecated-enum-compare -Wdeprecated-enum-compare-conditional -Wdeprecated-enum-enum-conversion -Wdeprecated-enum-float-conversion -Wdeprecated-increment-bool -Wdeprecated-register -Wdeprecated-this-capture -Wdeprecated-volatile -Wdeprecated-writable-str -Wextra-semi
cflags_cc = -fvisibility-inlines-hidden -std=c++17 -fno-exceptions -fno-rtti -Wnon-virtual-dtor -Wno-noexcept-type -Wno-abstract-vbase-init -Wno-weak-vtables -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-undefined-func-template
root_out_dir = .
target_output_name = paragraph_test

See if you find something missing on your side.

Cedric

unread,
Aug 5, 2025, 8:45:51 AMAug 5
to skia-discuss
Hello, so after a lot of debugging I final found the cause of the crash. In our build, we set this flag:  -D_GLIBCXX_USE_CXX11_ABI=0. And since when building Skia, this flag is not specified, it is considered to be 1 by default, hence an ABI incompatibility between Skia and our code. 
The ParagraphStyle structure has a std::u16string as member (in the header file) which is what corrupted the memory.

I will rebuild Skia with that flag set to 0, this should fix the issue.

jlav...@google.com

unread,
Aug 5, 2025, 10:17:06 AMAug 5
to skia-discuss
Thank you for clarifying that.
Reply all
Reply to author
Forward
0 new messages