On Friday, November 8, 2019 at 8:27:13 PM UTC-5, Sam Clegg wrote:
IIUC the stack limit of the VM is implementation defined and
> can't be relied upon which means that currently I don't think its
> possible to do what you are trying to do.
>
Alas. :-( To try and establish a sort of baseline about stack overflow
handling in JavaScript hosts, I posted a question on...Stack Overflow:
https://stackoverflow.com/q/58908855/
<https://stackoverflow.com/questions/58908855/what-if-any-javascript-operations-are-guaranteed-not-to-cause-stackoverflow-ra#58908855>
It's my attempt to clear the air a bit about whether or not there is such a
thing as "safe" recovery from a JavaScript out-of-stack RangeError. My
suspicion seems to be confirmed--that the JS spec does not have the
systemic rigor to support it coherently. Even if there's some level at
which a particular engine guarantees atomicity to avoid certain internal
corruptions, the portions of the language implemented in JavaScript itself
would likely not have any such bulletproofing. That's to say nothing of
your own usermode code, which cannot maintain invariants when there's no
firm ground to stand on.
There's a suggestion that coding directly in Wasm could offer enough
confidence to build some kind of transaction mechanic. But with C being a
layer of abstraction atop that, I do not believe Emscripten has this
safety. e.g. the following code was always was in state `1` when the
RangeError is trapped...and I'd guess that's the internals of malloc():
int state = 0; // 1=malloc(), 2=free(), 3=recurse() itself
EMSCRIPTEN_KEEPALIVE
void recurse(int depth) { // I called this from a JS try...catch
if (depth == 0)
return;
state = 1;
void *dummy = malloc(depth); // overflowed in here
state = 2;
free(dummy);
state = 3;
recurse(depth - 1);
state = 0;
}
I don't know an easy way to *prove* the heap can get corrupted by this. If
anyone can build a repro case that does so, that might be an interesting
emscripten GitHub issue for anyone researching the topic to find (even if
resolved: WontFix) Maybe there's a clang equivalent to mcheck() to get
this proof?
...BUT what I'd really like to see would be something in the tooling that
helped mitigate this. It is unfortunate to force people into a
shallow-stack custom bytecode interpreter just to get the sole benefit of
(hopeful) safe recovery from stack overflows. I'll re-suggest that
building to Wasm and having the hooks into the compiler (like those used to
accomplish Asyncify) could permit a stack cost model, and you could choose
to force a stack overflow *before* running operations that might otherwise
overflow in mid-operation. Analogous to:
void transaction(void) {
void *data = malloc(...);
/* dostuff */
free(data);
}
void whatever(void) {
/* ... */
crash_if_not_enough_stack_for(transaction);
transaction(); // guaranteed to run if we get here
/* ... */
}
Again: I'm aware that you can abstract away the C into your own universe
where you attempt something analogous (though much slower). It's just
frustrating to already be inside of virtualized machines when doing so--and
to be operating on guesswork even then--with the ball punted from '89
getting kicked even further down the road. :-/ If Wasm could be a turning
point to more of a RTOS/embedded mindset, that could really help raise the
bar on software reliability...and strengthen the argument for Wasm as the
future.
Best,
--Brian
http://hostilefork.com
--
You received this message because you are subscribed to the Google Groups
"emscripten-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/emscripten-discuss/49342172-e6b3-4437-b547-025f387e6b39%40googlegroups.com.