|
1 | 1 | /* |
2 | | - * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2012, 2026, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
38 | 38 | #include "runtime/mutexLocker.hpp" |
39 | 39 | #include "runtime/os.hpp" |
40 | 40 | #include "runtime/thread.inline.hpp" |
| 41 | +#include "runtime/vmOperations.hpp" |
| 42 | +#include "runtime/vmThread.hpp" |
41 | 43 | #include "utilities/growableArray.hpp" |
42 | 44 | #include "utilities/ostream.hpp" |
43 | 45 |
|
@@ -460,15 +462,6 @@ static void release_locks(Thread* thread) { |
460 | 462 | assert(thread != nullptr, "invariant"); |
461 | 463 | assert(!thread->is_Java_thread() || JavaThread::cast(thread)->thread_state() == _thread_in_vm, "invariant"); |
462 | 464 |
|
463 | | -#ifdef ASSERT |
464 | | - Mutex* owned_lock = thread->owned_locks(); |
465 | | - while (owned_lock != nullptr) { |
466 | | - Mutex* next = owned_lock->next(); |
467 | | - owned_lock->unlock(); |
468 | | - owned_lock = next; |
469 | | - } |
470 | | -#endif // ASSERT |
471 | | - |
472 | 465 | if (Threads_lock->owned_by_self()) { |
473 | 466 | Threads_lock->unlock(); |
474 | 467 | } |
@@ -550,17 +543,14 @@ class JavaThreadInVMAndNative : public StackObj { |
550 | 543 | } |
551 | 544 | }; |
552 | 545 |
|
553 | | -static void post_events(bool emit_old_object_samples, bool emit_event_shutdown, Thread* thread) { |
554 | | - if (emit_old_object_samples) { |
555 | | - LeakProfiler::emit_events(max_jlong, false, false); |
556 | | - } |
557 | | - if (emit_event_shutdown) { |
| 546 | +static void post_events(bool exception_handler, bool oom, Thread * thread) { |
| 547 | + if (exception_handler) { |
558 | 548 | EventShutdown e; |
559 | | - e.set_reason("VM Error"); |
| 549 | + e.set_reason(oom ? "CrashOnOutOfMemoryError" : "VM Error"); |
560 | 550 | e.commit(); |
561 | 551 | } |
562 | 552 | EventDumpReason event; |
563 | | - event.set_reason(emit_old_object_samples ? "Out of Memory" : "Crash"); |
| 553 | + event.set_reason(exception_handler && oom ? "CrashOnOutOfMemoryError" : exception_handler ? "Crash" : "Out of Memory"); |
564 | 554 | event.set_recordingId(-1); |
565 | 555 | event.commit(); |
566 | 556 | } |
@@ -594,20 +584,40 @@ static bool guard_reentrancy() { |
594 | 584 | return false; |
595 | 585 | } |
596 | 586 |
|
597 | | -void JfrEmergencyDump::on_vm_shutdown(bool emit_old_object_samples, bool emit_event_shutdown) { |
| 587 | +void JfrEmergencyDump::on_vm_shutdown(bool exception_handler, bool oom) { |
598 | 588 | if (!guard_reentrancy()) { |
599 | 589 | return; |
600 | 590 | } |
| 591 | + |
601 | 592 | Thread* const thread = Thread::current_or_null_safe(); |
602 | 593 | assert(thread != nullptr, "invariant"); |
| 594 | + |
| 595 | + // Ensure a JavaThread is _thread_in_vm when we make this call |
| 596 | + JavaThreadInVMAndNative jtivm(thread); |
| 597 | + post_events(exception_handler, oom, thread); |
| 598 | + |
603 | 599 | if (thread->is_Watcher_thread()) { |
604 | | - log_info(jfr, system)("The Watcher thread crashed so no jfr emergency dump will be generated."); |
| 600 | + // We cannot attempt an emergency dump using the Watcher thread |
| 601 | + // because we rely on the WatcherThread task "is_error_reported()", |
| 602 | + // to exit the VM after a hardcoded timeout, should the relatively |
| 603 | + // risky operation of an emergency dump fail (deadlock, livelock). |
| 604 | + log_warning(jfr, system) |
| 605 | + ("The Watcher thread crashed so no jfr emergency dump will be generated."); |
605 | 606 | return; |
606 | 607 | } |
607 | | - // Ensure a JavaThread is _thread_in_vm when we make this call |
608 | | - JavaThreadInVMAndNative jtivm(thread); |
| 608 | + |
| 609 | + if (thread->is_VM_thread()) { |
| 610 | + const VM_Operation* const operation = VMThread::vm_operation(); |
| 611 | + if (operation != nullptr && operation->type() == VM_Operation::VMOp_JFROldObject) { |
| 612 | + // We will not be able to issue a rotation because the rotation lock |
| 613 | + // is held by the JFR Recorder Thread that issued the VM_Operation. |
| 614 | + log_warning(jfr, system) |
| 615 | + ("The VM Thread crashed as part of emitting leak profiler events so no jfr emergency dump will be generated."); |
| 616 | + return; |
| 617 | + } |
| 618 | + } |
| 619 | + |
609 | 620 | release_locks(thread); |
610 | | - post_events(emit_old_object_samples, emit_event_shutdown, thread); |
611 | 621 |
|
612 | 622 | // if JavaThread, transition to _thread_in_native to issue a final flushpoint |
613 | 623 | NoHandleMark nhm; |
|
0 commit comments