@@ -319,6 +319,14 @@ class NodeInspectorClient : public V8InspectorClient {
319
319
return uv_hrtime () * 1.0 / NANOS_PER_MSEC;
320
320
}
321
321
322
+ void maxAsyncCallStackDepthChanged (int depth) override {
323
+ if (depth == 0 ) {
324
+ env_->inspector_agent ()->DisableAsyncHook ();
325
+ } else {
326
+ env_->inspector_agent ()->EnableAsyncHook ();
327
+ }
328
+ }
329
+
322
330
void contextCreated (Local<Context> context, const std::string& name) {
323
331
std::unique_ptr<StringBuffer> name_buffer = Utf8ToStringView (name);
324
332
v8_inspector::V8ContextInfo info (context, CONTEXT_GROUP_ID,
@@ -449,7 +457,9 @@ Agent::Agent(Environment* env) : parent_env_(env),
449
457
client_(nullptr ),
450
458
platform_(nullptr ),
451
459
enabled_(false ),
452
- next_context_number_(1 ) {}
460
+ next_context_number_(1 ),
461
+ pending_enable_async_hook_(false ),
462
+ pending_disable_async_hook_(false ) {}
453
463
454
464
// Destructor needs to be defined here in implementation file as the header
455
465
// does not have full definition of some classes.
@@ -498,17 +508,6 @@ bool Agent::StartIoThread(bool wait_for_connect) {
498
508
HandleScope handle_scope (isolate);
499
509
auto context = parent_env_->context ();
500
510
501
- // Enable tracking of async stack traces
502
- if (!enable_async_hook_function_.IsEmpty ()) {
503
- Local<Function> enable_fn = enable_async_hook_function_.Get (isolate);
504
- auto result = enable_fn->Call (context, Undefined (isolate), 0 , nullptr );
505
- if (result.IsEmpty ()) {
506
- FatalError (
507
- " node::InspectorAgent::StartIoThread" ,
508
- " Cannot enable Inspector's AsyncHook, please report this." );
509
- }
510
- }
511
-
512
511
// Send message to enable debug in workers
513
512
Local<Object> process_object = parent_env_->process_object ();
514
513
Local<Value> emit_fn =
@@ -537,38 +536,9 @@ void Agent::Stop() {
537
536
io_.reset ();
538
537
enabled_ = false ;
539
538
}
540
-
541
- v8::Isolate* isolate = parent_env_->isolate ();
542
- HandleScope handle_scope (isolate);
543
-
544
- // Disable tracking of async stack traces
545
- if (!disable_async_hook_function_.IsEmpty ()) {
546
- Local<Function> disable_fn = disable_async_hook_function_.Get (isolate);
547
- auto result = disable_fn->Call (parent_env_->context (),
548
- Undefined (parent_env_->isolate ()), 0 , nullptr );
549
- if (result.IsEmpty ()) {
550
- FatalError (
551
- " node::InspectorAgent::Stop" ,
552
- " Cannot disable Inspector's AsyncHook, please report this." );
553
- }
554
- }
555
539
}
556
540
557
541
void Agent::Connect (InspectorSessionDelegate* delegate) {
558
- if (!enabled_) {
559
- // Enable tracking of async stack traces
560
- v8::Isolate* isolate = parent_env_->isolate ();
561
- HandleScope handle_scope (isolate);
562
- auto context = parent_env_->context ();
563
- Local<Function> enable_fn = enable_async_hook_function_.Get (isolate);
564
- auto result = enable_fn->Call (context, Undefined (isolate), 0 , nullptr );
565
- if (result.IsEmpty ()) {
566
- FatalError (
567
- " node::InspectorAgent::Connect" ,
568
- " Cannot enable Inspector's AsyncHook, please report this." );
569
- }
570
- }
571
-
572
542
enabled_ = true ;
573
543
client_->connectFrontend (delegate);
574
544
}
@@ -626,6 +596,50 @@ void Agent::RegisterAsyncHook(Isolate* isolate,
626
596
v8::Local<v8::Function> disable_function) {
627
597
enable_async_hook_function_.Reset (isolate, enable_function);
628
598
disable_async_hook_function_.Reset (isolate, disable_function);
599
+ if (pending_enable_async_hook_) {
600
+ CHECK (!pending_disable_async_hook_);
601
+ pending_enable_async_hook_ = false ;
602
+ EnableAsyncHook ();
603
+ } else if (pending_disable_async_hook_) {
604
+ CHECK (!pending_enable_async_hook_);
605
+ pending_disable_async_hook_ = false ;
606
+ DisableAsyncHook ();
607
+ }
608
+ }
609
+
610
+ void Agent::EnableAsyncHook () {
611
+ if (!enable_async_hook_function_.IsEmpty ()) {
612
+ Isolate* isolate = parent_env_->isolate ();
613
+ ToggleAsyncHook (isolate, enable_async_hook_function_.Get (isolate));
614
+ } else if (pending_disable_async_hook_) {
615
+ CHECK (!pending_enable_async_hook_);
616
+ pending_disable_async_hook_ = false ;
617
+ } else {
618
+ pending_enable_async_hook_ = true ;
619
+ }
620
+ }
621
+
622
+ void Agent::DisableAsyncHook () {
623
+ if (!disable_async_hook_function_.IsEmpty ()) {
624
+ Isolate* isolate = parent_env_->isolate ();
625
+ ToggleAsyncHook (isolate, disable_async_hook_function_.Get (isolate));
626
+ } else if (pending_enable_async_hook_) {
627
+ CHECK (!pending_disable_async_hook_);
628
+ pending_enable_async_hook_ = false ;
629
+ } else {
630
+ pending_disable_async_hook_ = true ;
631
+ }
632
+ }
633
+
634
+ void Agent::ToggleAsyncHook (Isolate* isolate, Local<Function> fn) {
635
+ HandleScope handle_scope (isolate);
636
+ auto context = parent_env_->context ();
637
+ auto result = fn->Call (context, Undefined (isolate), 0 , nullptr );
638
+ if (result.IsEmpty ()) {
639
+ FatalError (
640
+ " node::inspector::Agent::ToggleAsyncHook" ,
641
+ " Cannot toggle Inspector's AsyncHook, please report this." );
642
+ }
629
643
}
630
644
631
645
void Agent::AsyncTaskScheduled (const StringView& task_name, void * task,
0 commit comments