50113
|
1 |
/*
|
|
2 |
* Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
|
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 |
*
|
|
5 |
* This code is free software; you can redistribute it and/or modify it
|
|
6 |
* under the terms of the GNU General Public License version 2 only, as
|
|
7 |
* published by the Free Software Foundation.
|
|
8 |
*
|
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that
|
|
13 |
* accompanied this code).
|
|
14 |
*
|
|
15 |
* You should have received a copy of the GNU General Public License version
|
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 |
*
|
|
19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
20 |
* or visit www.oracle.com if you need additional information or have any
|
|
21 |
* questions.
|
|
22 |
*
|
|
23 |
*/
|
|
24 |
|
|
25 |
#include "precompiled.hpp"
|
|
26 |
#include "jfr/jfrEvents.hpp"
|
|
27 |
#include "jfr/leakprofiler/leakProfiler.hpp"
|
|
28 |
#include "jfr/recorder/repository/jfrEmergencyDump.hpp"
|
|
29 |
#include "jfr/recorder/service/jfrPostBox.hpp"
|
|
30 |
#include "jfr/recorder/service/jfrRecorderService.hpp"
|
|
31 |
#include "jfr/utilities/jfrTypes.hpp"
|
|
32 |
#include "memory/resourceArea.hpp"
|
|
33 |
#include "runtime/atomic.hpp"
|
|
34 |
#include "runtime/handles.hpp"
|
|
35 |
#include "runtime/globals.hpp"
|
|
36 |
#include "runtime/mutexLocker.hpp"
|
|
37 |
#include "runtime/thread.hpp"
|
|
38 |
|
|
39 |
/*
|
|
40 |
* We are just about to exit the VM, so we will be very aggressive
|
|
41 |
* at this point in order to increase overall success of dumping jfr data:
|
|
42 |
*
|
|
43 |
* 1. if the thread state is not "_thread_in_vm", we will quick transition
|
|
44 |
* it to "_thread_in_vm".
|
|
45 |
* 2. the nesting state for both resource and handle areas are unknown,
|
|
46 |
* so we allocate new fresh arenas, discarding the old ones.
|
|
47 |
* 3. if the thread is the owner of some critical lock(s), unlock them.
|
|
48 |
*
|
|
49 |
* If we end up deadlocking in the attempt of dumping out jfr data,
|
|
50 |
* we rely on the WatcherThread task "is_error_reported()",
|
|
51 |
* to exit the VM after a hard-coded timeout.
|
|
52 |
* This "safety net" somewhat explains the aggressiveness in this attempt.
|
|
53 |
*
|
|
54 |
*/
|
|
55 |
static void prepare_for_emergency_dump(Thread* thread) {
|
|
56 |
if (thread->is_Java_thread()) {
|
|
57 |
((JavaThread*)thread)->set_thread_state(_thread_in_vm);
|
|
58 |
}
|
|
59 |
|
|
60 |
#ifdef ASSERT
|
|
61 |
Monitor* owned_lock = thread->owned_locks();
|
|
62 |
while (owned_lock != NULL) {
|
|
63 |
Monitor* next = owned_lock->next();
|
|
64 |
owned_lock->unlock();
|
|
65 |
owned_lock = next;
|
|
66 |
}
|
|
67 |
#endif // ASSERT
|
|
68 |
|
|
69 |
if (Threads_lock->owned_by_self()) {
|
|
70 |
Threads_lock->unlock();
|
|
71 |
}
|
|
72 |
|
|
73 |
if (Module_lock->owned_by_self()) {
|
|
74 |
Module_lock->unlock();
|
|
75 |
}
|
|
76 |
|
|
77 |
if (Heap_lock->owned_by_self()) {
|
|
78 |
Heap_lock->unlock();
|
|
79 |
}
|
|
80 |
|
|
81 |
if (Safepoint_lock->owned_by_self()) {
|
|
82 |
Safepoint_lock->unlock();
|
|
83 |
}
|
|
84 |
|
|
85 |
if (VMOperationQueue_lock->owned_by_self()) {
|
|
86 |
VMOperationQueue_lock->unlock();
|
|
87 |
}
|
|
88 |
|
|
89 |
if (VMOperationRequest_lock->owned_by_self()) {
|
|
90 |
VMOperationRequest_lock->unlock();
|
|
91 |
}
|
|
92 |
|
|
93 |
|
|
94 |
if (Service_lock->owned_by_self()) {
|
|
95 |
Service_lock->unlock();
|
|
96 |
}
|
|
97 |
|
|
98 |
if (CodeCache_lock->owned_by_self()) {
|
|
99 |
CodeCache_lock->unlock();
|
|
100 |
}
|
|
101 |
|
|
102 |
if (PeriodicTask_lock->owned_by_self()) {
|
|
103 |
PeriodicTask_lock->unlock();
|
|
104 |
}
|
|
105 |
|
|
106 |
if (JfrMsg_lock->owned_by_self()) {
|
|
107 |
JfrMsg_lock->unlock();
|
|
108 |
}
|
|
109 |
|
|
110 |
if (JfrBuffer_lock->owned_by_self()) {
|
|
111 |
JfrBuffer_lock->unlock();
|
|
112 |
}
|
|
113 |
|
|
114 |
if (JfrStream_lock->owned_by_self()) {
|
|
115 |
JfrStream_lock->unlock();
|
|
116 |
}
|
|
117 |
|
|
118 |
if (JfrStacktrace_lock->owned_by_self()) {
|
|
119 |
JfrStacktrace_lock->unlock();
|
|
120 |
}
|
|
121 |
}
|
|
122 |
|
|
123 |
static volatile int jfr_shutdown_lock = 0;
|
|
124 |
|
|
125 |
static bool guard_reentrancy() {
|
|
126 |
return Atomic::cmpxchg(1, &jfr_shutdown_lock, 0) == 0;
|
|
127 |
}
|
|
128 |
|
|
129 |
void JfrEmergencyDump::on_vm_shutdown(bool exception_handler) {
|
|
130 |
if (!guard_reentrancy()) {
|
|
131 |
return;
|
|
132 |
}
|
|
133 |
// function made non-reentrant
|
|
134 |
Thread* thread = Thread::current();
|
|
135 |
if (exception_handler) {
|
|
136 |
// we are crashing
|
|
137 |
if (thread->is_Watcher_thread()) {
|
|
138 |
// The Watcher thread runs the periodic thread sampling task.
|
|
139 |
// If it has crashed, it is likely that another thread is
|
|
140 |
// left in a suspended state. This would mean the system
|
|
141 |
// will not be able to ever move to a safepoint. We try
|
|
142 |
// to avoid issuing safepoint operations when attempting
|
|
143 |
// an emergency dump, but a safepoint might be already pending.
|
|
144 |
return;
|
|
145 |
}
|
|
146 |
prepare_for_emergency_dump(thread);
|
|
147 |
}
|
|
148 |
EventDumpReason event;
|
|
149 |
if (event.should_commit()) {
|
|
150 |
event.set_reason(exception_handler ? "Crash" : "Out of Memory");
|
|
151 |
event.set_recordingId(-1);
|
|
152 |
event.commit();
|
|
153 |
}
|
|
154 |
if (!exception_handler) {
|
|
155 |
// OOM
|
|
156 |
LeakProfiler::emit_events(max_jlong, false);
|
|
157 |
}
|
|
158 |
const int messages = MSGBIT(MSG_VM_ERROR);
|
|
159 |
ResourceMark rm(thread);
|
|
160 |
HandleMark hm(thread);
|
|
161 |
JfrRecorderService service;
|
|
162 |
service.rotate(messages);
|
|
163 |
}
|