vurtun / nuklear

A single-header ANSI C gui library
13.7k stars 1.11k forks source link

runtime crashes when compiling to web-assembly #607

Open Deins opened 6 years ago

Deins commented 6 years ago

Hi, when i compile this library to web assembly (using emscripten) some functions cause nuklear to crash. For example nk_label_colored crashes when finishing frame (inside nk_convert) with error: chrome:

exception thrown: RuntimeError: integer result unrepresentable,RuntimeError: integer result unrepresentable
    at __ZL14nk_draw_vertexPvPK17nk_convert_config7nk_vec2S3_9nk_colorf (wasm-function[237]:548)
    at __ZL25nk_draw_list_push_rect_uvP12nk_draw_list7nk_vec2S1_S1_S1_8nk_color (wasm-function[252]:598)
    at _nk_draw_list_add_text (wasm-function[253]:1137)
    at _nk_convert (wasm-function[254]:4379)
    at __ZN3gfx6RenderEv (wasm-function[317]:3383)
    at __Z25OnPlatformRenderAndUpdatef (wasm-function[115]:916)
    at __Z12ProcessFramev (wasm-function[341]:321)
    at dynCall_v (wasm-function[442]:9)
    at Object.Module.dynCall_v (http://localhost/working/web/game.js:6286:37)
    at browserIterationFunc (http://localhost/working/web/game.js:2083:30)
printErr @ game.html:1249

firefox:

exception thrown: RuntimeError: integer overflow, __ZL14nk_draw_vertexPvPK17nk_convert_config7nk_vec2S3_9nk_colorf@http://localhost/working/web/game.js:211454:1
__ZL25nk_draw_list_push_rect_uvP12nk_draw_list7nk_vec2S1_S1_S1_8nk_color@http://localhost/working/web/game.js:224674:1
_nk_draw_list_add_text@http://localhost/working/web/game.js:226039:1
_nk_convert@http://localhost/working/web/game.js:230480:1
__ZN3gfx6RenderEv@http://localhost/working/web/game.js:311664:1
__Z25OnPlatformRenderAndUpdatef@http://localhost/working/web/game.js:5964:1
__Z12ProcessFramev@http://localhost/working/web/game.js:327024:1
dynCall_v@http://localhost/working/web/game.js:363404:1
Module.dynCall_v@http://localhost/working/web/game.js:6286:10
browserIterationFunc@http://localhost/working/web/game.js:2083:11
runIter@http://localhost/working/web/game.js:2200:13
Browser_mainLoop_runner@http://localhost/working/web/game.js:2138:9
game.html:1249:13
RuntimeError: integer overflow

Regular labels work without problems. Also x86 or x64 builds and runs without any problems. I have integrated nuklear in my own opengl pipeline, but that doesn't seem to be the problem, as the nuklear crashes when building the vertex buffers internally. I haven't really learned how to debug wasm, however i found that the crashing instruction lays inside nk_draw_vertex near the while cycle or in the nk_draw_vertex_layout_element_is_end_of_layout. Does nuklear intentionally use integer overflow? Or maybe use some unaligned reads or something other unportable which could cause these problems?

P.S. asm.js build with emscripten also runs without problems.

example code:

if (nk_begin(&ctx, "Test", nk_rect(350, 0, 220, 220), NK_WINDOW_BORDER | NK_WINDOW_MOVABLE | NK_WINDOW_CLOSABLE))
{
    nk_layout_row_static(&ctx, 30, 80, 1);
    nk_label(&ctx, "Hello World!", NK_TEXT_ALIGN_LEFT);
    nk_label_colored(&ctx, "Hello Color!", NK_TEXT_ALIGN_LEFT, nk_color{ 255,222,0,255 }); // this crashes in wasm, without this the code runs fine
}
nk_end(&ctx);
Deins commented 6 years ago

Ok this issue is really weird and i am almost starting to think it is compiler bug or something like that, and not nuklear fault. The issue only happens in optimized build, debug build runs fine .

Deins commented 6 years ago

the issue can be fixed with compiler/linker option -s "BINARYEN_TRAP_MODE='clamp'" but it adds some small performance overhead. If anybody wants to play around with web-assembly and try find the real cause for this issue I created a minimalistic example here: https://github.com/Deins/nuklear_wasm_bug_test

dumblob commented 6 years ago

How does it behave with -O2? I'm asking, because e.g. RedHat compiles the whole Enterprise Linux and packages with -O2 and not -O3, because -O3 makes some unsafe optimizations. Not sure though whether emcc does also all possible safe optimizations for -O2 and turns on some unsafe optimizations for -O3.

tanis2000 commented 6 years ago

the issue can be fixed with compiler/linker option -s "BINARYEN_TRAP_MODE='clamp'" but it adds some small performance overhead. If anybody wants to play around with web-assembly and try find the real cause for this issue I created a minimalistic example here: https://github.com/Deins/nuklear_wasm_bug_test

Your post just saved my day and I managed to push out my entry for LD43, but still it looks like it's very slow on Windows, while on macOS it works fine.

It would be nice to correct the real issue though. It looks like most of them are just integer overflows.

tanis2000 commented 5 years ago

I opened a new issue there https://github.com/vurtun/nuklear/issues/774 with all the information I've put together over the past weekend.