Mercurial > hg > truffle
annotate src/share/vm/utilities/debug.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | 126ea7725993 |
children | 30f67acf635d |
rev | line source |
---|---|
0 | 1 /* |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2 * Copyright (c) 1997, 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 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_debug.cpp.incl" | |
27 | |
28 #ifndef ASSERT | |
29 # ifdef _DEBUG | |
30 // NOTE: don't turn the lines below into a comment -- if you're getting | |
31 // a compile error here, change the settings to define ASSERT | |
32 ASSERT should be defined when _DEBUG is defined. It is not intended to be used for debugging | |
33 functions that do not slow down the system too much and thus can be left in optimized code. | |
34 On the other hand, the code should not be included in a production version. | |
35 # endif // _DEBUG | |
36 #endif // ASSERT | |
37 | |
38 | |
39 #ifdef _DEBUG | |
40 # ifndef ASSERT | |
41 configuration error: ASSERT must be defined in debug version | |
42 # endif // ASSERT | |
43 #endif // _DEBUG | |
44 | |
45 | |
46 #ifdef PRODUCT | |
47 # if -defined _DEBUG || -defined ASSERT | |
48 configuration error: ASSERT et al. must not be defined in PRODUCT version | |
49 # endif | |
50 #endif // PRODUCT | |
51 | |
52 | |
53 void warning(const char* format, ...) { | |
54 // In case error happens before init or during shutdown | |
55 if (tty == NULL) ostream_init(); | |
56 | |
57 tty->print("%s warning: ", VM_Version::vm_name()); | |
58 va_list ap; | |
59 va_start(ap, format); | |
60 tty->vprint_cr(format, ap); | |
61 va_end(ap); | |
62 if (BreakAtWarning) BREAKPOINT; | |
63 } | |
64 | |
65 #ifndef PRODUCT | |
66 | |
67 #define is_token_break(ch) (isspace(ch) || (ch) == ',') | |
68 | |
69 static const char* last_file_name = NULL; | |
70 static int last_line_no = -1; | |
71 | |
72 // assert/guarantee/... may happen very early during VM initialization. | |
73 // Don't rely on anything that is initialized by Threads::create_vm(). For | |
74 // example, don't use tty. | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
75 bool error_is_suppressed(const char* file_name, int line_no) { |
0 | 76 // The following 1-element cache requires that passed-in |
77 // file names are always only constant literals. | |
78 if (file_name == last_file_name && line_no == last_line_no) return true; | |
79 | |
80 int file_name_len = (int)strlen(file_name); | |
81 char separator = os::file_separator()[0]; | |
82 const char* base_name = strrchr(file_name, separator); | |
83 if (base_name == NULL) | |
84 base_name = file_name; | |
85 | |
86 // scan the SuppressErrorAt option | |
87 const char* cp = SuppressErrorAt; | |
88 for (;;) { | |
89 const char* sfile; | |
90 int sfile_len; | |
91 int sline; | |
92 bool noisy; | |
93 while ((*cp) != '\0' && is_token_break(*cp)) cp++; | |
94 if ((*cp) == '\0') break; | |
95 sfile = cp; | |
96 while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':') cp++; | |
97 sfile_len = cp - sfile; | |
98 if ((*cp) == ':') cp++; | |
99 sline = 0; | |
100 while ((*cp) != '\0' && isdigit(*cp)) { | |
101 sline *= 10; | |
102 sline += (*cp) - '0'; | |
103 cp++; | |
104 } | |
105 // "file:line!" means the assert suppression is not silent | |
106 noisy = ((*cp) == '!'); | |
107 while ((*cp) != '\0' && !is_token_break(*cp)) cp++; | |
108 // match the line | |
109 if (sline != 0) { | |
110 if (sline != line_no) continue; | |
111 } | |
112 // match the file | |
113 if (sfile_len > 0) { | |
114 const char* look = file_name; | |
115 const char* look_max = file_name + file_name_len - sfile_len; | |
116 const char* foundp; | |
117 bool match = false; | |
118 while (!match | |
119 && (foundp = strchr(look, sfile[0])) != NULL | |
120 && foundp <= look_max) { | |
121 match = true; | |
122 for (int i = 1; i < sfile_len; i++) { | |
123 if (sfile[i] != foundp[i]) { | |
124 match = false; | |
125 break; | |
126 } | |
127 } | |
128 look = foundp + 1; | |
129 } | |
130 if (!match) continue; | |
131 } | |
132 // got a match! | |
133 if (noisy) { | |
134 fdStream out(defaultStream::output_fd()); | |
135 out.print_raw("[error suppressed at "); | |
136 out.print_raw(base_name); | |
137 char buf[16]; | |
138 jio_snprintf(buf, sizeof(buf), ":%d]", line_no); | |
139 out.print_raw_cr(buf); | |
140 } else { | |
141 // update 1-element cache for fast silent matches | |
142 last_file_name = file_name; | |
143 last_line_no = line_no; | |
144 } | |
145 return true; | |
146 } | |
147 | |
148 if (!is_error_reported()) { | |
149 // print a friendly hint: | |
150 fdStream out(defaultStream::output_fd()); | |
151 out.print_raw_cr("# To suppress the following error report, specify this argument"); | |
152 out.print_raw ("# after -XX: or in .hotspotrc: SuppressErrorAt="); | |
153 out.print_raw (base_name); | |
154 char buf[16]; | |
155 jio_snprintf(buf, sizeof(buf), ":%d", line_no); | |
156 out.print_raw_cr(buf); | |
157 } | |
158 return false; | |
159 } | |
160 | |
161 #undef is_token_break | |
162 | |
163 #else | |
164 | |
165 // Place-holder for non-existent suppression check: | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
166 #define error_is_suppressed(file_name, line_no) (false) |
0 | 167 |
168 #endif //PRODUCT | |
169 | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
170 void report_vm_error(const char* file, int line, const char* error_msg, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
171 const char* detail_msg) |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
172 { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
173 if (Debugging || error_is_suppressed(file, line)) return; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
174 Thread* const thread = ThreadLocalStorage::get_thread_slow(); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
175 VMError err(thread, file, line, error_msg, detail_msg); |
0 | 176 err.report_and_die(); |
177 } | |
178 | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
179 void report_fatal(const char* file, int line, const char* message) |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
180 { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
181 report_vm_error(file, line, "fatal error", message); |
0 | 182 } |
183 | |
184 // Used by report_vm_out_of_memory to detect recursion. | |
185 static jint _exiting_out_of_mem = 0; | |
186 | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
187 void report_vm_out_of_memory(const char* file, int line, size_t size, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
188 const char* message) { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
189 if (Debugging || error_is_suppressed(file, line)) return; |
0 | 190 |
191 // We try to gather additional information for the first out of memory | |
192 // error only; gathering additional data might cause an allocation and a | |
193 // recursive out_of_memory condition. | |
194 | |
195 const jint exiting = 1; | |
196 // If we succeed in changing the value, we're the first one in. | |
197 bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting; | |
198 | |
199 if (first_time_here) { | |
200 Thread* thread = ThreadLocalStorage::get_thread_slow(); | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
201 VMError(thread, file, line, size, message).report_and_die(); |
0 | 202 } |
227
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
113
diff
changeset
|
203 |
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
113
diff
changeset
|
204 // Dump core and abort |
8d852b81e775
6694099: Hotspot vm_exit_out_of_memory should dump core
poonam
parents:
113
diff
changeset
|
205 vm_abort(true); |
0 | 206 } |
207 | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
208 void report_should_not_call(const char* file, int line) { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
209 report_vm_error(file, line, "ShouldNotCall()"); |
0 | 210 } |
211 | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
212 void report_should_not_reach_here(const char* file, int line) { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
213 report_vm_error(file, line, "ShouldNotReachHere()"); |
0 | 214 } |
215 | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
216 void report_unimplemented(const char* file, int line) { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
217 report_vm_error(file, line, "Unimplemented()"); |
0 | 218 } |
219 | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
220 void report_untested(const char* file, int line, const char* message) { |
0 | 221 #ifndef PRODUCT |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
222 warning("Untested: %s in %s: %d\n", message, file, line); |
0 | 223 #endif // PRODUCT |
224 } | |
225 | |
226 void report_java_out_of_memory(const char* message) { | |
227 static jint out_of_memory_reported = 0; | |
228 | |
229 // A number of threads may attempt to report OutOfMemoryError at around the | |
230 // same time. To avoid dumping the heap or executing the data collection | |
231 // commands multiple times we just do it once when the first threads reports | |
232 // the error. | |
233 if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) { | |
234 // create heap dump before OnOutOfMemoryError commands are executed | |
235 if (HeapDumpOnOutOfMemoryError) { | |
236 tty->print_cr("java.lang.OutOfMemoryError: %s", message); | |
237 HeapDumper::dump_heap(); | |
238 } | |
239 | |
240 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) { | |
241 VMError err(message); | |
242 err.report_java_out_of_memory(); | |
243 } | |
244 } | |
245 } | |
246 | |
247 | |
248 extern "C" void ps(); | |
249 | |
250 static bool error_reported = false; | |
251 | |
252 // call this when the VM is dying--it might loosen some asserts | |
253 void set_error_reported() { | |
254 error_reported = true; | |
255 } | |
256 | |
257 bool is_error_reported() { | |
258 return error_reported; | |
259 } | |
260 | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
261 #ifndef PRODUCT |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
262 #include <signal.h> |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
263 |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
264 void test_error_handler(size_t test_num) |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
265 { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
266 if (test_num == 0) return; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
267 |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
268 // If asserts are disabled, use the corresponding guarantee instead. |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
269 size_t n = test_num; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
270 NOT_DEBUG(if (n <= 2) n += 2); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
271 |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
272 const char* const str = "hello"; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
273 const size_t num = (size_t)os::vm_page_size(); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
274 |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
275 const char* const eol = os::line_separator(); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
276 const char* const msg = "this message should be truncated during formatting"; |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
277 |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
278 // Keep this in sync with test/runtime/6888954/vmerrors.sh. |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
279 switch (n) { |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
280 case 1: assert(str == NULL, "expected null"); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
281 case 2: assert(num == 1023 && *str == 'X', |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
282 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
283 case 3: guarantee(str == NULL, "expected null"); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
284 case 4: guarantee(num == 1023 && *str == 'X', |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
285 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
286 case 5: fatal("expected null"); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
287 case 6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
288 case 7: fatal(err_msg("%s%s# %s%s# %s%s# %s%s# %s%s# " |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
289 "%s%s# %s%s# %s%s# %s%s# %s%s# " |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
290 "%s%s# %s%s# %s%s# %s%s# %s", |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
291 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
292 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
293 msg, eol, msg, eol, msg, eol, msg, eol, msg)); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
294 case 8: vm_exit_out_of_memory(num, "ChunkPool::allocate"); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
295 case 9: ShouldNotCallThis(); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
296 case 10: ShouldNotReachHere(); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
297 case 11: Unimplemented(); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
298 // This is last because it does not generate an hs_err* file on Windows. |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
299 case 12: os::signal_raise(SIGSEGV); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
300 |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
301 default: ShouldNotReachHere(); |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
302 } |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
303 } |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
304 #endif // #ifndef PRODUCT |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
989
diff
changeset
|
305 |
0 | 306 // ------ helper functions for debugging go here ------------ |
307 | |
308 #ifndef PRODUCT | |
309 // All debug entries should be wrapped with a stack allocated | |
310 // Command object. It makes sure a resource mark is set and | |
311 // flushes the logfile to prevent file sharing problems. | |
312 | |
313 class Command : public StackObj { | |
314 private: | |
315 ResourceMark rm; | |
316 ResetNoHandleMark rnhm; | |
317 HandleMark hm; | |
318 bool debug_save; | |
319 public: | |
320 static int level; | |
321 Command(const char* str) { | |
322 debug_save = Debugging; | |
323 Debugging = true; | |
324 if (level++ > 0) return; | |
325 tty->cr(); | |
326 tty->print_cr("\"Executing %s\"", str); | |
327 } | |
328 | |
329 ~Command() { tty->flush(); Debugging = debug_save; level--; } | |
330 }; | |
331 | |
332 int Command::level = 0; | |
333 | |
334 extern "C" void blob(CodeBlob* cb) { | |
335 Command c("blob"); | |
336 cb->print(); | |
337 } | |
338 | |
339 | |
340 extern "C" void dump_vtable(address p) { | |
341 Command c("dump_vtable"); | |
342 klassOop k = (klassOop)p; | |
343 instanceKlass::cast(k)->vtable()->print(); | |
344 } | |
345 | |
346 | |
347 extern "C" void nm(intptr_t p) { | |
348 // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability) | |
349 Command c("nm"); | |
350 CodeBlob* cb = CodeCache::find_blob((address)p); | |
351 if (cb == NULL) { | |
352 tty->print_cr("NULL"); | |
353 } else { | |
354 cb->print(); | |
355 } | |
356 } | |
357 | |
358 | |
359 extern "C" void disnm(intptr_t p) { | |
360 Command c("disnm"); | |
361 CodeBlob* cb = CodeCache::find_blob((address) p); | |
362 cb->print(); | |
363 Disassembler::decode(cb); | |
364 } | |
365 | |
366 | |
367 extern "C" void printnm(intptr_t p) { | |
368 char buffer[256]; | |
369 sprintf(buffer, "printnm: " INTPTR_FORMAT, p); | |
370 Command c(buffer); | |
371 CodeBlob* cb = CodeCache::find_blob((address) p); | |
372 if (cb->is_nmethod()) { | |
373 nmethod* nm = (nmethod*)cb; | |
374 nm->print_nmethod(true); | |
375 } | |
376 } | |
377 | |
378 | |
379 extern "C" void universe() { | |
380 Command c("universe"); | |
381 Universe::print(); | |
382 } | |
383 | |
384 | |
385 extern "C" void verify() { | |
386 // try to run a verify on the entire system | |
387 // note: this may not be safe if we're not at a safepoint; for debugging, | |
388 // this manipulates the safepoint settings to avoid assertion failures | |
389 Command c("universe verify"); | |
390 bool safe = SafepointSynchronize::is_at_safepoint(); | |
391 if (!safe) { | |
392 tty->print_cr("warning: not at safepoint -- verify may fail"); | |
393 SafepointSynchronize::set_is_at_safepoint(); | |
394 } | |
395 // Ensure Eden top is correct before verification | |
396 Universe::heap()->prepare_for_verify(); | |
397 Universe::verify(true); | |
398 if (!safe) SafepointSynchronize::set_is_not_at_safepoint(); | |
399 } | |
400 | |
401 | |
402 extern "C" void pp(void* p) { | |
403 Command c("pp"); | |
404 FlagSetting fl(PrintVMMessages, true); | |
405 if (Universe::heap()->is_in(p)) { | |
406 oop obj = oop(p); | |
407 obj->print(); | |
408 } else { | |
409 tty->print("%#p", p); | |
410 } | |
411 } | |
412 | |
413 | |
414 // pv: print vm-printable object | |
415 extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); } | |
416 extern "C" void findpc(intptr_t x); | |
417 | |
418 extern "C" void ps() { // print stack | |
419 Command c("ps"); | |
420 | |
421 | |
422 // Prints the stack of the current Java thread | |
423 JavaThread* p = JavaThread::active(); | |
424 tty->print(" for thread: "); | |
425 p->print(); | |
426 tty->cr(); | |
427 | |
428 if (p->has_last_Java_frame()) { | |
429 // If the last_Java_fp is set we are in C land and | |
430 // can call the standard stack_trace function. | |
431 p->trace_stack(); | |
432 } else { | |
433 frame f = os::current_frame(); | |
434 RegisterMap reg_map(p); | |
435 f = f.sender(®_map); | |
436 tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id()); | |
437 p->trace_stack_from(vframe::new_vframe(&f, ®_map, p)); | |
438 pd_ps(f); | |
439 } | |
440 | |
441 } | |
442 | |
443 | |
444 extern "C" void psf() { // print stack frames | |
445 { | |
446 Command c("psf"); | |
447 JavaThread* p = JavaThread::active(); | |
448 tty->print(" for thread: "); | |
449 p->print(); | |
450 tty->cr(); | |
451 if (p->has_last_Java_frame()) { | |
452 p->trace_frames(); | |
453 } | |
454 } | |
455 } | |
456 | |
457 | |
458 extern "C" void threads() { | |
459 Command c("threads"); | |
460 Threads::print(false, true); | |
461 } | |
462 | |
463 | |
464 extern "C" void psd() { | |
465 Command c("psd"); | |
466 SystemDictionary::print(); | |
467 } | |
468 | |
469 | |
470 extern "C" void safepoints() { | |
471 Command c("safepoints"); | |
472 SafepointSynchronize::print_state(); | |
473 } | |
474 | |
475 | |
476 extern "C" void pss() { // print all stacks | |
477 Command c("pss"); | |
478 Threads::print(true, true); | |
479 } | |
480 | |
481 | |
482 extern "C" void debug() { // to set things up for compiler debugging | |
483 Command c("debug"); | |
484 WizardMode = true; | |
485 PrintVMMessages = PrintCompilation = true; | |
486 PrintInlining = PrintAssembly = true; | |
487 tty->flush(); | |
488 } | |
489 | |
490 | |
491 extern "C" void ndebug() { // undo debug() | |
492 Command c("ndebug"); | |
493 PrintCompilation = false; | |
494 PrintInlining = PrintAssembly = false; | |
495 tty->flush(); | |
496 } | |
497 | |
498 | |
499 extern "C" void flush() { | |
500 Command c("flush"); | |
501 tty->flush(); | |
502 } | |
503 | |
504 | |
505 extern "C" void events() { | |
506 Command c("events"); | |
507 Events::print_last(tty, 50); | |
508 } | |
509 | |
510 | |
511 extern "C" void nevents(int n) { | |
512 Command c("events"); | |
513 Events::print_last(tty, n); | |
514 } | |
515 | |
516 | |
517 // Given a heap address that was valid before the most recent GC, if | |
518 // the oop that used to contain it is still live, prints the new | |
519 // location of the oop and the address. Useful for tracking down | |
520 // certain kinds of naked oop and oop map bugs. | |
521 extern "C" void pnl(intptr_t old_heap_addr) { | |
522 // Print New Location of old heap address | |
523 Command c("pnl"); | |
524 #ifndef VALIDATE_MARK_SWEEP | |
525 tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled"); | |
526 #else | |
527 MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr); | |
528 #endif | |
529 } | |
530 | |
531 | |
532 extern "C" methodOop findm(intptr_t pc) { | |
533 Command c("findm"); | |
534 nmethod* nm = CodeCache::find_nmethod((address)pc); | |
535 return (nm == NULL) ? (methodOop)NULL : nm->method(); | |
536 } | |
537 | |
538 | |
539 extern "C" nmethod* findnm(intptr_t addr) { | |
540 Command c("findnm"); | |
541 return CodeCache::find_nmethod((address)addr); | |
542 } | |
543 | |
544 static address same_page(address x, address y) { | |
545 intptr_t page_bits = -os::vm_page_size(); | |
546 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) { | |
547 return x; | |
548 } else if (x > y) { | |
549 return (address)(intptr_t(y) | ~page_bits) + 1; | |
550 } else { | |
551 return (address)(intptr_t(y) & page_bits); | |
552 } | |
553 } | |
554 | |
555 class LookForRefInGenClosure : public OopsInGenClosure { | |
556 public: | |
557 oop target; | |
558 void do_oop(oop* o) { | |
559 if (o != NULL && *o == target) { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
560 tty->print_cr(INTPTR_FORMAT, o); |
0 | 561 } |
562 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
563 void do_oop(narrowOop* o) { ShouldNotReachHere(); } |
0 | 564 }; |
565 | |
566 | |
567 class LookForRefInObjectClosure : public ObjectClosure { | |
568 private: | |
569 LookForRefInGenClosure look_in_object; | |
570 public: | |
571 LookForRefInObjectClosure(oop target) { look_in_object.target = target; } | |
572 void do_object(oop obj) { | |
573 obj->oop_iterate(&look_in_object); | |
574 } | |
575 }; | |
576 | |
577 | |
578 static void findref(intptr_t x) { | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
579 CollectedHeap *ch = Universe::heap(); |
0 | 580 LookForRefInGenClosure lookFor; |
581 lookFor.target = (oop) x; | |
582 LookForRefInObjectClosure look_in_object((oop) x); | |
583 | |
584 tty->print_cr("Searching heap:"); | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
113
diff
changeset
|
585 ch->object_iterate(&look_in_object); |
0 | 586 |
587 tty->print_cr("Searching strong roots:"); | |
588 Universe::oops_do(&lookFor, false); | |
589 JNIHandles::oops_do(&lookFor); // Global (strong) JNI handles | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
432
diff
changeset
|
590 Threads::oops_do(&lookFor, NULL); |
0 | 591 ObjectSynchronizer::oops_do(&lookFor); |
592 //FlatProfiler::oops_do(&lookFor); | |
593 SystemDictionary::oops_do(&lookFor); | |
594 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
432
diff
changeset
|
595 tty->print_cr("Searching code cache:"); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
432
diff
changeset
|
596 CodeCache::oops_do(&lookFor); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
432
diff
changeset
|
597 |
0 | 598 tty->print_cr("Done."); |
599 } | |
600 | |
601 class FindClassObjectClosure: public ObjectClosure { | |
602 private: | |
603 const char* _target; | |
604 public: | |
605 FindClassObjectClosure(const char name[]) { _target = name; } | |
606 | |
607 virtual void do_object(oop obj) { | |
608 if (obj->is_klass()) { | |
609 Klass* k = klassOop(obj)->klass_part(); | |
610 if (k->name() != NULL) { | |
611 ResourceMark rm; | |
612 const char* ext = k->external_name(); | |
613 if ( strcmp(_target, ext) == 0 ) { | |
614 tty->print_cr("Found " INTPTR_FORMAT, obj); | |
615 obj->print(); | |
616 } | |
617 } | |
618 } | |
619 } | |
620 }; | |
621 | |
622 // | |
623 extern "C" void findclass(const char name[]) { | |
624 Command c("findclass"); | |
625 if (name != NULL) { | |
626 tty->print_cr("Finding class %s -> ", name); | |
627 FindClassObjectClosure srch(name); | |
628 Universe::heap()->permanent_object_iterate(&srch); | |
629 } | |
630 } | |
631 | |
632 // Another interface that isn't ambiguous in dbx. | |
633 // Can we someday rename the other find to hsfind? | |
634 extern "C" void hsfind(intptr_t x) { | |
635 Command c("hsfind"); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
636 os::print_location(tty, x, false); |
0 | 637 } |
638 | |
639 | |
640 extern "C" void hsfindref(intptr_t x) { | |
641 Command c("hsfindref"); | |
642 findref(x); | |
643 } | |
644 | |
645 extern "C" void find(intptr_t x) { | |
646 Command c("find"); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
647 os::print_location(tty, x, false); |
0 | 648 } |
649 | |
650 | |
651 extern "C" void findpc(intptr_t x) { | |
652 Command c("findpc"); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
653 os::print_location(tty, x, true); |
0 | 654 } |
655 | |
656 | |
657 // int versions of all methods to avoid having to type type casts in the debugger | |
658 | |
659 void pp(intptr_t p) { pp((void*)p); } | |
660 void pp(oop p) { pp((void*)p); } | |
661 | |
662 void help() { | |
663 Command c("help"); | |
664 tty->print_cr("basic"); | |
665 tty->print_cr(" pp(void* p) - try to make sense of p"); | |
666 tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()"); | |
667 tty->print_cr(" ps() - print current thread stack"); | |
668 tty->print_cr(" pss() - print all thread stacks"); | |
669 tty->print_cr(" pm(int pc) - print methodOop given compiled PC"); | |
670 tty->print_cr(" findm(intptr_t pc) - finds methodOop"); | |
671 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it"); | |
672 | |
673 tty->print_cr("misc."); | |
674 tty->print_cr(" flush() - flushes the log file"); | |
675 tty->print_cr(" events() - dump last 50 events"); | |
676 | |
677 | |
678 tty->print_cr("compiler debugging"); | |
679 tty->print_cr(" debug() - to set things up for compiler debugging"); | |
680 tty->print_cr(" ndebug() - undo debug"); | |
681 } | |
682 | |
683 #if 0 | |
684 | |
685 // BobV's command parser for debugging on windows when nothing else works. | |
686 | |
687 enum CommandID { | |
688 CMDID_HELP, | |
689 CMDID_QUIT, | |
690 CMDID_HSFIND, | |
691 CMDID_PSS, | |
692 CMDID_PS, | |
693 CMDID_PSF, | |
694 CMDID_FINDM, | |
695 CMDID_FINDNM, | |
696 CMDID_PP, | |
697 CMDID_BPT, | |
698 CMDID_EXIT, | |
699 CMDID_VERIFY, | |
700 CMDID_THREADS, | |
701 CMDID_ILLEGAL = 99 | |
702 }; | |
703 | |
704 struct CommandParser { | |
705 char *name; | |
706 CommandID code; | |
707 char *description; | |
708 }; | |
709 | |
710 struct CommandParser CommandList[] = { | |
711 (char *)"help", CMDID_HELP, " Dump this list", | |
712 (char *)"quit", CMDID_QUIT, " Return from this routine", | |
713 (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address", | |
714 (char *)"ps", CMDID_PS, " Print Current Thread Stack Trace", | |
715 (char *)"pss", CMDID_PSS, " Print All Thread Stack Trace", | |
716 (char *)"psf", CMDID_PSF, " Print All Stack Frames", | |
717 (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC", | |
718 (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC", | |
719 (char *)"pp", CMDID_PP, " Find out something about a pointer", | |
720 (char *)"break", CMDID_BPT, " Execute a breakpoint", | |
721 (char *)"exitvm", CMDID_EXIT, "Exit the VM", | |
722 (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify", | |
723 (char *)"thread", CMDID_THREADS, "Dump Info on all Threads", | |
724 (char *)0, CMDID_ILLEGAL | |
725 }; | |
726 | |
727 | |
728 // get_debug_command() | |
729 // | |
730 // Read a command from standard input. | |
731 // This is useful when you have a debugger | |
732 // which doesn't support calling into functions. | |
733 // | |
734 void get_debug_command() | |
735 { | |
736 ssize_t count; | |
737 int i,j; | |
738 bool gotcommand; | |
739 intptr_t addr; | |
740 char buffer[256]; | |
741 nmethod *nm; | |
742 methodOop m; | |
743 | |
744 tty->print_cr("You have entered the diagnostic command interpreter"); | |
745 tty->print("The supported commands are:\n"); | |
746 for ( i=0; ; i++ ) { | |
747 if ( CommandList[i].code == CMDID_ILLEGAL ) | |
748 break; | |
749 tty->print_cr(" %s \n", CommandList[i].name ); | |
750 } | |
751 | |
752 while ( 1 ) { | |
753 gotcommand = false; | |
754 tty->print("Please enter a command: "); | |
755 count = scanf("%s", buffer) ; | |
756 if ( count >=0 ) { | |
757 for ( i=0; ; i++ ) { | |
758 if ( CommandList[i].code == CMDID_ILLEGAL ) { | |
759 if (!gotcommand) tty->print("Invalid command, please try again\n"); | |
760 break; | |
761 } | |
762 if ( strcmp(buffer, CommandList[i].name) == 0 ) { | |
763 gotcommand = true; | |
764 switch ( CommandList[i].code ) { | |
765 case CMDID_PS: | |
766 ps(); | |
767 break; | |
768 case CMDID_PSS: | |
769 pss(); | |
770 break; | |
771 case CMDID_PSF: | |
772 psf(); | |
773 break; | |
774 case CMDID_FINDM: | |
775 tty->print("Please enter the hex addr to pass to findm: "); | |
776 scanf("%I64X", &addr); | |
777 m = (methodOop)findm(addr); | |
778 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m); | |
779 break; | |
780 case CMDID_FINDNM: | |
781 tty->print("Please enter the hex addr to pass to findnm: "); | |
782 scanf("%I64X", &addr); | |
783 nm = (nmethod*)findnm(addr); | |
784 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm); | |
785 break; | |
786 case CMDID_PP: | |
787 tty->print("Please enter the hex addr to pass to pp: "); | |
788 scanf("%I64X", &addr); | |
789 pp((void*)addr); | |
790 break; | |
791 case CMDID_EXIT: | |
792 exit(0); | |
793 case CMDID_HELP: | |
794 tty->print("Here are the supported commands: "); | |
795 for ( j=0; ; j++ ) { | |
796 if ( CommandList[j].code == CMDID_ILLEGAL ) | |
797 break; | |
798 tty->print_cr(" %s -- %s\n", CommandList[j].name, | |
799 CommandList[j].description ); | |
800 } | |
801 break; | |
802 case CMDID_QUIT: | |
803 return; | |
804 break; | |
805 case CMDID_BPT: | |
806 BREAKPOINT; | |
807 break; | |
808 case CMDID_VERIFY: | |
809 verify();; | |
810 break; | |
811 case CMDID_THREADS: | |
812 threads();; | |
813 break; | |
814 case CMDID_HSFIND: | |
815 tty->print("Please enter the hex addr to pass to hsfind: "); | |
816 scanf("%I64X", &addr); | |
817 tty->print("Calling hsfind(0x%I64X)\n", addr); | |
818 hsfind(addr); | |
819 break; | |
820 default: | |
821 case CMDID_ILLEGAL: | |
822 break; | |
823 } | |
824 } | |
825 } | |
826 } | |
827 } | |
828 } | |
829 #endif | |
830 | |
831 #endif // PRODUCT |