From 1535528793881f5fb33ff28051a908c3829afd1f Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Mon, 18 Mar 2019 23:14:49 +0800 Subject: [PATCH] src: fix DTrace GC callbacks DCHECKs and add cleanup Use the variant of GC callbacks that takes data to avoid running into DCHECKs when multiple Environments try to add the same callback to the same isolate multiple times. In addition, remove the callbacks in the Environment cleanup hook. --- src/node_dtrace.cc | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/node_dtrace.cc b/src/node_dtrace.cc index 5b2b9b8e14e942..910c19df73c7ef 100644 --- a/src/node_dtrace.cc +++ b/src/node_dtrace.cc @@ -248,15 +248,19 @@ void DTRACE_HTTP_CLIENT_RESPONSE(const FunctionCallbackInfo& args) { NODE_HTTP_CLIENT_RESPONSE(&conn, conn.remote, conn.port, conn.fd); } - -void dtrace_gc_start(Isolate* isolate, GCType type, GCCallbackFlags flags) { +void dtrace_gc_start(Isolate* isolate, + GCType type, + GCCallbackFlags flags, + void* data) { // Previous versions of this probe point only logged type and flags. // That's why for reasons of backwards compatibility the isolate goes last. NODE_GC_START(type, flags, isolate); } - -void dtrace_gc_done(Isolate* isolate, GCType type, GCCallbackFlags flags) { +void dtrace_gc_done(Isolate* isolate, + GCType type, + GCCallbackFlags flags, + void* data) { // Previous versions of this probe point only logged type and flags. // That's why for reasons of backwards compatibility the isolate goes last. NODE_GC_DONE(type, flags, isolate); @@ -272,8 +276,16 @@ void InitDTrace(Environment* env) { } #endif - env->isolate()->AddGCPrologueCallback(dtrace_gc_start); - env->isolate()->AddGCEpilogueCallback(dtrace_gc_done); + // We need to use the variant of GC callbacks that takes data to + // avoid running into DCHECKs when multiple Environments try to add + // the same callback to the same isolate multiple times. + env->isolate()->AddGCPrologueCallback(dtrace_gc_start, env); + env->isolate()->AddGCEpilogueCallback(dtrace_gc_done, env); + env->AddCleanupHook([](void* data) { + Environment* env = static_cast(data); + env->isolate()->RemoveGCPrologueCallback(dtrace_gc_start, env); + env->isolate()->RemoveGCEpilogueCallback(dtrace_gc_done, env); + }, env); } void InitializeDTrace(Local target,