Sorry if there's a topic where this is already discussed, I just couldn't find it.
I'm migrating from 1.39.16 to 2.0.10, and most if it has been straight forward, and documented in the release notes.
However, it seems my global initializers aren't called.
My code that is misbehaving:
const dmhash_t PROP_EULER = dmHashString64("euler");
At runtime, this value PROP_EULER is 0, and I've put a print in the dmHashString64() and it doesn't output anything.
A simpler test also failed:
struct MyTest
{
MyTest() {
printf("MyTest: printf\n");
dmLogWarning("MyTest: log warning\n");
}
} g_TestInitializer;
My command lines haven't changed from 1.39.16 to 2.0.10:
gameobject.cpp:
./emsdk-2.0.10/upstream/emscripten/em++ -O3 -Wall -fPIC -fno-exceptions -fno-rtti -DGL_ES_VERSION_2_0 -DGOOGLE_PROTOBUF_NO_RTTI -D__STDC_LIMIT_MACROS -DDDF_EXPOSE_DESCRIPTORS -s WASM=1 -s LEGACY_VM_SUPPORT=0 -s DISABLE_EXCEPTION_CATCHING=1 -s AGGRESSIVE_VARIABLE_ELIMINATION=1 -s PRECISE_F32=2 -s EXTRA_EXPORTED_RUNTIME_METHODS=["stringToUTF8","ccall","stackTrace","UTF8ToString","callMain"] -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s TOTAL_MEMORY=268435456 -s LLD_REPORT_UNDEFINED -Idefault/src/gameobject -I../src/gameobject -Idefault/src -I../src -Idefault/proto -I../proto -Idefault/src/dmsdk -I../src/dmsdk -I./ext/include -I./sdk/include -I./include -I./include/wasm-web -I./ext/include/wasm-web -DDLIB_LOG_DOMAIN="GAMEOBJECT" ../src/gameobject/gameobject.cpp -c -o default/src/gameobject/gameobject_1.o
Linker:
./emsdk-2.0.10/upstream/emscripten/em++ default/src/__exported_symbols_5_5.o default/src/common/main_5.o -o /Users/mawe/work/defold/engine/engine/build/default/src/dmengine.js -O3 -Wno-warn-absolute-paths --emit-symbol-map --memory-init-file 0 -lidbfs.js -s WASM=1 -s LEGACY_VM_SUPPORT=0 -s DISABLE_EXCEPTION_CATCHING=1 -s AGGRESSIVE_VARIABLE_ELIMINATION=1 -s PRECISE_F32=2 -s EXTRA_EXPORTED_RUNTIME_METHODS=["stringToUTF8","ccall","stackTrace","UTF8ToString","callMain"] -s ERROR_ON_UNDEFINED_SYMBOLS=1 -s TOTAL_MEMORY=268435456 -s LLD_REPORT_UNDEFINED -s EXPORTED_FUNCTIONS=["_JSWriteDump","_dmExportedSymbols","_main"] -Ldefault/src -L./lib/wasm-web -L./ext/lib/wasm-web -lengine -lengine_service -lwebviewext -lprofilerext -lfacebookext -liapext -lpushext -liacext -lgameobject -lddf -lliveupdate -lresource -lgamesys -lphysics -lBulletDynamics -lBulletCollision -lLinearMath -lBox2D -lrecord_null -lrender -lscript -llua -lextension -lhid -linput -lparticle -lrig -ldlib -lmbedtls -lzip -lgui -lcrashext -lgraphics -ldmglfw -lsound --js-library ./lib/wasm-web/js/library_glfw.js --js-library ./lib/wasm-web/js/library_sys.js --js-library ./lib/wasm-web/js/library_script.js --js-library ./lib/wasm-web/js/library_sound.js
What am I missing? (I'm sure it's something obvious)
Can you reduce this to simple example that we can reproduce on our end. The example you posted seems to work fine for me:
$ cat test.cc
#include <stdio.h>
struct MyTest
{
MyTest() {
printf("MyTest: printf\n");
}
} g_TestInitializer;
int main() {
printf("main\n");
}
$ ./emcc test.cc
$ node a.out.js
MyTest: printf
main
Bear in mind that the constructor will only be called if the object file in which it is defined ends up being required by the linker. Could that me related?
Sure. It will ofc take some time, and I'll have to postpone it to later this week.
As for the PROP_EULER variable, it's required by a function in the same .cpp file, but at runtime the value (checked in this function) is 0, and not the correct value. Note that I haven't changed any code or command line between the 1.39.16 and 2.0.10.
Very strange. You aren't using dynamic linking are you? (MAIN_MODULE or SIDE_MODULE, or compiling with -fPIC?)
The command lines (see above) contain -fPIC yes.
Do you need -fPIC? Can you try without to see if it is the cause (either way we need to fix it but it would help to know if its related to that flag).
I'll check.
It's there since it's such a common flag for all the other platforms.
No luck with removing -fPIC
I think we need some kind of repro case to investigate further.
Here is a small example where this manifests itself:
emscripten-issue-13038.tar.gz
Compile with:
emscripten-issue-13038 $ ./build.sh
Wrote ./libjson.a
Wrote ./libcrash.a
Wrote ./libtest.a
wrote issue.js
emscripten-issue-13038 $ node issue.js
main
position: hash: 375
PROP_POSITION: hash: 0
FAILED
There's nothing fancy going on, simply libraries that call functions from other libraries.
And there are several ways to make it magically work:
*) comment out test.cpp:27:
//m_Struct.Set(64);
*) comment out test.cpp:12:
//assert(m_Value != 0 && "some message");
This is what the output says if the code worked:
emscripten-issue-13038 $ node issue.js
Global Initializer: yes!
main
position: hash: 375
PROP_POSITION: hash: 375
I hope this helps!
@JCash Thanks for the testcase - this looks like a linker bug to me too. test.o is included, as can be seen from other code from it being present, but the constructor is not... and commenting out the (unrelated) assertion makes it work, which seems bizarre.
I don't know enough about lld to debug it any further, though.
Could be this know bug perhaps? : https://bugs.llvm.org/show_bug.cgi?id=48156
Sounds like it could be, yes! Symptoms match.
Thanks for the help!
I expect I'll have to wait some more months before I try to upgrade again.
And, I cannot in good faith recommend anyone else to do so either, given the severity.
Given the nature of the issue, it seems pretty "random" when you'll get a working app.
Will you notify the users somehow?
I'm not sure how to convince the wasm-ld ppl how to upgrade the issue from "normal" to something more urgent, since it's a quite severe issue?
Sorry for being such a gloom, I know how frustrating such things can be.
@JCash One thing you can do to speed this up is to bisect this. Confirming it is the suspected lld commit in that lld issue would help get more focus on this.
Another option is to check if https://bugs.llvm.org/show_bug.cgi?id=48156#c1 fixes the issue, which would also confirm things.
Indeed if you can confirm that the wasm-ld bug is the one you are seeing then that would increase the urgency with which we address it. (I'm the primary maintainer of wasm-ld so we are the same people).
@kripken did you repro this failure? Can you perhaps confirm that the wasm-ld issue is the one at play here?
Sure, I'll give it a shot this weekend.
(I have to continue on my other tasks for now)
@sbc100 I did run the testcase here and verified it failed. I did not have time to bisect, make a custom LLVM, or look into it any further. @JCash if you can't get to it on the weekend I can try to find time for that.
I think this should be fixed by https://github.com/llvm/llvm-project/commit/cb77e877f8132b885fcac8b7532c58072537b9ed
That fix is in the new 2.0.11 release.
Thank you for the fix!
Small note about changelogs:
I see that the updated change log here: https://github.com/emscripten-core/emscripten/blob/master/ChangeLog.md
But the changelog on the webpage doesn't seem to have been updated in two weeks?
https://emscripten.org/docs/introducing_emscripten/release_notes.html
I updated the site now, and the changelog looks correct.