Open alexcrichton opened 1 year ago
Also cc @abrown on this since, by default, compiling with threads sets --max-memory
to the base size of memory, so any C++ application compiling with threads will run into this until they specify a --max-memory
as well. (mostly something for documentation for now)
For comparison, here is what emscripten does:
That code will abort rather than return 0 from new
. In practice that avoids a lot of difficult-to-debug situations like what you hit @alexcrichton , and I'm not a spec expert but I think it's acceptable since per the spec you can always add a system set_new_handler
that aborts anyhow. We've had this behavior for many years and have not had complaints from users that I can recall.
Slightly complicating this is that emscripten also does the same for malloc
and not just new
:
That is definitely nonstandard (but very useful for the above reason) and so we have an option to turn that off (to return 0 from malloc), which some users require as they want to recover from OOMs.
Ah makes sense, and thanks for the links! My sense of spec compliance originated from libcxx's current source where the intention seems to be to return NULL
, but if that's the route to go to handle this then this is moreso an issue for wasi-sdk
rather than wasi-libc
since that's where the libcxx
library is built. (and perhaps I should have opened this issue over there instead of here...)
This example program is intended to allocate 4 wasm pages of memory:
This can be compiled to have a max wasm memory size of 2 pages, though, which will cause the program to OOM at runtime:
which produces foo.wasm.gz.
When run:
this program will (currently for me) infinite loop.
The issue seems to be that when compiled with
-fno-exceptions
, which I believe is currently required of C++ code compiled with wasi-libc to wasm since__cxa_throw
isn't otherwise defined, then theoperator new
operator is defined to returnNULL
for failed allocations. For a native platform this is fine because it probably faults quickly when accessing this address. For Wasm, however, this is a valid address so the program keeps going.This was, for me, an unfortunately slow way for me to discover that the original program I was working with was OOM-ing and needed a
--max-memory
argument to be passed that was larger than the base. I'm not sure how best to improve this, though, since I suspect aborting on failure would not be spec-compliant with C++.