Mercurial > hg > truffle
annotate src/share/vm/utilities/vmError.cpp @ 1994:6cd6d394f280
7001033: assert(gch->gc_cause() == GCCause::_scavenge_alot || !gch->incremental_collection_failed())
7002546: regression on SpecJbb2005 on 7b118 comparing to 7b117 on small heaps
Summary: Relaxed assertion checking related to incremental_collection_failed flag to allow for ExplicitGCInvokesConcurrent behaviour where we do not want a failing scavenge to bail to a stop-world collection. Parameterized incremental_collection_will_fail() so we can selectively use, or not use, as appropriate, the statistical prediction at specific use sites. This essentially reverts the scavenge bail-out logic to what it was prior to some recent changes that had inadvertently started using the statistical prediction which can be noisy in the presence of bursty loads. Added some associated verbose non-product debugging messages.
Reviewed-by: johnc, tonyp
author | ysr |
---|---|
date | Tue, 07 Dec 2010 21:55:53 -0800 |
parents | f95d63e2154a |
children | 2d4762ec74af |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "compiler/compileBroker.hpp" | |
27 #include "gc_interface/collectedHeap.hpp" | |
28 #include "runtime/arguments.hpp" | |
29 #include "runtime/frame.inline.hpp" | |
30 #include "runtime/init.hpp" | |
31 #include "runtime/os.hpp" | |
32 #include "runtime/thread.hpp" | |
33 #include "runtime/vmThread.hpp" | |
34 #include "runtime/vm_operations.hpp" | |
35 #include "utilities/debug.hpp" | |
36 #include "utilities/defaultStream.hpp" | |
37 #include "utilities/top.hpp" | |
38 #include "utilities/vmError.hpp" | |
0 | 39 |
40 // List of environment variables that should be reported in error log file. | |
41 const char *env_list[] = { | |
42 // All platforms | |
43 "JAVA_HOME", "JRE_HOME", "JAVA_TOOL_OPTIONS", "_JAVA_OPTIONS", "CLASSPATH", | |
44 "JAVA_COMPILER", "PATH", "USERNAME", | |
45 | |
46 // Env variables that are defined on Solaris/Linux | |
47 "LD_LIBRARY_PATH", "LD_PRELOAD", "SHELL", "DISPLAY", | |
48 "HOSTTYPE", "OSTYPE", "ARCH", "MACHTYPE", | |
49 | |
50 // defined on Linux | |
51 "LD_ASSUME_KERNEL", "_JAVA_SR_SIGNUM", | |
52 | |
53 // defined on Windows | |
54 "OS", "PROCESSOR_IDENTIFIER", "_ALT_JAVA_HOME_DIR", | |
55 | |
56 (const char *)0 | |
57 }; | |
58 | |
59 // Fatal error handler for internal errors and crashes. | |
60 // | |
61 // The default behavior of fatal error handler is to print a brief message | |
62 // to standard out (defaultStream::output_fd()), then save detailed information | |
63 // into an error report file (hs_err_pid<pid>.log) and abort VM. If multiple | |
64 // threads are having troubles at the same time, only one error is reported. | |
65 // The thread that is reporting error will abort VM when it is done, all other | |
66 // threads are blocked forever inside report_and_die(). | |
67 | |
68 // Constructor for crashes | |
69 VMError::VMError(Thread* thread, int sig, address pc, void* siginfo, void* context) { | |
70 _thread = thread; | |
71 _id = sig; | |
72 _pc = pc; | |
73 _siginfo = siginfo; | |
74 _context = context; | |
75 | |
76 _verbose = false; | |
77 _current_step = 0; | |
78 _current_step_info = NULL; | |
79 | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
80 _message = NULL; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
81 _detail_msg = NULL; |
0 | 82 _filename = NULL; |
83 _lineno = 0; | |
84 | |
85 _size = 0; | |
86 } | |
87 | |
88 // Constructor for internal errors | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
89 VMError::VMError(Thread* thread, const char* filename, int lineno, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
90 const char* message, const char * detail_msg) |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
91 { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
92 _thread = thread; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
93 _id = internal_error; // Value that's not an OS exception/signal |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
94 _filename = filename; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
95 _lineno = lineno; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
96 _message = message; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
97 _detail_msg = detail_msg; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
98 |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
99 _verbose = false; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
100 _current_step = 0; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
101 _current_step_info = NULL; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
102 |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
103 _pc = NULL; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
104 _siginfo = NULL; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
105 _context = NULL; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
106 |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
107 _size = 0; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
108 } |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
109 |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
110 // Constructor for OOM errors |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
111 VMError::VMError(Thread* thread, const char* filename, int lineno, size_t size, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
112 const char* message) { |
0 | 113 _thread = thread; |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
114 _id = oom_error; // Value that's not an OS exception/signal |
0 | 115 _filename = filename; |
116 _lineno = lineno; | |
117 _message = message; | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
118 _detail_msg = NULL; |
0 | 119 |
120 _verbose = false; | |
121 _current_step = 0; | |
122 _current_step_info = NULL; | |
123 | |
124 _pc = NULL; | |
125 _siginfo = NULL; | |
126 _context = NULL; | |
127 | |
128 _size = size; | |
129 } | |
130 | |
131 | |
132 // Constructor for non-fatal errors | |
133 VMError::VMError(const char* message) { | |
134 _thread = NULL; | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
135 _id = internal_error; // Value that's not an OS exception/signal |
0 | 136 _filename = NULL; |
137 _lineno = 0; | |
138 _message = message; | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
139 _detail_msg = NULL; |
0 | 140 |
141 _verbose = false; | |
142 _current_step = 0; | |
143 _current_step_info = NULL; | |
144 | |
145 _pc = NULL; | |
146 _siginfo = NULL; | |
147 _context = NULL; | |
148 | |
149 _size = 0; | |
150 } | |
151 | |
152 // -XX:OnError=<string>, where <string> can be a list of commands, separated | |
153 // by ';'. "%p" is replaced by current process id (pid); "%%" is replaced by | |
154 // a single "%". Some examples: | |
155 // | |
156 // -XX:OnError="pmap %p" // show memory map | |
157 // -XX:OnError="gcore %p; dbx - %p" // dump core and launch debugger | |
158 // -XX:OnError="cat hs_err_pid%p.log | mail my_email@sun.com" | |
159 // -XX:OnError="kill -9 %p" // ?#!@# | |
160 | |
161 // A simple parser for -XX:OnError, usage: | |
162 // ptr = OnError; | |
163 // while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr) != NULL) | |
164 // ... ... | |
165 static char* next_OnError_command(char* buf, int buflen, const char** ptr) { | |
166 if (ptr == NULL || *ptr == NULL) return NULL; | |
167 | |
168 const char* cmd = *ptr; | |
169 | |
170 // skip leading blanks or ';' | |
171 while (*cmd == ' ' || *cmd == ';') cmd++; | |
172 | |
173 if (*cmd == '\0') return NULL; | |
174 | |
175 const char * cmdend = cmd; | |
176 while (*cmdend != '\0' && *cmdend != ';') cmdend++; | |
177 | |
178 Arguments::copy_expand_pid(cmd, cmdend - cmd, buf, buflen); | |
179 | |
180 *ptr = (*cmdend == '\0' ? cmdend : cmdend + 1); | |
181 return buf; | |
182 } | |
183 | |
184 | |
185 static void print_bug_submit_message(outputStream *out, Thread *thread) { | |
186 if (out == NULL) return; | |
187 out->print_raw_cr("# If you would like to submit a bug report, please visit:"); | |
188 out->print_raw ("# "); | |
189 out->print_raw_cr(Arguments::java_vendor_url_bug()); | |
190 // If the crash is in native code, encourage user to submit a bug to the | |
191 // provider of that code. | |
56
31d829b33f26
6549844: Wording problems in "An unexpected error ..."
coleenp
parents:
0
diff
changeset
|
192 if (thread && thread->is_Java_thread() && |
31d829b33f26
6549844: Wording problems in "An unexpected error ..."
coleenp
parents:
0
diff
changeset
|
193 !thread->is_hidden_from_external_view()) { |
0 | 194 JavaThread* jt = (JavaThread*)thread; |
195 if (jt->thread_state() == _thread_in_native) { | |
196 out->print_cr("# The crash happened outside the Java Virtual Machine in native code.\n# See problematic frame for where to report the bug."); | |
197 } | |
198 } | |
199 out->print_raw_cr("#"); | |
200 } | |
201 | |
202 | |
203 // Return a string to describe the error | |
204 char* VMError::error_string(char* buf, int buflen) { | |
205 char signame_buf[64]; | |
206 const char *signame = os::exception_name(_id, signame_buf, sizeof(signame_buf)); | |
207 | |
208 if (signame) { | |
209 jio_snprintf(buf, buflen, | |
210 "%s (0x%x) at pc=" PTR_FORMAT ", pid=%d, tid=" UINTX_FORMAT, | |
211 signame, _id, _pc, | |
212 os::current_process_id(), os::current_thread_id()); | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
213 } else if (_filename != NULL && _lineno > 0) { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
214 // skip directory names |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
215 char separator = os::file_separator()[0]; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
216 const char *p = strrchr(_filename, separator); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
217 int n = jio_snprintf(buf, buflen, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
218 "Internal Error at %s:%d, pid=%d, tid=" UINTX_FORMAT, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
219 p ? p + 1 : _filename, _lineno, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
220 os::current_process_id(), os::current_thread_id()); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
221 if (n >= 0 && n < buflen && _message) { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
222 if (_detail_msg) { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
223 jio_snprintf(buf + n, buflen - n, "%s%s: %s", |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
224 os::line_separator(), _message, _detail_msg); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
225 } else { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
226 jio_snprintf(buf + n, buflen - n, "%sError: %s", |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
227 os::line_separator(), _message); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
228 } |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
229 } |
0 | 230 } else { |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
231 jio_snprintf(buf, buflen, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
232 "Internal Error (0x%x), pid=%d, tid=" UINTX_FORMAT, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
233 _id, os::current_process_id(), os::current_thread_id()); |
0 | 234 } |
235 | |
236 return buf; | |
237 } | |
238 | |
1384 | 239 void VMError::print_stack_trace(outputStream* st, JavaThread* jt, |
240 char* buf, int buflen, bool verbose) { | |
241 #ifdef ZERO | |
242 if (jt->zero_stack()->sp() && jt->top_zero_frame()) { | |
243 // StackFrameStream uses the frame anchor, which may not have | |
244 // been set up. This can be done at any time in Zero, however, | |
245 // so if it hasn't been set up then we just set it up now and | |
246 // clear it again when we're done. | |
247 bool has_last_Java_frame = jt->has_last_Java_frame(); | |
248 if (!has_last_Java_frame) | |
249 jt->set_last_Java_frame(); | |
250 st->print("Java frames:"); | |
251 | |
252 // If the top frame is a Shark frame and the frame anchor isn't | |
253 // set up then it's possible that the information in the frame | |
254 // is garbage: it could be from a previous decache, or it could | |
255 // simply have never been written. So we print a warning... | |
256 StackFrameStream sfs(jt); | |
257 if (!has_last_Java_frame && !sfs.is_done()) { | |
258 if (sfs.current()->zeroframe()->is_shark_frame()) { | |
259 st->print(" (TOP FRAME MAY BE JUNK)"); | |
260 } | |
261 } | |
262 st->cr(); | |
263 | |
264 // Print the frames | |
265 for(int i = 0; !sfs.is_done(); sfs.next(), i++) { | |
266 sfs.current()->zero_print_on_error(i, st, buf, buflen); | |
267 st->cr(); | |
268 } | |
269 | |
270 // Reset the frame anchor if necessary | |
271 if (!has_last_Java_frame) | |
272 jt->reset_last_Java_frame(); | |
273 } | |
274 #else | |
275 if (jt->has_last_Java_frame()) { | |
276 st->print_cr("Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)"); | |
277 for(StackFrameStream sfs(jt); !sfs.is_done(); sfs.next()) { | |
278 sfs.current()->print_on_error(st, buf, buflen, verbose); | |
279 st->cr(); | |
280 } | |
281 } | |
282 #endif // ZERO | |
283 } | |
0 | 284 |
285 // This is the main function to report a fatal error. Only one thread can | |
286 // call this function, so we don't need to worry about MT-safety. But it's | |
287 // possible that the error handler itself may crash or die on an internal | |
288 // error, for example, when the stack/heap is badly damaged. We must be | |
289 // able to handle recursive errors that happen inside error handler. | |
290 // | |
291 // Error reporting is done in several steps. If a crash or internal error | |
292 // occurred when reporting an error, the nested signal/exception handler | |
293 // can skip steps that are already (or partially) done. Error reporting will | |
294 // continue from the next step. This allows us to retrieve and print | |
295 // information that may be unsafe to get after a fatal error. If it happens, | |
296 // you may find nested report_and_die() frames when you look at the stack | |
297 // in a debugger. | |
298 // | |
299 // In general, a hang in error handler is much worse than a crash or internal | |
300 // error, as it's harder to recover from a hang. Deadlock can happen if we | |
301 // try to grab a lock that is already owned by current thread, or if the | |
302 // owner is blocked forever (e.g. in os::infinite_sleep()). If possible, the | |
303 // error handler and all the functions it called should avoid grabbing any | |
304 // lock. An important thing to notice is that memory allocation needs a lock. | |
305 // | |
306 // We should avoid using large stack allocated buffers. Many errors happen | |
307 // when stack space is already low. Making things even worse is that there | |
308 // could be nested report_and_die() calls on stack (see above). Only one | |
309 // thread can report error, so large buffers are statically allocated in data | |
310 // segment. | |
311 | |
312 void VMError::report(outputStream* st) { | |
313 # define BEGIN if (_current_step == 0) { _current_step = 1; | |
314 # define STEP(n, s) } if (_current_step < n) { _current_step = n; _current_step_info = s; | |
315 # define END } | |
316 | |
317 // don't allocate large buffer on stack | |
318 static char buf[O_BUFLEN]; | |
319 | |
320 BEGIN | |
321 | |
56
31d829b33f26
6549844: Wording problems in "An unexpected error ..."
coleenp
parents:
0
diff
changeset
|
322 STEP(10, "(printing fatal error message)") |
0 | 323 |
324 st->print_cr("#"); | |
56
31d829b33f26
6549844: Wording problems in "An unexpected error ..."
coleenp
parents:
0
diff
changeset
|
325 st->print_cr("# A fatal error has been detected by the Java Runtime Environment:"); |
0 | 326 |
327 STEP(15, "(printing type of error)") | |
328 | |
329 switch(_id) { | |
330 case oom_error: | |
331 st->print_cr("#"); | |
332 st->print("# java.lang.OutOfMemoryError: "); | |
333 if (_size) { | |
334 st->print("requested "); | |
420
a1980da045cc
6462850: generate biased locking code in C2 ideal graph
kvn
parents:
196
diff
changeset
|
335 sprintf(buf,SIZE_FORMAT,_size); |
0 | 336 st->print(buf); |
337 st->print(" bytes"); | |
338 if (_message != NULL) { | |
339 st->print(" for "); | |
340 st->print(_message); | |
341 } | |
342 st->print_cr(". Out of swap space?"); | |
343 } else { | |
344 if (_message != NULL) | |
345 st->print_cr(_message); | |
346 } | |
347 break; | |
348 case internal_error: | |
349 default: | |
350 break; | |
351 } | |
352 | |
353 STEP(20, "(printing exception/signal name)") | |
354 | |
355 st->print_cr("#"); | |
356 st->print("# "); | |
357 // Is it an OS exception/signal? | |
358 if (os::exception_name(_id, buf, sizeof(buf))) { | |
359 st->print("%s", buf); | |
360 st->print(" (0x%x)", _id); // signal number | |
361 st->print(" at pc=" PTR_FORMAT, _pc); | |
362 } else { | |
363 st->print("Internal Error"); | |
364 if (_filename != NULL && _lineno > 0) { | |
365 #ifdef PRODUCT | |
366 // In product mode chop off pathname? | |
367 char separator = os::file_separator()[0]; | |
368 const char *p = strrchr(_filename, separator); | |
369 const char *file = p ? p+1 : _filename; | |
370 #else | |
371 const char *file = _filename; | |
372 #endif | |
373 size_t len = strlen(file); | |
374 size_t buflen = sizeof(buf); | |
375 | |
376 strncpy(buf, file, buflen); | |
377 if (len + 10 < buflen) { | |
603
dbbe28fc66b5
6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents:
511
diff
changeset
|
378 sprintf(buf + len, ":%d", _lineno); |
0 | 379 } |
380 st->print(" (%s)", buf); | |
381 } else { | |
382 st->print(" (0x%x)", _id); | |
383 } | |
384 } | |
385 | |
386 STEP(30, "(printing current thread and pid)") | |
387 | |
388 // process id, thread id | |
389 st->print(", pid=%d", os::current_process_id()); | |
390 st->print(", tid=" UINTX_FORMAT, os::current_thread_id()); | |
391 st->cr(); | |
392 | |
393 STEP(40, "(printing error message)") | |
394 | |
395 // error message | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
396 if (_detail_msg) { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
397 st->print_cr("# %s: %s", _message ? _message : "Error", _detail_msg); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1384
diff
changeset
|
398 } else if (_message) { |
0 | 399 st->print_cr("# Error: %s", _message); |
400 } | |
401 | |
402 STEP(50, "(printing Java version string)") | |
403 | |
404 // VM version | |
405 st->print_cr("#"); | |
473
3ad2b8576c4a
6689685: Hotspot crash error message should include libraries version
coleenp
parents:
420
diff
changeset
|
406 JDK_Version::current().to_string(buf, sizeof(buf)); |
3ad2b8576c4a
6689685: Hotspot crash error message should include libraries version
coleenp
parents:
420
diff
changeset
|
407 st->print_cr("# JRE version: %s", buf); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
56
diff
changeset
|
408 st->print_cr("# Java VM: %s (%s %s %s %s)", |
0 | 409 Abstract_VM_Version::vm_name(), |
410 Abstract_VM_Version::vm_release(), | |
411 Abstract_VM_Version::vm_info_string(), | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
56
diff
changeset
|
412 Abstract_VM_Version::vm_platform_string(), |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
56
diff
changeset
|
413 UseCompressedOops ? "compressed oops" : "" |
0 | 414 ); |
415 | |
416 STEP(60, "(printing problematic frame)") | |
417 | |
418 // Print current frame if we have a context (i.e. it's a crash) | |
419 if (_context) { | |
420 st->print_cr("# Problematic frame:"); | |
421 st->print("# "); | |
422 frame fr = os::fetch_frame_from_context(_context); | |
423 fr.print_on_error(st, buf, sizeof(buf)); | |
424 st->cr(); | |
425 st->print_cr("#"); | |
426 } | |
427 | |
428 STEP(65, "(printing bug submit message)") | |
429 | |
430 if (_verbose) print_bug_submit_message(st, _thread); | |
431 | |
432 STEP(70, "(printing thread)" ) | |
433 | |
434 if (_verbose) { | |
435 st->cr(); | |
436 st->print_cr("--------------- T H R E A D ---------------"); | |
437 st->cr(); | |
438 } | |
439 | |
440 STEP(80, "(printing current thread)" ) | |
441 | |
442 // current thread | |
443 if (_verbose) { | |
444 if (_thread) { | |
445 st->print("Current thread (" PTR_FORMAT "): ", _thread); | |
446 _thread->print_on_error(st, buf, sizeof(buf)); | |
447 st->cr(); | |
448 } else { | |
449 st->print_cr("Current thread is native thread"); | |
450 } | |
451 st->cr(); | |
452 } | |
453 | |
454 STEP(90, "(printing siginfo)" ) | |
455 | |
456 // signal no, signal code, address that caused the fault | |
457 if (_verbose && _siginfo) { | |
458 os::print_siginfo(st, _siginfo); | |
459 st->cr(); | |
460 } | |
461 | |
462 STEP(100, "(printing registers, top of stack, instructions near pc)") | |
463 | |
464 // registers, top of stack, instructions near pc | |
465 if (_verbose && _context) { | |
466 os::print_context(st, _context); | |
467 st->cr(); | |
468 } | |
469 | |
1907 | 470 STEP(105, "(printing register info)") |
471 | |
472 // decode register contents if possible | |
473 if (_verbose && _context && Universe::is_fully_initialized()) { | |
474 os::print_register_info(st, _context); | |
475 st->cr(); | |
476 } | |
477 | |
0 | 478 STEP(110, "(printing stack bounds)" ) |
479 | |
480 if (_verbose) { | |
481 st->print("Stack: "); | |
482 | |
483 address stack_top; | |
484 size_t stack_size; | |
485 | |
486 if (_thread) { | |
487 stack_top = _thread->stack_base(); | |
488 stack_size = _thread->stack_size(); | |
489 } else { | |
490 stack_top = os::current_stack_base(); | |
491 stack_size = os::current_stack_size(); | |
492 } | |
493 | |
494 address stack_bottom = stack_top - stack_size; | |
495 st->print("[" PTR_FORMAT "," PTR_FORMAT "]", stack_bottom, stack_top); | |
496 | |
497 frame fr = _context ? os::fetch_frame_from_context(_context) | |
498 : os::current_frame(); | |
499 | |
500 if (fr.sp()) { | |
501 st->print(", sp=" PTR_FORMAT, fr.sp()); | |
1684
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
502 size_t free_stack_size = pointer_delta(fr.sp(), stack_bottom, 1024); |
66c5dadb4d61
6973308: Missing zero length check before repne scas in check_klass_subtype_slow_path()
kvn
parents:
1552
diff
changeset
|
503 st->print(", free space=" SIZE_FORMAT "k", free_stack_size); |
0 | 504 } |
505 | |
506 st->cr(); | |
507 } | |
508 | |
509 STEP(120, "(printing native stack)" ) | |
510 | |
511 if (_verbose) { | |
512 frame fr = _context ? os::fetch_frame_from_context(_context) | |
513 : os::current_frame(); | |
514 | |
515 // see if it's a valid frame | |
516 if (fr.pc()) { | |
517 st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); | |
518 | |
519 int count = 0; | |
520 | |
521 while (count++ < StackPrintLimit) { | |
522 fr.print_on_error(st, buf, sizeof(buf)); | |
523 st->cr(); | |
524 if (os::is_first_C_frame(&fr)) break; | |
525 fr = os::get_sender_for_C_frame(&fr); | |
526 } | |
527 | |
528 if (count > StackPrintLimit) { | |
529 st->print_cr("...<more frames>..."); | |
530 } | |
531 | |
532 st->cr(); | |
533 } | |
534 } | |
535 | |
536 STEP(130, "(printing Java stack)" ) | |
537 | |
538 if (_verbose && _thread && _thread->is_Java_thread()) { | |
1384 | 539 print_stack_trace(st, (JavaThread*)_thread, buf, sizeof(buf)); |
0 | 540 } |
541 | |
1119
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
1010
diff
changeset
|
542 STEP(135, "(printing target Java thread stack)" ) |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
1010
diff
changeset
|
543 |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
1010
diff
changeset
|
544 // printing Java thread stack trace if it is involved in GC crash |
1907 | 545 if (_verbose && _thread && (_thread->is_Named_thread())) { |
1119
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
1010
diff
changeset
|
546 JavaThread* jt = ((NamedThread *)_thread)->processed_thread(); |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
1010
diff
changeset
|
547 if (jt != NULL) { |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
1010
diff
changeset
|
548 st->print_cr("JavaThread " PTR_FORMAT " (nid = " UINTX_FORMAT ") was being processed", jt, jt->osthread()->thread_id()); |
1384 | 549 print_stack_trace(st, jt, buf, sizeof(buf), true); |
1119
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
1010
diff
changeset
|
550 } |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
1010
diff
changeset
|
551 } |
547f81740344
6361589: Print out stack trace for target thread of GC crash
minqi
parents:
1010
diff
changeset
|
552 |
0 | 553 STEP(140, "(printing VM operation)" ) |
554 | |
555 if (_verbose && _thread && _thread->is_VM_thread()) { | |
556 VMThread* t = (VMThread*)_thread; | |
557 VM_Operation* op = t->vm_operation(); | |
558 if (op) { | |
559 op->print_on_error(st); | |
560 st->cr(); | |
561 st->cr(); | |
562 } | |
563 } | |
564 | |
565 STEP(150, "(printing current compile task)" ) | |
566 | |
567 if (_verbose && _thread && _thread->is_Compiler_thread()) { | |
568 CompilerThread* t = (CompilerThread*)_thread; | |
569 if (t->task()) { | |
570 st->cr(); | |
571 st->print_cr("Current CompileTask:"); | |
572 t->task()->print_line_on_error(st, buf, sizeof(buf)); | |
573 st->cr(); | |
574 } | |
575 } | |
576 | |
577 STEP(160, "(printing process)" ) | |
578 | |
579 if (_verbose) { | |
580 st->cr(); | |
581 st->print_cr("--------------- P R O C E S S ---------------"); | |
582 st->cr(); | |
583 } | |
584 | |
585 STEP(170, "(printing all threads)" ) | |
586 | |
587 // all threads | |
588 if (_verbose && _thread) { | |
589 Threads::print_on_error(st, _thread, buf, sizeof(buf)); | |
590 st->cr(); | |
591 } | |
592 | |
593 STEP(175, "(printing VM state)" ) | |
594 | |
595 if (_verbose) { | |
596 // Safepoint state | |
597 st->print("VM state:"); | |
598 | |
599 if (SafepointSynchronize::is_synchronizing()) st->print("synchronizing"); | |
600 else if (SafepointSynchronize::is_at_safepoint()) st->print("at safepoint"); | |
601 else st->print("not at safepoint"); | |
602 | |
603 // Also see if error occurred during initialization or shutdown | |
604 if (!Universe::is_fully_initialized()) { | |
605 st->print(" (not fully initialized)"); | |
606 } else if (VM_Exit::vm_exited()) { | |
607 st->print(" (shutting down)"); | |
608 } else { | |
609 st->print(" (normal execution)"); | |
610 } | |
611 st->cr(); | |
612 st->cr(); | |
613 } | |
614 | |
615 STEP(180, "(printing owned locks on error)" ) | |
616 | |
617 // mutexes/monitors that currently have an owner | |
618 if (_verbose) { | |
619 print_owned_locks_on_error(st); | |
620 st->cr(); | |
621 } | |
622 | |
623 STEP(190, "(printing heap information)" ) | |
624 | |
625 if (_verbose && Universe::is_fully_initialized()) { | |
626 // print heap information before vm abort | |
627 Universe::print_on(st); | |
628 st->cr(); | |
629 } | |
630 | |
1907 | 631 STEP(195, "(printing code cache information)" ) |
632 | |
633 if (_verbose && Universe::is_fully_initialized()) { | |
634 // print code cache information before vm abort | |
635 CodeCache::print_bounds(st); | |
636 st->cr(); | |
637 } | |
638 | |
0 | 639 STEP(200, "(printing dynamic libraries)" ) |
640 | |
641 if (_verbose) { | |
642 // dynamic libraries, or memory map | |
643 os::print_dll_info(st); | |
644 st->cr(); | |
645 } | |
646 | |
647 STEP(210, "(printing VM options)" ) | |
648 | |
649 if (_verbose) { | |
650 // VM options | |
651 Arguments::print_on(st); | |
652 st->cr(); | |
653 } | |
654 | |
655 STEP(220, "(printing environment variables)" ) | |
656 | |
657 if (_verbose) { | |
658 os::print_environment_variables(st, env_list, buf, sizeof(buf)); | |
659 st->cr(); | |
660 } | |
661 | |
662 STEP(225, "(printing signal handlers)" ) | |
663 | |
664 if (_verbose) { | |
665 os::print_signal_handlers(st, buf, sizeof(buf)); | |
666 st->cr(); | |
667 } | |
668 | |
669 STEP(230, "" ) | |
670 | |
671 if (_verbose) { | |
672 st->cr(); | |
673 st->print_cr("--------------- S Y S T E M ---------------"); | |
674 st->cr(); | |
675 } | |
676 | |
677 STEP(240, "(printing OS information)" ) | |
678 | |
679 if (_verbose) { | |
680 os::print_os_info(st); | |
681 st->cr(); | |
682 } | |
683 | |
684 STEP(250, "(printing CPU info)" ) | |
685 if (_verbose) { | |
686 os::print_cpu_info(st); | |
687 st->cr(); | |
688 } | |
689 | |
690 STEP(260, "(printing memory info)" ) | |
691 | |
692 if (_verbose) { | |
693 os::print_memory_info(st); | |
694 st->cr(); | |
695 } | |
696 | |
697 STEP(270, "(printing internal vm info)" ) | |
698 | |
699 if (_verbose) { | |
700 st->print_cr("vm_info: %s", Abstract_VM_Version::internal_vm_info_string()); | |
701 st->cr(); | |
702 } | |
703 | |
704 STEP(280, "(printing date and time)" ) | |
705 | |
706 if (_verbose) { | |
707 os::print_date_and_time(st); | |
708 st->cr(); | |
709 } | |
710 | |
711 END | |
712 | |
713 # undef BEGIN | |
714 # undef STEP | |
715 # undef END | |
716 } | |
717 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
718 VMError* volatile VMError::first_error = NULL; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
719 volatile jlong VMError::first_error_tid = -1; |
0 | 720 |
721 void VMError::report_and_die() { | |
722 // Don't allocate large buffer on stack | |
723 static char buffer[O_BUFLEN]; | |
724 | |
725 // An error could happen before tty is initialized or after it has been | |
726 // destroyed. Here we use a very simple unbuffered fdStream for printing. | |
727 // Only out.print_raw() and out.print_raw_cr() should be used, as other | |
728 // printing methods need to allocate large buffer on stack. To format a | |
729 // string, use jio_snprintf() with a static buffer or use staticBufferStream. | |
730 static fdStream out(defaultStream::output_fd()); | |
731 | |
732 // How many errors occurred in error handler when reporting first_error. | |
733 static int recursive_error_count; | |
734 | |
735 // We will first print a brief message to standard out (verbose = false), | |
736 // then save detailed information in log file (verbose = true). | |
737 static bool out_done = false; // done printing to standard out | |
738 static bool log_done = false; // done saving error log | |
739 static fdStream log; // error log | |
740 | |
741 if (SuppressFatalErrorMessage) { | |
742 os::abort(); | |
743 } | |
744 jlong mytid = os::current_thread_id(); | |
745 if (first_error == NULL && | |
746 Atomic::cmpxchg_ptr(this, &first_error, NULL) == NULL) { | |
747 | |
748 // first time | |
749 first_error_tid = mytid; | |
750 set_error_reported(); | |
751 | |
752 if (ShowMessageBoxOnError) { | |
753 show_message_box(buffer, sizeof(buffer)); | |
754 | |
755 // User has asked JVM to abort. Reset ShowMessageBoxOnError so the | |
756 // WatcherThread can kill JVM if the error handler hangs. | |
757 ShowMessageBoxOnError = false; | |
758 } | |
759 | |
760 // reset signal handlers or exception filter; make sure recursive crashes | |
761 // are handled properly. | |
762 reset_signal_handlers(); | |
763 | |
764 } else { | |
511
dabd8d202164
4997835: RFE: crash dump will only be created when running w/ -XX:+ShowMessageBoxOnError
coleenp
parents:
473
diff
changeset
|
765 // If UseOsErrorReporting we call this for each level of the call stack |
dabd8d202164
4997835: RFE: crash dump will only be created when running w/ -XX:+ShowMessageBoxOnError
coleenp
parents:
473
diff
changeset
|
766 // while searching for the exception handler. Only the first level needs |
dabd8d202164
4997835: RFE: crash dump will only be created when running w/ -XX:+ShowMessageBoxOnError
coleenp
parents:
473
diff
changeset
|
767 // to be reported. |
dabd8d202164
4997835: RFE: crash dump will only be created when running w/ -XX:+ShowMessageBoxOnError
coleenp
parents:
473
diff
changeset
|
768 if (UseOSErrorReporting && log_done) return; |
dabd8d202164
4997835: RFE: crash dump will only be created when running w/ -XX:+ShowMessageBoxOnError
coleenp
parents:
473
diff
changeset
|
769 |
0 | 770 // This is not the first error, see if it happened in a different thread |
771 // or in the same thread during error reporting. | |
772 if (first_error_tid != mytid) { | |
773 jio_snprintf(buffer, sizeof(buffer), | |
774 "[thread " INT64_FORMAT " also had an error]", | |
775 mytid); | |
776 out.print_raw_cr(buffer); | |
777 | |
778 // error reporting is not MT-safe, block current thread | |
779 os::infinite_sleep(); | |
780 | |
781 } else { | |
782 if (recursive_error_count++ > 30) { | |
783 out.print_raw_cr("[Too many errors, abort]"); | |
784 os::die(); | |
785 } | |
786 | |
787 jio_snprintf(buffer, sizeof(buffer), | |
788 "[error occurred during error reporting %s, id 0x%x]", | |
789 first_error ? first_error->_current_step_info : "", | |
790 _id); | |
791 if (log.is_open()) { | |
792 log.cr(); | |
793 log.print_raw_cr(buffer); | |
794 log.cr(); | |
795 } else { | |
796 out.cr(); | |
797 out.print_raw_cr(buffer); | |
798 out.cr(); | |
799 } | |
800 } | |
801 } | |
802 | |
803 // print to screen | |
804 if (!out_done) { | |
805 first_error->_verbose = false; | |
806 | |
807 staticBufferStream sbs(buffer, sizeof(buffer), &out); | |
808 first_error->report(&sbs); | |
809 | |
810 out_done = true; | |
811 | |
812 first_error->_current_step = 0; // reset current_step | |
813 first_error->_current_step_info = ""; // reset current_step string | |
814 } | |
815 | |
816 // print to error log file | |
817 if (!log_done) { | |
818 first_error->_verbose = true; | |
819 | |
820 // see if log file is already open | |
821 if (!log.is_open()) { | |
822 // open log file | |
823 int fd = -1; | |
824 | |
825 if (ErrorFile != NULL) { | |
826 bool copy_ok = | |
827 Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer)); | |
828 if (copy_ok) { | |
829 fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); | |
830 } | |
831 } | |
832 | |
833 if (fd == -1) { | |
834 const char *cwd = os::get_current_directory(buffer, sizeof(buffer)); | |
835 size_t len = strlen(cwd); | |
836 // either user didn't specify, or the user's location failed, | |
837 // so use the default name in the current directory | |
838 jio_snprintf(&buffer[len], sizeof(buffer)-len, "%shs_err_pid%u.log", | |
839 os::file_separator(), os::current_process_id()); | |
840 fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); | |
841 } | |
842 | |
843 if (fd == -1) { | |
844 // try temp directory | |
845 const char * tmpdir = os::get_temp_directory(); | |
1353
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
1119
diff
changeset
|
846 jio_snprintf(buffer, sizeof(buffer), "%s%shs_err_pid%u.log", |
a2ea687fdc7c
6938627: Make temporary directory use property java.io.tmpdir when specified
coleenp
parents:
1119
diff
changeset
|
847 tmpdir, os::file_separator(), os::current_process_id()); |
0 | 848 fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
849 } | |
850 | |
851 if (fd != -1) { | |
852 out.print_raw("# An error report file with more information is saved as:\n# "); | |
853 out.print_raw_cr(buffer); | |
854 os::set_error_file(buffer); | |
855 | |
856 log.set_fd(fd); | |
857 } else { | |
858 out.print_raw_cr("# Can not save log file, dump to screen.."); | |
859 log.set_fd(defaultStream::output_fd()); | |
860 } | |
861 } | |
862 | |
863 staticBufferStream sbs(buffer, O_BUFLEN, &log); | |
864 first_error->report(&sbs); | |
865 first_error->_current_step = 0; // reset current_step | |
866 first_error->_current_step_info = ""; // reset current_step string | |
867 | |
868 if (log.fd() != defaultStream::output_fd()) { | |
869 close(log.fd()); | |
870 } | |
871 | |
872 log.set_fd(-1); | |
873 log_done = true; | |
874 } | |
875 | |
876 | |
877 static bool skip_OnError = false; | |
878 if (!skip_OnError && OnError && OnError[0]) { | |
879 skip_OnError = true; | |
880 | |
881 out.print_raw_cr("#"); | |
882 out.print_raw ("# -XX:OnError=\""); | |
883 out.print_raw (OnError); | |
884 out.print_raw_cr("\""); | |
885 | |
886 char* cmd; | |
887 const char* ptr = OnError; | |
888 while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr)) != NULL){ | |
889 out.print_raw ("# Executing "); | |
890 #if defined(LINUX) | |
891 out.print_raw ("/bin/sh -c "); | |
892 #elif defined(SOLARIS) | |
893 out.print_raw ("/usr/bin/sh -c "); | |
894 #endif | |
895 out.print_raw ("\""); | |
896 out.print_raw (cmd); | |
897 out.print_raw_cr("\" ..."); | |
898 | |
899 os::fork_and_exec(cmd); | |
900 } | |
901 | |
902 // done with OnError | |
903 OnError = NULL; | |
904 } | |
905 | |
906 static bool skip_bug_url = false; | |
907 if (!skip_bug_url) { | |
908 skip_bug_url = true; | |
909 | |
910 out.print_raw_cr("#"); | |
911 print_bug_submit_message(&out, _thread); | |
912 } | |
913 | |
914 if (!UseOSErrorReporting) { | |
915 // os::abort() will call abort hooks, try it first. | |
916 static bool skip_os_abort = false; | |
917 if (!skip_os_abort) { | |
918 skip_os_abort = true; | |
919 os::abort(); | |
920 } | |
921 | |
922 // if os::abort() doesn't abort, try os::die(); | |
923 os::die(); | |
924 } | |
925 } | |
926 | |
927 /* | |
928 * OnOutOfMemoryError scripts/commands executed while VM is a safepoint - this | |
929 * ensures utilities such as jmap can observe the process is a consistent state. | |
930 */ | |
931 class VM_ReportJavaOutOfMemory : public VM_Operation { | |
932 private: | |
933 VMError *_err; | |
934 public: | |
935 VM_ReportJavaOutOfMemory(VMError *err) { _err = err; } | |
936 VMOp_Type type() const { return VMOp_ReportJavaOutOfMemory; } | |
937 void doit(); | |
938 }; | |
939 | |
940 void VM_ReportJavaOutOfMemory::doit() { | |
941 // Don't allocate large buffer on stack | |
942 static char buffer[O_BUFLEN]; | |
943 | |
944 tty->print_cr("#"); | |
945 tty->print_cr("# java.lang.OutOfMemoryError: %s", _err->message()); | |
946 tty->print_cr("# -XX:OnOutOfMemoryError=\"%s\"", OnOutOfMemoryError); | |
947 | |
948 // make heap parsability | |
949 Universe::heap()->ensure_parsability(false); // no need to retire TLABs | |
950 | |
951 char* cmd; | |
952 const char* ptr = OnOutOfMemoryError; | |
953 while ((cmd = next_OnError_command(buffer, sizeof(buffer), &ptr)) != NULL){ | |
954 tty->print("# Executing "); | |
955 #if defined(LINUX) | |
956 tty->print ("/bin/sh -c "); | |
957 #elif defined(SOLARIS) | |
958 tty->print ("/usr/bin/sh -c "); | |
959 #endif | |
960 tty->print_cr("\"%s\"...", cmd); | |
961 | |
962 os::fork_and_exec(cmd); | |
963 } | |
964 } | |
965 | |
966 void VMError::report_java_out_of_memory() { | |
967 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) { | |
968 MutexLocker ml(Heap_lock); | |
969 VM_ReportJavaOutOfMemory op(this); | |
970 VMThread::execute(&op); | |
971 } | |
972 } |