OOM crash on chrome with reasonable-looking code.
$ git clone https://github.com/derekdreery/dodrio-realworld-starter-kit.git$ git checkout e6c51ddd9ef63d6a54f6eedc7c742283e8fb1bc5$ cd wasm-history$ wasm-pack test --headless --chromeTests run fast and pass
OOM crash of chromium. I know it's OOM because I started chromium on the command line and got the following output:
[30:150:0408/153808.743127:FATAL:memory_linux.cc(42)] Out of memory.
[30:149:0408/153808.743124:FATAL:memory_linux.cc(42)] Out of memory.
In Firefox the tests complete but take much longer than they should.
For me, this issue isn't a problem any more, because I stopped parsing the URL and the crash stopped happening. However, I'm pretty sure it's a bug somewhere, so I should report here to get to the bottom of it.
Are there techniques to inspect the stack etc. in wasm? Could I use these to see what's going on inside the wasm code in chromium?
Alternatively, can anyone else work out what's going on?
This problem arose during https://github.com/rustwasm/gloo/issues/70
Running without --headless and opening this in Chrome does indeed crash the tab. (works in Firefox). This seems like it may be a Chrome bug rather than a wasm-bindgen bug, but can you perhaps try to minimize it to see what's triggering the issue?
@alexcrichton I also found unexpected behavior in firefox. The test took about 10s to run. Without using the URL crate tests run in about 5ms. It feels like there is a problem in firefox as well for me, but I'm interested if other people see the same behavior.
Ok I've done the best I can to reverse this, but this is unfortunately far deeper than wasm-bindgen. I do not personally have time to keep investigating this. If you're intersted in seeing this resolved it'd likely and LLVM/LLD/Chrome/v8 bug somewhere along the way, although I've got no idea where. So far this program is what I've minimized it to which crashes in Chrome but passes in Firefox:
use unicode_normalization::*;
#[no_mangle]
pub extern fn run() {
for x in "test".nfc() {
}
}
I'm not really sure why, but in any case this isn't a wasm-bindgen bug so I'm going to close.
Thanks for looking into this!
I've found that with release mode on your code (and the original) work fine! Out of curiosity I've done some more digging, and the code that gets generated (i.e. the wasm) is weird. (I'm not an expert and anything below may be incorrect).
I think the function that's doing it is tables::canonical_fully_decompose. It seems the massive match statement generates wasm that chrome (crashes) and firefox (slow) doesn't like. It seems to create some sort of massive state machine that jumps all around these different blocks, and because there is no goto in wasm it has to do it using nested blocks and the break statement. Something about this must disagree with chrome, maybe they allocate a lot for each block of nesting, or they only allow a small amount of mem for each wasm process. Either way it blows up.
Hope this is interesting to you and you don't feel like you wasted time on this!
Ah yeah release mode "fixing" the bug makes sense, mostly because the test case isn't doing anything so LLVM is smart enough to remove everything. A massive match statement makes sense, I was looking for something like that! The behavior I saw was that simply including functionality (even if it wasn't called) would cause the tab to crash, and if it's a massive match statement that sounds like the WebAssembly compiler in v8 is probably choking during compilation and crashing the tab.
If you can get a single WebAssembly file and upload it that would likely be useful for the v8 developers!