emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.75k stars 3.3k forks source link

SDL2 TTF_RenderText_Solid Produces "alignment fault" when compiled with -s SAFE_HEAP=1 #14870

Open benjamin-t-brown opened 3 years ago

benjamin-t-brown commented 3 years ago

When compiling an SDL2 program that uses the SDL2_TTF library, I noticed that compiling with -s SAFE_HEAP=1 causes the application to crash whenever a call is made to render some text.

This small repository recreates this behavior: https://github.com/benjamin-t-brown/emscripten_sdl2_ttf_example

As a summary:

  SDL_Init(SDL_INIT_VIDEO);
  TTF_Init();

  SDL_Window *window= SDL_CreateWindow("SDL_ttf in SDL2", SDL_WINDOWPOS_UNDEFINED,
                            SDL_WINDOWPOS_UNDEFINED, 512, 512, 0);
  SDL_Renderer *renderer= SDL_CreateRenderer(window, -1, 0);
  TTF_Font *font = TTF_OpenFont("assets/monofonto.ttf", 25);
  SDL_Color color = {255, 255, 255};
  SDL_Surface *surface = TTF_RenderText_Solid(font, "Welcome to TTF Test", color);

When run in a web page, the code errors at TTF_RenderText_Solid with an alignment fault Uncaught (in promise) RuntimeError: abort(alignment fault) at Error... When run with the output of a gcc compiler, no alignment errors are found.

This code was compiled with the following:

em++ Test.cpp -g -O0 -s USE_SDL=2 -s USE_SDL_TTF=2 -s ALLOW_MEMORY_GROWTH=1 -s SAFE_HEAP=1 -s WARN_UNALIGNED=1 -s DISABLE_EXCEPTION_CATCHING=0 -s DEMANGLE_SUPPORT=1 -s ASSERTIONS=2  -s EXPORTED_FUNCTIONS='["_main"]' -s EXPORTED_RUNTIME_METHODS=['ccall'] --preload-file assets -o .build/test.js

Version

em++ --version
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 2.0.27 (7e538a419c3649f3a540a57beab347aa8f6c6271)
Copyright (C) 2014 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
adam4235 commented 2 years ago

I also found this same issue. I have Emscripten 3.1.8.

adam4235 commented 2 years ago

I was wondering also if it's actually a bug in SDL TTF, and there's a better place to report it? But if it is, then why doesn't valgrind find any errors?

kripken commented 2 years ago

Valgrind may not consider an unaligned read as an error. That does work on x86 and modern ARM. It also works in wasm (but not wasm2js).

btw, if you do not want to check for unaligned accesses you can use -sSAFE_HEAP=2, see

https://github.com/emscripten-core/emscripten/blob/cde710ccdd62022d933e388bdad47ad510dd3aee/src/settings.js#L305-L314

adam4235 commented 2 years ago

Ah OK. Indeed when I use SAFE_HEAP=2 it doesn't crash anymore (it still gives an "alignment fault" message). Does that mean it's not a bug in SDL TTF but just something suboptimal?

kripken commented 2 years ago

It is not optimal, yeah, as on some CPUs unaligned accesses are slow. So you might want to file an issue for the upstream project. But they might not consider it a bug, depending on what CPUs they care about, and whether this happens in performance-sensitive code or not, etc.

1bsyl commented 2 years ago

you can try to edit SDL_ttf.c

somehow comment out this : and alignment copy should be always 1. but is it faster / slower ?

 93 /* Round glyph to 16 bytes width and use SSE2 instructions */
  94 #if defined(__SSE2__)
  95 #  define HAVE_SSE2_INTRINSICS 1
  96 #endif
  97 
  98 /* Round glyph width to 16 bytes use NEON instructions */
  99 #if 0 /*defined(__ARM_NEON)*/
 100 #  define HAVE_NEON_INTRINSICS 1
 101 #endif
 102 
 103 /* Round glyph width to 8 bytes */
 104 #define HAVE_BLIT_GLYPH_64
 105 
 106 /* Android armeabi-v7a doesn't like int64 (Maybe all other __ARM_ARCH < 7 ?),
 107  * un-activate it, especially if NEON isn't detected */
 108 #if defined(__ARM_ARCH)
 109 #  if __ARM_ARCH < 8
 110 #    if defined(HAVE_BLIT_GLYPH_64)
 111 #      undef HAVE_BLIT_GLYPH_64
 112 #    endif
 113 #  endif
 114 #endif
adam4235 commented 8 months ago

I think this might be fixed because the underlying issue is fixed in SDL TTF 2.22? https://github.com/libsdl-org/SDL_ttf/issues/192

But it's not easy for me to check because my operating system hasn't updated to that version of SDL_TTF and it's not obvious to me how to custom install that specific version and have Emscripten use it. Perhaps I'll keep trying and / or check in the future, but if it's easy for someone else to verify and close this issue, please do.

sbc100 commented 8 months ago

Oh nice.. I guess we should update SDL_ttf and add a test