@@ -68,6 +68,7 @@ static Instrument instrument;
6868
6969static ProfilingWindow profiling_window;
7070
71+ static volatile bool _in_jfrsync = false ;
7172
7273struct MethodSample {
7374 u64 samples;
@@ -1211,7 +1212,9 @@ Error Profiler::start(Arguments& args, bool reset) {
12111212 switchLibraryTrap (true );
12121213
12131214 if (args._output == OUTPUT_JFR) {
1215+ _in_jfrsync = args._jfr_sync != NULL ;
12141216 error = _jfr.start (args, reset);
1217+ _in_jfrsync = false ;
12151218 if (error) {
12161219 uninstallTraps ();
12171220 switchLibraryTrap (false );
@@ -2024,6 +2027,27 @@ Error Profiler::restart(Arguments& args) {
20242027}
20252028
20262029void Profiler::shutdown (Arguments& args) {
2030+ // Potential deadlock may happen between current thread & profiling thread due to usage of jfrsync
2031+ // To avoid that we use `tryLock` rather than `lock`
2032+ if (!_state_lock.tryLock ()) {
2033+ volatile bool sleep = true ;
2034+
2035+ // peek lock until acquired or _in_jfrsync is set
2036+ while (!_state_lock.tryLock () && !_in_jfrsync) {
2037+ OS::uninterruptibleSleep (10000000 , &sleep); // 10ms
2038+ }
2039+
2040+ // retry to confirm if real deadlock
2041+ for (int i = 0 ; i < 10 && !_state_lock.tryLock () && _in_jfrsync; i++) {
2042+ OS::uninterruptibleSleep (10000000 , &sleep);
2043+ }
2044+ }
2045+
2046+ // deadlock detected, skip stopping the profiler.
2047+ if (!_state_lock.tryLock () && _in_jfrsync) {
2048+ Log::warn (" %s" , " async-profiler deadlock detected during process shutdown, skipping the shutdown hooks" );
2049+ return ;
2050+ }
20272051 MutexLocker ml (_state_lock);
20282052
20292053 // The last chance to dump profile before VM terminates
0 commit comments