rusty_v8 icon indicating copy to clipboard operation
rusty_v8 copied to clipboard

Terminating an isolate during module evaluation can crash V8

Open andreubotella opened this issue 3 years ago • 1 comments

This was found in Deno in denoland/deno#12658.

I suspect this is a V8 bug, as opposed to a rusty_v8 bug, but filing it here first just in case.

use std::sync::mpsc::{channel, Sender};
use std::thread::spawn;

fn module_instantiate<'a>(
  _: v8::Local<'a, v8::Context>,
  _: v8::Local<'a, v8::String>,
  _: v8::Local<'a, v8::FixedArray>,
  _: v8::Local<'a, v8::Module>,
) -> Option<v8::Local<'a, v8::Module>> {
  None
}

fn compile_module<'a>(
  scope: &mut v8::HandleScope<'a>,
  code: &'static str,
  origin: &'static str,
) -> v8::Local<'a, v8::Module> {
  let module_code = v8::String::new(scope, code).unwrap();
  let origin_string = v8::String::new(scope, origin).unwrap();
  let source_map_url = v8::undefined(scope);
  let script_origin = v8::ScriptOrigin::new(
    scope,
    origin_string.into(),
    0,
    0,
    false,
    0,
    source_map_url.into(),
    false,
    false,
    true,
  );
  let source =
    v8::script_compiler::Source::new(module_code, Some(&script_origin));
  v8::script_compiler::compile_module(scope, source).unwrap()
}

fn v8_main_thread(tx: Sender<v8::IsolateHandle>) {
  let platform = v8::new_default_platform(0, false).make_shared();
  v8::V8::initialize_platform(platform);
  v8::V8::initialize();

  let isolate = &mut v8::Isolate::new(v8::CreateParams::default());
  let scope = &mut v8::HandleScope::new(isolate);

  let context = v8::Context::new(scope);
  let scope = &mut v8::ContextScope::new(scope, context);

  let module = compile_module(
    scope,
    r#"
      // You need TLA to reproduce this crash.
      await Promise.resolve();
    "#,
    "test.js",
  );

  module
    .instantiate_module(scope, module_instantiate)
    .unwrap();

  tx.send(scope.thread_safe_handle()).unwrap();

  module.evaluate(scope).unwrap();
}

fn main() {
  let (tx, rx) = channel::<v8::IsolateHandle>();

  let thread_handle = spawn(move || v8_main_thread(tx));

  let isolate_handle = rx.recv().unwrap();
  isolate_handle.terminate_execution();

  thread_handle.join().unwrap();
}
#
# Fatal error in , line 0
# Check failed: (location_) != nullptr.
#
#
#
#FailureMessage Object: 0x7f47a48be130
==== C stack trace ===============================

    target/debug/worker_crash(+0x8ab7e3) [0x55c571c6f7e3]
    target/debug/worker_crash(+0x11591b) [0x55c5714d991b]
    target/debug/worker_crash(+0x8a53a5) [0x55c571c693a5]
    target/debug/worker_crash(+0x412de5) [0x55c5717d6de5]
    target/debug/worker_crash(+0x412641) [0x55c5717d6641]
    target/debug/worker_crash(+0x4120cd) [0x55c5717d60cd]
    target/debug/worker_crash(+0x411f1c) [0x55c5717d5f1c]
    target/debug/worker_crash(+0x124f2c) [0x55c5714e8f2c]
    target/debug/worker_crash(+0x107e5e) [0x55c5714cbe5e]
    target/debug/worker_crash(+0x10bceb) [0x55c5714cfceb]
    target/debug/worker_crash(+0x1033ce) [0x55c5714c73ce]
    target/debug/worker_crash(+0xef54b) [0x55c5714b354b]
    target/debug/worker_crash(+0xef873) [0x55c5714b3873]
    target/debug/worker_crash(+0xfbe53) [0x55c5714bfe53]
    target/debug/worker_crash(+0xfb933) [0x55c5714bf933]
    target/debug/worker_crash(+0xf9e13) [0x55c5714bde13]
    target/debug/worker_crash(+0xfc4cb) [0x55c5714c04cb]
    target/debug/worker_crash(+0xfc58b) [0x55c5714c058b]
    target/debug/worker_crash(+0xfc426) [0x55c5714c0426]
    target/debug/worker_crash(+0xf4d83) [0x55c5714b8d83]
    target/debug/worker_crash(+0xfb76b) [0x55c5714bf76b]
    target/debug/worker_crash(+0x10045e) [0x55c5714c445e]
    target/debug/worker_crash(+0xe516c3) [0x55c5722156c3]
    /lib64/libpthread.so.0(+0x9299) [0x7f47a4be8299]
    /lib64/libc.so.6(clone+0x43) [0x7f47a49c5353]
Trace/breakpoint trap (core dumped)

andreubotella avatar Nov 10 '21 07:11 andreubotella

Filed as a V8 bug: https://bugs.chromium.org/p/v8/issues/detail?id=12379

andreubotella avatar Nov 11 '21 08:11 andreubotella