summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2022-11-26 23:09:48 +0100
committerGitHub <noreply@github.com>2022-11-26 23:09:48 +0100
commit3a320db27014925bb40f10dd4e706302bc06c1f1 (patch)
tree5b5b8bd9a925960a454b825949c950b09467c7b4
parentd8ab492d016f45346002ae0e9bceac7e900b670a (diff)
fix(inspector): send "isDefault" in aux data (#16836)
With trial and error I found that most debuggers expect "isDefault" to be sent in "auxData" field of "executionContextCreated" notification. This stems from the fact that Node.js sends this data and eg. VSCode requires it to close connection to the debugger when the program finishes execution.
-rw-r--r--cli/tools/repl/session.rs14
-rw-r--r--core/inspector.rs18
-rw-r--r--core/runtime.rs11
-rw-r--r--runtime/worker.rs1
4 files changed, 36 insertions, 8 deletions
diff --git a/cli/tools/repl/session.rs b/cli/tools/repl/session.rs
index e3bdac3b2..361f5abb5 100644
--- a/cli/tools/repl/session.rs
+++ b/cli/tools/repl/session.rs
@@ -92,17 +92,19 @@ impl ReplSession {
for notification in session.notifications() {
let method = notification.get("method").unwrap().as_str().unwrap();
let params = notification.get("params").unwrap();
-
if method == "Runtime.executionContextCreated" {
- context_id = params
- .get("context")
+ let context = params.get("context").unwrap();
+ assert!(context
+ .get("auxData")
.unwrap()
- .get("id")
+ .get("isDefault")
.unwrap()
- .as_u64()
- .unwrap();
+ .as_bool()
+ .unwrap());
+ context_id = context.get("id").unwrap().as_u64().unwrap();
}
}
+ assert_ne!(context_id, 0);
let mut repl_session = ReplSession {
worker,
diff --git a/core/inspector.rs b/core/inspector.rs
index daedd291d..e3db65afe 100644
--- a/core/inspector.rs
+++ b/core/inspector.rs
@@ -150,6 +150,7 @@ impl JsRuntimeInspector {
pub fn new(
isolate: &mut v8::OwnedIsolate,
context: v8::Global<v8::Context>,
+ is_main: bool,
) -> Rc<RefCell<Self>> {
let scope = &mut v8::HandleScope::new(isolate);
@@ -183,13 +184,26 @@ impl JsRuntimeInspector {
// Tell the inspector about the global context.
let context = v8::Local::new(scope, context);
let context_name = v8::inspector::StringView::from(&b"global context"[..]);
- let aux_data = v8::inspector::StringView::from(&b""[..]);
+ // NOTE(bartlomieju): this is what Node.js does and it turns out some
+ // debuggers (like VSCode) rely on this information to disconnect after
+ // program completes
+ let aux_data = if is_main {
+ r#"{"isDefault": true}"#
+ } else {
+ r#"{"isDefault": false}"#
+ };
+ let aux_data_view = v8::inspector::StringView::from(aux_data.as_bytes());
self_
.v8_inspector
.borrow_mut()
.as_mut()
.unwrap()
- .context_created(context, Self::CONTEXT_GROUP_ID, context_name, aux_data);
+ .context_created(
+ context,
+ Self::CONTEXT_GROUP_ID,
+ context_name,
+ aux_data_view,
+ );
// Poll the session handler so we will get notified whenever there is
// new incoming debugger activity.
diff --git a/core/runtime.rs b/core/runtime.rs
index b1ce14883..8cb38de2f 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -88,6 +88,8 @@ pub struct JsRuntime {
allocations: IsolateAllocations,
extensions: Vec<Extension>,
event_loop_middlewares: Vec<Box<OpEventLoopFn>>,
+ // Marks if this is considered the top-level runtime. Used only be inspector.
+ is_main: bool,
}
pub(crate) struct DynImportModEvaluate {
@@ -274,7 +276,13 @@ pub struct RuntimeOptions {
/// [CompiledWasmModuleStore]. If no [CompiledWasmModuleStore] is specified,
/// `WebAssembly.Module` objects cannot be serialized.
pub compiled_wasm_module_store: Option<CompiledWasmModuleStore>,
+
+ /// Start inspector instance to allow debuggers to connect.
pub inspector: bool,
+
+ /// Describe if this is the main runtime instance, used by debuggers in some
+ /// situation - like disconnecting when program finishes running.
+ pub is_main: bool,
}
#[derive(Copy, Clone, PartialEq, Eq)]
@@ -498,6 +506,7 @@ impl JsRuntime {
Some(JsRuntimeInspector::new(
&mut isolate,
global_context.clone(),
+ options.is_main,
))
} else {
None
@@ -532,6 +541,7 @@ impl JsRuntime {
extensions: options.extensions,
state: state_rc,
module_map: Some(module_map_rc),
+ is_main: options.is_main,
};
// Init resources and ops before extensions to make sure they are
@@ -949,6 +959,7 @@ impl JsRuntime {
state.inspector = Some(JsRuntimeInspector::new(
self.v8_isolate.as_mut().unwrap(),
state.global_realm.clone().unwrap().0,
+ self.is_main,
));
}
diff --git a/runtime/worker.rs b/runtime/worker.rs
index 0c439c703..967d53ea8 100644
--- a/runtime/worker.rs
+++ b/runtime/worker.rs
@@ -240,6 +240,7 @@ impl MainWorker {
compiled_wasm_module_store: options.compiled_wasm_module_store.clone(),
extensions,
inspector: options.maybe_inspector_server.is_some(),
+ is_main: true,
..Default::default()
});