Skip to content

Crash after 32k calls to findProxyForURL due to quickjs in pac-resolver #333

Description

@weikinhuang

Hi, I'm running into an issue where quickjs will crash with an uncatchable error after 32k (2^15) calls to the compiled findProxyForURL function.

32759 SOCKS5 127.0.0.1:29001
32760 SOCKS5 127.0.0.1:29001
[C to host error: returning null] Error: QuickJSContext had no callback with id -32768
    at Object.callFunction (/Users/wehuang/source/http-proxy-via-socks/node_modules/@tootallnate/quickjs-emscripten/dist/context.js:117:27)
    at /Users/wehuang/source/http-proxy-via-socks/node_modules/@tootallnate/quickjs-emscripten/dist/module.js:36:31
    at QuickJSModuleCallbacks.handleAsyncify (/Users/wehuang/source/http-proxy-via-socks/node_modules/@tootallnate/quickjs-emscripten/dist/module.js:145:23)
    at QuickJSEmscriptenModuleCallbacks.callFunction (/Users/wehuang/source/http-proxy-via-socks/node_modules/@tootallnate/quickjs-emscripten/dist/module.js:30:80)
    at o (/Users/wehuang/source/http-proxy-via-socks/node_modules/@tootallnate/quickjs-emscripten/dist/generated/emscripten-module.WASM_RELEASE_SYNC.js:277:92)
    at wasm://wasm/001bd82a:wasm-function[1084]:0x54415
    at wasm://wasm/001bd82a:wasm-function[893]:0x49249
    at wasm://wasm/001bd82a:wasm-function[216]:0xc7e6
    at wasm://wasm/001bd82a:wasm-function[33]:0x2002
    at wasm://wasm/001bd82a:wasm-function[1008]:0x512d6

Here's the test script I'm using.

import { createPacResolver } from 'pac-resolver';
import { getQuickJS } from '@tootallnate/quickjs-emscripten';

const pac = `
function FindProxyForURL(url, host) {
  if (shExpMatch(host, "127.0.0.1")) {
    return "DIRECT";
  }
  if (shExpMatch(url, "*foo.*")) {
    return "SOCKS5 127.0.0.1:29001";
  }
  return "DIRECT";
}
`;

process.on('unhandledRejection', (reason, promise) => {
  // never gets here
  console.log('Unhandled Rejection at:', promise, 'reason:', reason);
  process.exit(1);
});
process.on('uncaughtException', (err) => {
  // never gets here
  console.error('There was an uncaught error', err);
  process.exit(1);
});

async function main() {
  const findProxyForURLPromise = Promise.all([getQuickJS()]).then(([qjs]) => createPacResolver(qjs, pac));
  const findProxyForURL = await findProxyForURLPromise;

  for (let i = 0; i < 100000; i++) {
    try {
      const result = await findProxyForURL('http://foo.com/', 'foo.com');
      console.log(i, result);
    } catch (e) {
      // never gets here
      console.log(`Error at ${i}`);
      console.error(e);
      throw e;
    }
  }
  // never gets here
  console.log('im done');
}

try {
   main();
} catch (e) {
  // never gets here
  console.log('main exited with error', e);
}

I'm running this in a server application, if I create a new findProxyForURLPromise on each request, it will cause a memory leak.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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