Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions bindings/profilers/wall.cc
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,10 @@ void WallProfiler::Cleanup(Isolate* isolate) {
if (interceptSignal()) {
SignalHandler::DecreaseUseCount();
}
Dispose(isolate);
// We're running inside the environment cleanup hook itself; Node removes
// the hook (and frees its internal record) after we return, so we must not
// remove it here — doing so would be a use-after-free. See Dispose().
Dispose(isolate, /*removeCleanupHook=*/false);
}
}

Expand Down Expand Up @@ -689,7 +692,7 @@ WallProfiler::~WallProfiler() {
liveContextPtrHead_ = nullptr;
}

void WallProfiler::Dispose(Isolate* isolate) {
void WallProfiler::Dispose(Isolate* isolate, bool removeCleanupHook) {
if (cpuProfiler_ != nullptr) {
cpuProfiler_->Dispose();
cpuProfiler_ = nullptr;
Expand All @@ -704,8 +707,10 @@ void WallProfiler::Dispose(Isolate* isolate) {
isolate->RemoveGCEpilogueCallback(&GCEpilogueCallback, this);
}

node::RemoveEnvironmentCleanupHook(
isolate, &WallProfiler::CleanupHook, isolate);
if (removeCleanupHook) {
node::RemoveEnvironmentCleanupHook(
isolate, &WallProfiler::CleanupHook, isolate);
}
}
}

Expand Down
9 changes: 8 additions & 1 deletion bindings/profilers/wall.hh
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,14 @@ class WallProfiler : public Nan::ObjectWrap {
ContextBuffer contexts_;

~WallProfiler();
void Dispose(v8::Isolate* isolate);
// removeCleanupHook must be false when Dispose is called from within the
// environment cleanup hook (CleanupHook). Node removes the hook itself after
// invoking it and dereferences its internal hook record again afterwards, so
// calling node::RemoveEnvironmentCleanupHook from inside the hook frees that
// record early and leaves Node reading freed memory (use-after-free crash on
// worker termination). In all other (still-running) call sites the hook is
// live and must be removed so it doesn't fire later against a dead profiler.
void Dispose(v8::Isolate* isolate, bool removeCleanupHook = true);

// A new CPU profiler object will be created each time profiling is started
// to work around https://bugs.chromium.org/p/v8/issues/detail?id=11051.
Expand Down
Loading
Loading