@@ -88,7 +88,8 @@ int NSolidCpuProfiler::TakeCpuProfile(SharedEnvInst envinst,
8888 auto pair = cpu_profiler_map_.emplace (
8989 std::piecewise_construct,
9090 std::forward_as_tuple (thread_id),
91- std::forward_as_tuple (duration,
91+ std::forward_as_tuple (thread_id,
92+ duration,
9293 utils::generate_unique_id (),
9394 data,
9495 cb,
@@ -196,9 +197,6 @@ void NSolidCpuProfiler::run_cpuprofiler_(SharedEnvInst envinst_sp) {
196197 return ;
197198 }
198199
199- // Assign v8::CpuProfiler and std::string profile_title to stor.
200- stor.profiler_ = profiler;
201-
202200 v8::Local<v8::String> profile_title = v8::String::NewFromUtf8 (
203201 isolate,
204202 stor.title_ .c_str (),
@@ -216,6 +214,9 @@ void NSolidCpuProfiler::run_cpuprofiler_(SharedEnvInst envinst_sp) {
216214 // Cleanup eveything.
217215 profiler->Dispose ();
218216 nsprofiler->cpu_profiler_map_ .erase (it);
217+ } else {
218+ // Assign v8::CpuProfiler to stor.
219+ stor.profiler_ = profiler;
219220 }
220221}
221222
@@ -250,18 +251,10 @@ void NSolidCpuProfiler::stop_cpuprofiler_(uint64_t thread_id) {
250251
251252void NSolidCpuProfiler::stop_cb_cpuprofiler_ (SharedEnvInst envinst_sp) {
252253 NSolidCpuProfiler* nsprofiler = NSolidCpuProfiler::Inst ();
253-
254- v8::Isolate* isolate = envinst_sp->isolate ();
255-
256- // At this point, maybe v8 already cleaned up our handles, if that happened,
257- // it won't we able to crate local handles without a handle scope.
258- //
259- // It's the better to make sure we have a HandleScope.
260- // DO NOT REMOVE, OTHERWISE V8 WILL CRASH.
261- v8::HandleScope handle_scope (isolate);
254+ uint64_t thread_id = envinst_sp->thread_id ();
262255
263256 nsuv::ns_mutex::scoped_lock lock (&nsprofiler->blocked_cpu_profilers_ );
264- auto it = nsprofiler->cpu_profiler_map_ .find (envinst_sp-> thread_id () );
257+ auto it = nsprofiler->cpu_profiler_map_ .find (thread_id);
265258
266259 // Not active profilers running.
267260 if (it == nsprofiler->cpu_profiler_map_ .end ()) {
@@ -271,20 +264,21 @@ void NSolidCpuProfiler::stop_cb_cpuprofiler_(SharedEnvInst envinst_sp) {
271264 auto & stor = it->second ;
272265 ASSERT_NOT_NULL (stor.profiler_ );
273266
267+ v8::Isolate* isolate = envinst_sp->isolate ();
268+ v8::HandleScope handle_scope (isolate);
274269 v8::Local<v8::String> profile_title = v8::String::NewFromUtf8 (
275270 isolate,
276271 stor.title_ .c_str (),
277272 v8::NewStringType::kInternalized ).ToLocalChecked ();
278273 v8::CpuProfile* profile = stor.profiler_ ->StopProfiling (profile_title);
279274 int er;
280275 if (profile == nullptr ) {
281- er = QueueCallback (NSolidCpuProfiler::cpuprofile_failed_,
282- envinst_sp->thread_id ());
276+ er = QueueCallback (NSolidCpuProfiler::cpuprofile_failed_, thread_id);
283277 } else {
284278 // We can parse the Cpu profiler on nsolid thread.
285279 er = QueueCallback (NSolidCpuProfiler::serialize_cpuprofile_,
286280 profile,
287- envinst_sp-> thread_id () );
281+ thread_id);
288282 }
289283
290284 if (er) {
@@ -299,9 +293,7 @@ void NSolidCpuProfiler::stop_cb_cpuprofiler_(SharedEnvInst envinst_sp) {
299293 }
300294
301295 // Assign the generated profile to tuple.
302- if (profile) {
303- stor.profile_ = profile;
304- }
296+ stor.profile_ = profile;
305297}
306298
307299
@@ -327,7 +319,7 @@ void NSolidCpuProfiler::cpuprofile_failed_(uint64_t thread_id) {
327319 // Cleanup of the v8 structures (Profiler and Profile) should be done from the
328320 // v8 thread.
329321 int er = RunCommand (GetEnvInst (thread_id),
330- CommandType::EventLoop ,
322+ CommandType::Interrupt ,
331323 NSolidCpuProfiler::cleanup_profile_);
332324 if (er) {
333325 // Nothing to do here really, just get rid of the warning.
@@ -342,7 +334,6 @@ void NSolidCpuProfiler::stream_cb_(std::string profileChunk, uint64_t* tid) {
342334 }
343335
344336 uint64_t thread_id = *tid;
345-
346337 NSolidCpuProfiler* nsprofiler = NSolidCpuProfiler::Inst ();
347338 nsuv::ns_mutex::scoped_lock lock (&nsprofiler->blocked_cpu_profilers_ );
348339 auto it = nsprofiler->cpu_profiler_map_ .find (thread_id);
@@ -359,11 +350,9 @@ void NSolidCpuProfiler::stream_cb_(std::string profileChunk, uint64_t* tid) {
359350 // Cleanup of the v8 structures (Profiler and Profile) should be done from
360351 // the v8 thread.
361352 int er = RunCommand (GetEnvInst (thread_id),
362- CommandType::EventLoop ,
353+ CommandType::Interrupt ,
363354 NSolidCpuProfiler::cleanup_profile_);
364355 if (er) {
365- // Nothing to do here really, just get rid of the warning.
366- delete tid;
367356 // Delete the reference of the profiler on this thread.
368357 nsprofiler->cpu_profiler_map_ .erase (it);
369358 }
@@ -378,6 +367,18 @@ void NSolidCpuProfiler::serialize_cpuprofile_(v8::CpuProfile* profile,
378367 return ;
379368 }
380369
370+ // Don't try to access the profile if the Isolate it comes from is gone
371+ SharedEnvInst envinst = GetEnvInst (thread_id);
372+ if (!envinst) {
373+ return ;
374+ }
375+
376+ // Keep the Isolate alive while serializing the CpuProfile
377+ EnvInst::Scope scp (envinst);
378+ if (!scp.Success ()) {
379+ return ;
380+ }
381+
381382 DataOutputStream<uint64_t , v8::CpuProfile> stream (&stream_cb_,
382383 profile,
383384 &thread_id);
0 commit comments