-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compiling to WASM with emscripten, parse exception: attempted pop from empty stack / beyond block start boundary #91628
Comments
There is more talk happening here. Apparently it is related to thread local storage, but it is unknown if it is a problem with rustc or emscripten. I also don't know why it specifically appears for me with auto-dereferencing |
Sorry for the confusion. I don't think the parse issue you identified is related to thread local storage. It was just that when tlively was trying to reproduce your error, he had the same linker message that I get. And when I try your example program, I don't reproduce the parse exception, but instead get the thread local storage issue. |
With the latest emscripten/llvm from git, the linking error with thread local storage is fixed. See emscripten-core/emscripten#15891 |
Now I can confirm that I get the
...where I previously didn't get that error with zackradisic's repository. I'm getting that with other simple examples as well, with no references in the Rust code. Versions in question:
...and...
Interesting enough, the error does not occur on my example when using the same version of emscripten above, but using an older v1.59 that I had complied previously on my machine:
...but the error does occur with v1.60. |
Seems like the error message comes from here? |
wasm-validate doesn't seem to like the file that gets feed to
Running
|
I've put a few more details over at this repository which is a simple program that uses threads, and includes the wasm files for the working with the 1.59.0 compiler, and the broken wasm file from 1.60.0. |
Running cargo-bisect-rustc results in the following regression report for this issue:
|
Anyone have thoughts on the most likely patch from that merge to be the regression in question? Issue 92555 at least mentions threads in the description. |
I'm running into the same issue when compiling with threads on wasm32-unknown-emscripten target. I'm getting the generic error above about "pop from empty stack" when using with various binaryen tools:
but a more actionable error message near the same offset when compiling Wasm in Node.js:
Looks like some potential ABI mismatch or miscompilation issue in some monomorphisation of this function. |
@alexcrichton just for reality check - this couldn't be related to the Wasm ABI feature, because that one only affects wasm32-unknown-unknown and not wasm32-unknown-emscripten, right? |
@gregbuchholz I'm not sure the bisect start is right, because I'm getting the same issue when built with nightly-2021-12-06 too. |
Tried to extract the full name of the function by index, but it doesn't help much:
|
Oh interesting, looks like this only happens after optimizations. Wasm binary built in debug mode is fine. So it's definitely some miscompilation or, at least, wasm-opt issue. |
By playing with different optimisation options, narrowed it down a little further: it's the thread-local init callback in That said, it might just happen to be the first thread-local that parsing is failing on. |
This increasingly looks like an issue at the linking stage, because this same code compiled into individual cdylib instead of being linked with other C/C++, works just fine. |
Avoid __cxa_thread_atexit_impl on Emscripten - Fixes rust-lang#91628. - Fixes emscripten-core/emscripten#15722. See discussion in both issues. The TL;DR is that weak linkage causes LLVM to produce broken Wasm, presumably due to pointer mismatch. The code is casting a void pointer to a function pointer with specific signature, but Wasm is very strict about function pointer compatibility, so the resulting code is invalid. Ideally LLVM should catch this earlier in the process rather than emit invalid Wasm, but it currently doesn't and this is an easy and valid fix, given that Emcripten doesn't have `__cxa_thread_atexit_impl` these days anyway. Unfortunately, I can't add a regression test as even after looking into this issue for a long time, I couldn't reproduce it with any minimal Rust example, only with extracted LLVM IR or on a large project involving Rust + C++.
Avoid __cxa_thread_atexit_impl on Emscripten - Fixes rust-lang#91628. - Fixes emscripten-core/emscripten#15722. See discussion in both issues. The TL;DR is that weak linkage causes LLVM to produce broken Wasm, presumably due to pointer mismatch. The code is casting a void pointer to a function pointer with specific signature, but Wasm is very strict about function pointer compatibility, so the resulting code is invalid. Ideally LLVM should catch this earlier in the process rather than emit invalid Wasm, but it currently doesn't and this is an easy and valid fix, given that Emcripten doesn't have `__cxa_thread_atexit_impl` these days anyway. Unfortunately, I can't add a regression test as even after looking into this issue for a long time, I couldn't reproduce it with any minimal Rust example, only with extracted LLVM IR or on a large project involving Rust + C++.
Avoid __cxa_thread_atexit_impl on Emscripten - Fixes rust-lang#91628. - Fixes emscripten-core/emscripten#15722. See discussion in both issues. The TL;DR is that weak linkage causes LLVM to produce broken Wasm, presumably due to pointer mismatch. The code is casting a void pointer to a function pointer with specific signature, but Wasm is very strict about function pointer compatibility, so the resulting code is invalid. Ideally LLVM should catch this earlier in the process rather than emit invalid Wasm, but it currently doesn't and this is an easy and valid fix, given that Emcripten doesn't have `__cxa_thread_atexit_impl` these days anyway. Unfortunately, I can't add a regression test as even after looking into this issue for a long time, I couldn't reproduce it with any minimal Rust example, only with extracted LLVM IR or on a large project involving Rust + C++.
- Fixes rust-lang/rust#91628. - Fixes emscripten-core/emscripten#15722. See discussion in both issues. The TL;DR is that weak linkage causes LLVM to produce broken Wasm, presumably due to pointer mismatch. The code is casting a void pointer to a function pointer with specific signature, but Wasm is very strict about function pointer compatibility, so the resulting code is invalid. Ideally LLVM should catch this earlier in the process rather than emit invalid Wasm, but it currently doesn't and this is an easy and valid fix, given that Emcripten doesn't have `__cxa_thread_atexit_impl` these days anyway. Unfortunately, I can't add a regression test as even after looking into this issue for a long time, I couldn't reproduce it with any minimal Rust example, only with extracted LLVM IR or on a large project involving Rust + C++. r? @alexcrichton
Avoid __cxa_thread_atexit_impl on Emscripten - Fixes rust-lang/rust#91628. - Fixes emscripten-core/emscripten#15722. See discussion in both issues. The TL;DR is that weak linkage causes LLVM to produce broken Wasm, presumably due to pointer mismatch. The code is casting a void pointer to a function pointer with specific signature, but Wasm is very strict about function pointer compatibility, so the resulting code is invalid. Ideally LLVM should catch this earlier in the process rather than emit invalid Wasm, but it currently doesn't and this is an easy and valid fix, given that Emcripten doesn't have `__cxa_thread_atexit_impl` these days anyway. Unfortunately, I can't add a regression test as even after looking into this issue for a long time, I couldn't reproduce it with any minimal Rust example, only with extracted LLVM IR or on a large project involving Rust + C++.
TLDR: Auto-dereferencing seems to break compiling to WASM with emscripten when threads are enabled?
When compiling to WASM with threads enabled with emscripten I get the following error:
Full error from rustc
I narrowed down the code causing this and it seems related to auto-dereferencing. This is the section of code, and you can see the type of parameter
s
in the closure is multiple nested references (&&&str
or&&str
). This code does not compile.However, when I use a reference pattern to dereference the closure parameter, the code compiles and works as expected:
I also tested this theory by trying to compile the following code and it fails with the same error:
Note that this error only occurs when compiling Rust with threads.
You can view the repo with the full reproduction here.
The text was updated successfully, but these errors were encountered: