1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-30 16:40:57 -05:00

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.
This commit is contained in:
Bartek Iwańczuk 2022-11-26 23:09:48 +01:00 committed by Yoshiya Hinosawa
parent 5e9e1395d0
commit 5d2461d46f
No known key found for this signature in database
GPG key ID: 0E8BFAA8A5B4E92B
4 changed files with 36 additions and 8 deletions

View file

@ -92,17 +92,19 @@ impl ReplSession {
for notification in session.notifications() { for notification in session.notifications() {
let method = notification.get("method").unwrap().as_str().unwrap(); let method = notification.get("method").unwrap().as_str().unwrap();
let params = notification.get("params").unwrap(); let params = notification.get("params").unwrap();
if method == "Runtime.executionContextCreated" { if method == "Runtime.executionContextCreated" {
context_id = params let context = params.get("context").unwrap();
.get("context") assert!(context
.get("auxData")
.unwrap() .unwrap()
.get("id") .get("isDefault")
.unwrap() .unwrap()
.as_u64() .as_bool()
.unwrap(); .unwrap());
context_id = context.get("id").unwrap().as_u64().unwrap();
} }
} }
assert_ne!(context_id, 0);
let mut repl_session = ReplSession { let mut repl_session = ReplSession {
worker, worker,

View file

@ -150,6 +150,7 @@ impl JsRuntimeInspector {
pub fn new( pub fn new(
isolate: &mut v8::OwnedIsolate, isolate: &mut v8::OwnedIsolate,
context: v8::Global<v8::Context>, context: v8::Global<v8::Context>,
is_main: bool,
) -> Rc<RefCell<Self>> { ) -> Rc<RefCell<Self>> {
let scope = &mut v8::HandleScope::new(isolate); let scope = &mut v8::HandleScope::new(isolate);
@ -183,13 +184,26 @@ impl JsRuntimeInspector {
// Tell the inspector about the global context. // Tell the inspector about the global context.
let context = v8::Local::new(scope, context); let context = v8::Local::new(scope, context);
let context_name = v8::inspector::StringView::from(&b"global 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_ self_
.v8_inspector .v8_inspector
.borrow_mut() .borrow_mut()
.as_mut() .as_mut()
.unwrap() .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 // Poll the session handler so we will get notified whenever there is
// new incoming debugger activity. // new incoming debugger activity.

View file

@ -88,6 +88,8 @@ pub struct JsRuntime {
allocations: IsolateAllocations, allocations: IsolateAllocations,
extensions: Vec<Extension>, extensions: Vec<Extension>,
event_loop_middlewares: Vec<Box<OpEventLoopFn>>, 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 { pub(crate) struct DynImportModEvaluate {
@ -274,7 +276,13 @@ pub struct RuntimeOptions {
/// [CompiledWasmModuleStore]. If no [CompiledWasmModuleStore] is specified, /// [CompiledWasmModuleStore]. If no [CompiledWasmModuleStore] is specified,
/// `WebAssembly.Module` objects cannot be serialized. /// `WebAssembly.Module` objects cannot be serialized.
pub compiled_wasm_module_store: Option<CompiledWasmModuleStore>, pub compiled_wasm_module_store: Option<CompiledWasmModuleStore>,
/// Start inspector instance to allow debuggers to connect.
pub inspector: bool, 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)] #[derive(Copy, Clone, PartialEq, Eq)]
@ -498,6 +506,7 @@ impl JsRuntime {
Some(JsRuntimeInspector::new( Some(JsRuntimeInspector::new(
&mut isolate, &mut isolate,
global_context.clone(), global_context.clone(),
options.is_main,
)) ))
} else { } else {
None None
@ -532,6 +541,7 @@ impl JsRuntime {
extensions: options.extensions, extensions: options.extensions,
state: state_rc, state: state_rc,
module_map: Some(module_map_rc), module_map: Some(module_map_rc),
is_main: options.is_main,
}; };
// Init resources and ops before extensions to make sure they are // Init resources and ops before extensions to make sure they are
@ -949,6 +959,7 @@ impl JsRuntime {
state.inspector = Some(JsRuntimeInspector::new( state.inspector = Some(JsRuntimeInspector::new(
self.v8_isolate.as_mut().unwrap(), self.v8_isolate.as_mut().unwrap(),
state.global_realm.clone().unwrap().0, state.global_realm.clone().unwrap().0,
self.is_main,
)); ));
} }

View file

@ -240,6 +240,7 @@ impl MainWorker {
compiled_wasm_module_store: options.compiled_wasm_module_store.clone(), compiled_wasm_module_store: options.compiled_wasm_module_store.clone(),
extensions, extensions,
inspector: options.maybe_inspector_server.is_some(), inspector: options.maybe_inspector_server.is_some(),
is_main: true,
..Default::default() ..Default::default()
}); });