334 * We are just about to exit the VM, so we will be very aggressive |
334 * We are just about to exit the VM, so we will be very aggressive |
335 * at this point in order to increase overall success of dumping jfr data: |
335 * at this point in order to increase overall success of dumping jfr data: |
336 * |
336 * |
337 * 1. if the thread state is not "_thread_in_vm", we will quick transition |
337 * 1. if the thread state is not "_thread_in_vm", we will quick transition |
338 * it to "_thread_in_vm". |
338 * it to "_thread_in_vm". |
339 * 2. the nesting state for both resource and handle areas are unknown, |
339 * 2. if the thread is the owner of some critical lock(s), unlock them. |
340 * so we allocate new fresh arenas, discarding the old ones. |
|
341 * 3. if the thread is the owner of some critical lock(s), unlock them. |
|
342 * |
340 * |
343 * If we end up deadlocking in the attempt of dumping out jfr data, |
341 * If we end up deadlocking in the attempt of dumping out jfr data, |
344 * we rely on the WatcherThread task "is_error_reported()", |
342 * we rely on the WatcherThread task "is_error_reported()", |
345 * to exit the VM after a hard-coded timeout. |
343 * to exit the VM after a hard-coded timeout (disallow WatcherThread to emergency dump). |
346 * This "safety net" somewhat explains the aggressiveness in this attempt. |
344 * This "safety net" somewhat explains the aggressiveness in this attempt. |
347 * |
345 * |
348 */ |
346 */ |
349 static void prepare_for_emergency_dump(Thread* thread) { |
347 static bool prepare_for_emergency_dump() { |
|
348 if (JfrStream_lock->owned_by_self()) { |
|
349 // crashed during jfr rotation, disallow recursion |
|
350 return false; |
|
351 } |
|
352 Thread* const thread = Thread::current(); |
|
353 if (thread->is_Watcher_thread()) { |
|
354 // need WatcherThread as a safeguard against potential deadlocks |
|
355 return false; |
|
356 } |
|
357 |
350 if (thread->is_Java_thread()) { |
358 if (thread->is_Java_thread()) { |
351 ((JavaThread*)thread)->set_thread_state(_thread_in_vm); |
359 ((JavaThread*)thread)->set_thread_state(_thread_in_vm); |
352 } |
360 } |
353 |
361 |
354 #ifdef ASSERT |
362 #ifdef ASSERT |
382 |
390 |
383 if (VMOperationRequest_lock->owned_by_self()) { |
391 if (VMOperationRequest_lock->owned_by_self()) { |
384 VMOperationRequest_lock->unlock(); |
392 VMOperationRequest_lock->unlock(); |
385 } |
393 } |
386 |
394 |
387 |
|
388 if (Service_lock->owned_by_self()) { |
395 if (Service_lock->owned_by_self()) { |
389 Service_lock->unlock(); |
396 Service_lock->unlock(); |
390 } |
397 } |
391 |
398 |
392 if (UseNotificationThread && Notification_lock->owned_by_self()) { |
399 if (UseNotificationThread && Notification_lock->owned_by_self()) { |
410 } |
417 } |
411 |
418 |
412 if (JfrStacktrace_lock->owned_by_self()) { |
419 if (JfrStacktrace_lock->owned_by_self()) { |
413 JfrStacktrace_lock->unlock(); |
420 JfrStacktrace_lock->unlock(); |
414 } |
421 } |
|
422 return true; |
415 } |
423 } |
416 |
424 |
417 static volatile int jfr_shutdown_lock = 0; |
425 static volatile int jfr_shutdown_lock = 0; |
418 |
426 |
419 static bool guard_reentrancy() { |
427 static bool guard_reentrancy() { |
420 return Atomic::cmpxchg(1, &jfr_shutdown_lock, 0) == 0; |
428 return Atomic::cmpxchg(1, &jfr_shutdown_lock, 0) == 0; |
421 } |
429 } |
422 |
430 |
423 void JfrEmergencyDump::on_vm_shutdown(bool exception_handler) { |
431 void JfrEmergencyDump::on_vm_shutdown(bool exception_handler) { |
424 if (!guard_reentrancy()) { |
432 if (!(guard_reentrancy() && prepare_for_emergency_dump())) { |
425 return; |
433 return; |
426 } |
|
427 // function made non-reentrant |
|
428 Thread* thread = Thread::current(); |
|
429 if (exception_handler) { |
|
430 // we are crashing |
|
431 if (thread->is_Watcher_thread()) { |
|
432 // The Watcher thread runs the periodic thread sampling task. |
|
433 // If it has crashed, it is likely that another thread is |
|
434 // left in a suspended state. This would mean the system |
|
435 // will not be able to ever move to a safepoint. We try |
|
436 // to avoid issuing safepoint operations when attempting |
|
437 // an emergency dump, but a safepoint might be already pending. |
|
438 return; |
|
439 } |
|
440 prepare_for_emergency_dump(thread); |
|
441 } |
434 } |
442 EventDumpReason event; |
435 EventDumpReason event; |
443 if (event.should_commit()) { |
436 if (event.should_commit()) { |
444 event.set_reason(exception_handler ? "Crash" : "Out of Memory"); |
437 event.set_reason(exception_handler ? "Crash" : "Out of Memory"); |
445 event.set_recordingId(-1); |
438 event.set_recordingId(-1); |
448 if (!exception_handler) { |
441 if (!exception_handler) { |
449 // OOM |
442 // OOM |
450 LeakProfiler::emit_events(max_jlong, false); |
443 LeakProfiler::emit_events(max_jlong, false); |
451 } |
444 } |
452 const int messages = MSGBIT(MSG_VM_ERROR); |
445 const int messages = MSGBIT(MSG_VM_ERROR); |
453 ResourceMark rm(thread); |
|
454 HandleMark hm(thread); |
|
455 JfrRecorderService service; |
446 JfrRecorderService service; |
456 service.rotate(messages); |
447 service.rotate(messages); |
457 } |
448 } |