Skip to content

Aborted(Assertion failed) on timeout of an async function #90

@phuhl

Description

@phuhl

Describe the bug
Running this code sandboxed:

     env.asyncFn("test")
       .then(r => env.asyncFn(r))
       .then(r => env.asyncFn(r))
       .then(r => env.asyncFn(r))
       .then(r => env.log(r));

Where asyncFn as passed to env is:

    const asyncFn = async (...args) => {
      return new Promise((resolve) => {
        setTimeout(() => resolve("done"), 100);
      });
    };

Crashes differently then a normal timeout. I set the timeout to 100 and got this stack:

RuntimeError: Aborted(Assertion failed: list_empty(&rt->gc_obj_list), at: ../../vendor/quickjs-ng/quickjs.c,1954,JS_FreeRuntime). Build with -sASSERTIONS for more info.
    at M (<project redacted>/node_modules/@jitl/quickjs-ng-wasmfile-release-sync/dist/emscripten-module.mjs:15:65)
    at b (<project redacted>/node_modules/@jitl/quickjs-ng-wasmfile-release-sync/dist/emscripten-module.mjs:22:315)
    at null.<anonymous> (wasm://wasm/001d15c2:1:210136)
    at null.<anonymous> (wasm://wasm/001d15c2:1:316245)
    at QuickJSFFI.c._QTS_FreeRuntime [as QTS_FreeRuntime] (<project redacted>/node_modules/@jitl/quickjs-ng-wasmfile-release-sync/dist/emscripten-module.mjs:30:95)
    at _Lifetime.disposer (<project redacted>/node_modules/quickjs-emscripten-core/src/module.ts:336:16)
    at _Lifetime.dispose (<project redacted>/node_modules/quickjs-emscripten-core/src/lifetime.ts:177:12)
    at _Scope.dispose (<project redacted>/node_modules/quickjs-emscripten-core/src/lifetime.ts:341:18)
    at QuickJSRuntime.dispose (<project redacted>/node_modules/quickjs-emscripten-core/src/runtime.ts:130:23)
    at _Scope.dispose (<project redacted>/node_modules/quickjs-emscripten-core/src/lifetime.ts:341:18)

To Reproduce

import { type SandboxOptions, loadQuickJs } from "@sebastianwessel/quickjs";
import variant from "@jitl/quickjs-ng-wasmfile-release-sync";

const options: SandboxOptions = {
  // allowFetch: true,
  // allowFs: false,
  executionTimeout: 100,
  memoryLimit: 1024 * 1024,
  env: {
    log: (p) => console.log(p),
    asyncFn: () => async (...args) => {
      return new Promise((resolve) => {
        setTimeout(() => resolve("done"), 100);
      });
    }
  },
};


const result = await runSandboxed<unknown>(async ({ evalCode }) => {
  return evalCode(`
     env.asyncFn("test")
       .then(r => env.asyncFn(r))
       .then(r => env.asyncFn(r))
       .then(r => env.asyncFn(r))
       .then(r => env.log(r));
    `);
}, options);

Steps to reproduce the behavior:

  1. Run the above code with a timeout of 100
  2. See error

Expected behavior
An "InternalError" with message "interrupted".

Desktop (please complete the following information):

  • OS: linux
  • nodejs: 22.14.0
  • Version
    "@jitl/quickjs-ng-wasmfile-release-sync": "^0.31.0",
    "@sebastianwessel/quickjs": "^3.0.0",

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions