[quickjs-devel] Re: stackoverflow

  • From: hj@xxxxxxxxx
  • To: quickjs-devel@xxxxxxxxxxxxx
  • Date: Tue, 13 Aug 2019 11:19:07 +0000


Quoting Charlie Gordon <qemacs@xxxxxxxxxxx>:

Hi guys,

Are you calling JS_Eval() from a different thread than the one where the JSRuntime or the JSContext were instantiated?

No, the JSContext is used in a single thread. But at the place where the JSContext is created, the c stack may be much deeper than at the place where JS_Rval is called.

QuickJS does not support multi-threading at the moment and is unlikely with the curent implementation to allow concurrent access to the same JSRuntime.

Yet calling JS_Eval and possibly other APIs from different threads sequentially, without concurrent access, as from workers, should be possible.

The problem is in the curent method used to detect stack overflow: we want to have a very efficient test for this and compare the current stack frame address with a reference value ctx->stack_top, set from an earlier observation of the said stack frame address, to determine if the exceeds ctx->stack_size. As noted by Alexander, the test was broken in the first release because the current stack depth `ctx->stack_top - js_get_stack_pointer()` was assumed to be non negative and stored in a `size_t`.

Changing the type to `ptrdiff_t` is not a correct fix: a negative stack depth is indicative of something fishy, such as calling `js_check_stack_overflow()` from a stack frame that is not a descendant of the one where `ctx->stack_top` was set. Calling from a different thread is a good example.

I think that in my case there is nothing fishy going on. Just the c stack being very deep at the moment the JSContext is created. I think the solution of using ptrdiff_t would work in my case.

There are multiple solutions, a combinaison of which should fix the issue:

* set `ctx->stack_top` in JS_Eval(), but this would prevent stack overflow detection in cases where javascript and C code are nested recursively.
* detecting calls from different threads in JS_Eval and other APIs, and set `ctx->stack_top` only in this case.
* make `stack_top` a _Thread_local variable instead of a member of JSContext, and set it one way or another for every thread that invokes the compiler/interpreter

We should also prevent stack overflows in the compiler.

Both of these issues will be fixed in an upcoming release.

In the mean time, you can disable stack overflow checks in your applications by changing the `#if defined(EMSCRIPTEN)` to `#if 1` above the definition of `js_get_stack_pointer()`.

That is what I have been doing to fix it temporarily.

Best regards

Chqrlie.


Thanks,

Huib-Jan


Other related posts: