Skip to content

Commit 583edd9

Browse files
committedApr 10, 2020
src: fix cleanup hook removal for InspectorTimer
Fix this to account for the fact that `Stop()` may already have been called from a cleanup hook when the `inspector::Agent` is deleted along with the `Environment`, at which point cleanup hooks are no longer available. PR-URL: #32523 Reviewed-By: Matheus Marchini <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent c664214 commit 583edd9

File tree

1 file changed

+24
-16
lines changed

1 file changed

+24
-16
lines changed
 

‎src/inspector_agent.cc

+24-16
Original file line numberDiff line numberDiff line change
@@ -357,32 +357,26 @@ class InspectorTimer {
357357
int64_t interval_ms = 1000 * interval_s;
358358
uv_timer_start(&timer_, OnTimer, interval_ms, interval_ms);
359359
timer_.data = this;
360-
361-
env->AddCleanupHook(CleanupHook, this);
362360
}
363361

364362
InspectorTimer(const InspectorTimer&) = delete;
365363

366364
void Stop() {
367-
env_->RemoveCleanupHook(CleanupHook, this);
365+
if (timer_.data == nullptr) return;
368366

369-
if (timer_.data == this) {
370-
timer_.data = nullptr;
371-
uv_timer_stop(&timer_);
372-
env_->CloseHandle(reinterpret_cast<uv_handle_t*>(&timer_), TimerClosedCb);
373-
}
367+
timer_.data = nullptr;
368+
uv_timer_stop(&timer_);
369+
env_->CloseHandle(reinterpret_cast<uv_handle_t*>(&timer_), TimerClosedCb);
374370
}
375371

372+
inline Environment* env() const { return env_; }
373+
376374
private:
377375
static void OnTimer(uv_timer_t* uvtimer) {
378376
InspectorTimer* timer = node::ContainerOf(&InspectorTimer::timer_, uvtimer);
379377
timer->callback_(timer->data_);
380378
}
381379

382-
static void CleanupHook(void* data) {
383-
static_cast<InspectorTimer*>(data)->Stop();
384-
}
385-
386380
static void TimerClosedCb(uv_handle_t* uvtimer) {
387381
std::unique_ptr<InspectorTimer> timer(
388382
node::ContainerOf(&InspectorTimer::timer_,
@@ -405,16 +399,29 @@ class InspectorTimerHandle {
405399
InspectorTimerHandle(Environment* env, double interval_s,
406400
V8InspectorClient::TimerCallback callback, void* data) {
407401
timer_ = new InspectorTimer(env, interval_s, callback, data);
402+
403+
env->AddCleanupHook(CleanupHook, this);
408404
}
409405

410406
InspectorTimerHandle(const InspectorTimerHandle&) = delete;
411407

412408
~InspectorTimerHandle() {
413-
CHECK_NOT_NULL(timer_);
414-
timer_->Stop();
415-
timer_ = nullptr;
409+
Stop();
416410
}
411+
417412
private:
413+
void Stop() {
414+
if (timer_ != nullptr) {
415+
timer_->env()->RemoveCleanupHook(CleanupHook, this);
416+
timer_->Stop();
417+
}
418+
timer_ = nullptr;
419+
}
420+
421+
static void CleanupHook(void* data) {
422+
static_cast<InspectorTimerHandle*>(data)->Stop();
423+
}
424+
418425
InspectorTimer* timer_;
419426
};
420427

@@ -737,8 +744,9 @@ class NodeInspectorClient : public V8InspectorClient {
737744
bool is_main_;
738745
bool running_nested_loop_ = false;
739746
std::unique_ptr<V8Inspector> client_;
740-
std::unordered_map<int, std::unique_ptr<ChannelImpl>> channels_;
747+
// Note: ~ChannelImpl may access timers_ so timers_ has to come first.
741748
std::unordered_map<void*, InspectorTimerHandle> timers_;
749+
std::unordered_map<int, std::unique_ptr<ChannelImpl>> channels_;
742750
int next_session_id_ = 1;
743751
bool waiting_for_resume_ = false;
744752
bool waiting_for_frontend_ = false;

0 commit comments

Comments
 (0)
Please sign in to comment.