void mozilla_sampler_stop() { if (!stack_key_initialized) profiler_init(nullptr); TableTicker *t = tlsTicker.get(); if (!t) { return; } bool disableJS = t->ProfileJS(); bool unwinderThreader = t->HasUnwinderThread(); // Shut down and reap the unwinder thread. We have to do this // before stopping the sampler, so as to guarantee that the unwinder // thread doesn't try to access memory that the subsequent call to // mozilla_sampler_stop causes to be freed. if (unwinderThreader) { uwt__stop(); } t->Stop(); delete t; tlsTicker.set(nullptr); if (disableJS) { PseudoStack *stack = tlsPseudoStack.get(); ASSERT(stack != nullptr); stack->disableJSSampling(); } if (unwinderThreader) { uwt__deinit(); } mozilla::IOInterposer::Unregister(mozilla::IOInterposeObserver::OpAll, sInterposeObserver); sIsProfiling = false; nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); if (os) os->NotifyObservers(nullptr, "profiler-stopped", nullptr); }
void mozilla_sampler_shutdown() { sInitCount--; if (sInitCount > 0) return; // Save the profile on shutdown if requested. TableTicker *t = tlsTicker.get(); if (t) { const char *val = PR_GetEnv("MOZ_PROFILER_SHUTDOWN"); if (val) { std::ofstream stream; stream.open(val); if (stream.is_open()) { t->ToStreamAsJSON(stream); stream.close(); } } } // Shut down and reap the unwinder thread. We have to do this // before stopping the sampler, so as to guarantee that the unwinder // thread doesn't try to access memory that the subsequent call to // mozilla_sampler_stop causes to be freed. if (sps_version2()) { uwt__deinit(); } profiler_stop(); Sampler::Shutdown(); // We can't delete the Stack because we can be between a // sampler call_enter/call_exit point. // TODO Need to find a safe time to delete Stack }