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.

Reply via email to