Mon, 02 Jul 2012 13:11:28 -0400
Merge
1 /*
2 * Copyright (c) 1997, 2012, 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 */
25 #include "precompiled.hpp"
26 #include "classfile/systemDictionary.hpp"
27 #include "code/codeCache.hpp"
28 #include "code/icBuffer.hpp"
29 #include "code/nmethod.hpp"
30 #include "code/vtableStubs.hpp"
31 #include "compiler/compileBroker.hpp"
32 #include "compiler/disassembler.hpp"
33 #include "gc_implementation/shared/markSweep.hpp"
34 #include "gc_interface/collectedHeap.hpp"
35 #include "interpreter/bytecodeHistogram.hpp"
36 #include "interpreter/interpreter.hpp"
37 #include "memory/resourceArea.hpp"
38 #include "memory/universe.hpp"
39 #include "oops/oop.inline.hpp"
40 #include "prims/privilegedStack.hpp"
41 #include "runtime/arguments.hpp"
42 #include "runtime/frame.hpp"
43 #include "runtime/java.hpp"
44 #include "runtime/sharedRuntime.hpp"
45 #include "runtime/stubCodeGenerator.hpp"
46 #include "runtime/stubRoutines.hpp"
47 #include "runtime/vframe.hpp"
48 #include "services/heapDumper.hpp"
49 #include "utilities/defaultStream.hpp"
50 #include "utilities/events.hpp"
51 #include "utilities/top.hpp"
52 #include "utilities/vmError.hpp"
53 #ifdef TARGET_OS_FAMILY_linux
54 # include "os_linux.inline.hpp"
55 # include "thread_linux.inline.hpp"
56 #endif
57 #ifdef TARGET_OS_FAMILY_solaris
58 # include "os_solaris.inline.hpp"
59 # include "thread_solaris.inline.hpp"
60 #endif
61 #ifdef TARGET_OS_FAMILY_windows
62 # include "os_windows.inline.hpp"
63 # include "thread_windows.inline.hpp"
64 #endif
65 #ifdef TARGET_OS_FAMILY_bsd
66 # include "os_bsd.inline.hpp"
67 # include "thread_bsd.inline.hpp"
68 #endif
70 #ifndef ASSERT
71 # ifdef _DEBUG
72 // NOTE: don't turn the lines below into a comment -- if you're getting
73 // a compile error here, change the settings to define ASSERT
74 ASSERT should be defined when _DEBUG is defined. It is not intended to be used for debugging
75 functions that do not slow down the system too much and thus can be left in optimized code.
76 On the other hand, the code should not be included in a production version.
77 # endif // _DEBUG
78 #endif // ASSERT
81 #ifdef _DEBUG
82 # ifndef ASSERT
83 configuration error: ASSERT must be defined in debug version
84 # endif // ASSERT
85 #endif // _DEBUG
88 #ifdef PRODUCT
89 # if -defined _DEBUG || -defined ASSERT
90 configuration error: ASSERT et al. must not be defined in PRODUCT version
91 # endif
92 #endif // PRODUCT
95 void warning(const char* format, ...) {
96 if (PrintWarnings) {
97 // In case error happens before init or during shutdown
98 if (tty == NULL) ostream_init();
100 tty->print("%s warning: ", VM_Version::vm_name());
101 va_list ap;
102 va_start(ap, format);
103 tty->vprint_cr(format, ap);
104 va_end(ap);
105 }
106 if (BreakAtWarning) BREAKPOINT;
107 }
109 #ifndef PRODUCT
111 #define is_token_break(ch) (isspace(ch) || (ch) == ',')
113 static const char* last_file_name = NULL;
114 static int last_line_no = -1;
116 // assert/guarantee/... may happen very early during VM initialization.
117 // Don't rely on anything that is initialized by Threads::create_vm(). For
118 // example, don't use tty.
119 bool error_is_suppressed(const char* file_name, int line_no) {
120 // The following 1-element cache requires that passed-in
121 // file names are always only constant literals.
122 if (file_name == last_file_name && line_no == last_line_no) return true;
124 int file_name_len = (int)strlen(file_name);
125 char separator = os::file_separator()[0];
126 const char* base_name = strrchr(file_name, separator);
127 if (base_name == NULL)
128 base_name = file_name;
130 // scan the SuppressErrorAt option
131 const char* cp = SuppressErrorAt;
132 for (;;) {
133 const char* sfile;
134 int sfile_len;
135 int sline;
136 bool noisy;
137 while ((*cp) != '\0' && is_token_break(*cp)) cp++;
138 if ((*cp) == '\0') break;
139 sfile = cp;
140 while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':') cp++;
141 sfile_len = cp - sfile;
142 if ((*cp) == ':') cp++;
143 sline = 0;
144 while ((*cp) != '\0' && isdigit(*cp)) {
145 sline *= 10;
146 sline += (*cp) - '0';
147 cp++;
148 }
149 // "file:line!" means the assert suppression is not silent
150 noisy = ((*cp) == '!');
151 while ((*cp) != '\0' && !is_token_break(*cp)) cp++;
152 // match the line
153 if (sline != 0) {
154 if (sline != line_no) continue;
155 }
156 // match the file
157 if (sfile_len > 0) {
158 const char* look = file_name;
159 const char* look_max = file_name + file_name_len - sfile_len;
160 const char* foundp;
161 bool match = false;
162 while (!match
163 && (foundp = strchr(look, sfile[0])) != NULL
164 && foundp <= look_max) {
165 match = true;
166 for (int i = 1; i < sfile_len; i++) {
167 if (sfile[i] != foundp[i]) {
168 match = false;
169 break;
170 }
171 }
172 look = foundp + 1;
173 }
174 if (!match) continue;
175 }
176 // got a match!
177 if (noisy) {
178 fdStream out(defaultStream::output_fd());
179 out.print_raw("[error suppressed at ");
180 out.print_raw(base_name);
181 char buf[16];
182 jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
183 out.print_raw_cr(buf);
184 } else {
185 // update 1-element cache for fast silent matches
186 last_file_name = file_name;
187 last_line_no = line_no;
188 }
189 return true;
190 }
192 if (!is_error_reported()) {
193 // print a friendly hint:
194 fdStream out(defaultStream::output_fd());
195 out.print_raw_cr("# To suppress the following error report, specify this argument");
196 out.print_raw ("# after -XX: or in .hotspotrc: SuppressErrorAt=");
197 out.print_raw (base_name);
198 char buf[16];
199 jio_snprintf(buf, sizeof(buf), ":%d", line_no);
200 out.print_raw_cr(buf);
201 }
202 return false;
203 }
205 #undef is_token_break
207 #else
209 // Place-holder for non-existent suppression check:
210 #define error_is_suppressed(file_name, line_no) (false)
212 #endif // !PRODUCT
214 void report_vm_error(const char* file, int line, const char* error_msg,
215 const char* detail_msg)
216 {
217 if (Debugging || error_is_suppressed(file, line)) return;
218 Thread* const thread = ThreadLocalStorage::get_thread_slow();
219 VMError err(thread, file, line, error_msg, detail_msg);
220 err.report_and_die();
221 }
223 void report_fatal(const char* file, int line, const char* message)
224 {
225 report_vm_error(file, line, "fatal error", message);
226 }
228 // Used by report_vm_out_of_memory to detect recursion.
229 static jint _exiting_out_of_mem = 0;
231 void report_vm_out_of_memory(const char* file, int line, size_t size,
232 const char* message) {
233 if (Debugging) return;
235 // We try to gather additional information for the first out of memory
236 // error only; gathering additional data might cause an allocation and a
237 // recursive out_of_memory condition.
239 const jint exiting = 1;
240 // If we succeed in changing the value, we're the first one in.
241 bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting;
243 if (first_time_here) {
244 Thread* thread = ThreadLocalStorage::get_thread_slow();
245 VMError(thread, file, line, size, message).report_and_die();
246 }
248 // Dump core and abort
249 vm_abort(true);
250 }
252 void report_should_not_call(const char* file, int line) {
253 report_vm_error(file, line, "ShouldNotCall()");
254 }
256 void report_should_not_reach_here(const char* file, int line) {
257 report_vm_error(file, line, "ShouldNotReachHere()");
258 }
260 void report_unimplemented(const char* file, int line) {
261 report_vm_error(file, line, "Unimplemented()");
262 }
264 void report_untested(const char* file, int line, const char* message) {
265 #ifndef PRODUCT
266 warning("Untested: %s in %s: %d\n", message, file, line);
267 #endif // !PRODUCT
268 }
270 void report_out_of_shared_space(SharedSpaceType shared_space) {
271 static const char* name[] = {
272 "permanent generation",
273 "shared read only space",
274 "shared read write space",
275 "shared miscellaneous data space"
276 };
277 static const char* flag[] = {
278 "PermGen",
279 "SharedReadOnlySize",
280 "SharedReadWriteSize",
281 "SharedMiscDataSize"
282 };
284 warning("\nThe %s is not large enough\n"
285 "to preload requested classes. Use -XX:%s=\n"
286 "to increase the initial size of %s.\n",
287 name[shared_space], flag[shared_space], name[shared_space]);
288 exit(2);
289 }
291 void report_java_out_of_memory(const char* message) {
292 static jint out_of_memory_reported = 0;
294 // A number of threads may attempt to report OutOfMemoryError at around the
295 // same time. To avoid dumping the heap or executing the data collection
296 // commands multiple times we just do it once when the first threads reports
297 // the error.
298 if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
299 // create heap dump before OnOutOfMemoryError commands are executed
300 if (HeapDumpOnOutOfMemoryError) {
301 tty->print_cr("java.lang.OutOfMemoryError: %s", message);
302 HeapDumper::dump_heap_from_oome();
303 }
305 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
306 VMError err(message);
307 err.report_java_out_of_memory();
308 }
309 }
310 }
312 static bool error_reported = false;
314 // call this when the VM is dying--it might loosen some asserts
315 void set_error_reported() {
316 error_reported = true;
317 }
319 bool is_error_reported() {
320 return error_reported;
321 }
323 #ifndef PRODUCT
324 #include <signal.h>
326 void test_error_handler(size_t test_num)
327 {
328 if (test_num == 0) return;
330 // If asserts are disabled, use the corresponding guarantee instead.
331 size_t n = test_num;
332 NOT_DEBUG(if (n <= 2) n += 2);
334 const char* const str = "hello";
335 const size_t num = (size_t)os::vm_page_size();
337 const char* const eol = os::line_separator();
338 const char* const msg = "this message should be truncated during formatting";
340 // Keep this in sync with test/runtime/6888954/vmerrors.sh.
341 switch (n) {
342 case 1: assert(str == NULL, "expected null");
343 case 2: assert(num == 1023 && *str == 'X',
344 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
345 case 3: guarantee(str == NULL, "expected null");
346 case 4: guarantee(num == 1023 && *str == 'X',
347 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
348 case 5: fatal("expected null");
349 case 6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
350 case 7: fatal(err_msg("%s%s# %s%s# %s%s# %s%s# %s%s# "
351 "%s%s# %s%s# %s%s# %s%s# %s%s# "
352 "%s%s# %s%s# %s%s# %s%s# %s",
353 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
354 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
355 msg, eol, msg, eol, msg, eol, msg, eol, msg));
356 case 8: vm_exit_out_of_memory(num, "ChunkPool::allocate");
357 case 9: ShouldNotCallThis();
358 case 10: ShouldNotReachHere();
359 case 11: Unimplemented();
360 // This is last because it does not generate an hs_err* file on Windows.
361 case 12: os::signal_raise(SIGSEGV);
363 default: ShouldNotReachHere();
364 }
365 }
366 #endif // !PRODUCT
368 // ------ helper functions for debugging go here ------------
370 // All debug entries should be wrapped with a stack allocated
371 // Command object. It makes sure a resource mark is set and
372 // flushes the logfile to prevent file sharing problems.
374 class Command : public StackObj {
375 private:
376 ResourceMark rm;
377 ResetNoHandleMark rnhm;
378 HandleMark hm;
379 bool debug_save;
380 public:
381 static int level;
382 Command(const char* str) {
383 debug_save = Debugging;
384 Debugging = true;
385 if (level++ > 0) return;
386 tty->cr();
387 tty->print_cr("\"Executing %s\"", str);
388 }
390 ~Command() {
391 tty->flush();
392 Debugging = debug_save;
393 level--;
394 }
395 };
397 int Command::level = 0;
399 #ifndef PRODUCT
401 extern "C" void blob(CodeBlob* cb) {
402 Command c("blob");
403 cb->print();
404 }
407 extern "C" void dump_vtable(address p) {
408 Command c("dump_vtable");
409 klassOop k = (klassOop)p;
410 instanceKlass::cast(k)->vtable()->print();
411 }
414 extern "C" void nm(intptr_t p) {
415 // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
416 Command c("nm");
417 CodeBlob* cb = CodeCache::find_blob((address)p);
418 if (cb == NULL) {
419 tty->print_cr("NULL");
420 } else {
421 cb->print();
422 }
423 }
426 extern "C" void disnm(intptr_t p) {
427 Command c("disnm");
428 CodeBlob* cb = CodeCache::find_blob((address) p);
429 nmethod* nm = cb->as_nmethod_or_null();
430 if (nm) {
431 nm->print();
432 Disassembler::decode(nm);
433 } else {
434 cb->print();
435 Disassembler::decode(cb);
436 }
437 }
440 extern "C" void printnm(intptr_t p) {
441 char buffer[256];
442 sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
443 Command c(buffer);
444 CodeBlob* cb = CodeCache::find_blob((address) p);
445 if (cb->is_nmethod()) {
446 nmethod* nm = (nmethod*)cb;
447 nm->print_nmethod(true);
448 }
449 }
452 extern "C" void universe() {
453 Command c("universe");
454 Universe::print();
455 }
458 extern "C" void verify() {
459 // try to run a verify on the entire system
460 // note: this may not be safe if we're not at a safepoint; for debugging,
461 // this manipulates the safepoint settings to avoid assertion failures
462 Command c("universe verify");
463 bool safe = SafepointSynchronize::is_at_safepoint();
464 if (!safe) {
465 tty->print_cr("warning: not at safepoint -- verify may fail");
466 SafepointSynchronize::set_is_at_safepoint();
467 }
468 // Ensure Eden top is correct before verification
469 Universe::heap()->prepare_for_verify();
470 Universe::verify(true);
471 if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
472 }
475 extern "C" void pp(void* p) {
476 Command c("pp");
477 FlagSetting fl(PrintVMMessages, true);
478 FlagSetting f2(DisplayVMOutput, true);
479 if (Universe::heap()->is_in(p)) {
480 oop obj = oop(p);
481 obj->print();
482 } else {
483 tty->print(PTR_FORMAT, p);
484 }
485 }
488 // pv: print vm-printable object
489 extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); }
490 extern "C" void findpc(intptr_t x);
492 #endif // !PRODUCT
494 extern "C" void ps() { // print stack
495 if (Thread::current() == NULL) return;
496 Command c("ps");
499 // Prints the stack of the current Java thread
500 JavaThread* p = JavaThread::active();
501 tty->print(" for thread: ");
502 p->print();
503 tty->cr();
505 if (p->has_last_Java_frame()) {
506 // If the last_Java_fp is set we are in C land and
507 // can call the standard stack_trace function.
508 #ifdef PRODUCT
509 p->print_stack();
510 } else {
511 tty->print_cr("Cannot find the last Java frame, printing stack disabled.");
512 #else // !PRODUCT
513 p->trace_stack();
514 } else {
515 frame f = os::current_frame();
516 RegisterMap reg_map(p);
517 f = f.sender(®_map);
518 tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
519 p->trace_stack_from(vframe::new_vframe(&f, ®_map, p));
520 pd_ps(f);
521 #endif // PRODUCT
522 }
524 }
526 extern "C" void pfl() {
527 // print frame layout
528 Command c("pfl");
529 JavaThread* p = JavaThread::active();
530 tty->print(" for thread: ");
531 p->print();
532 tty->cr();
533 if (p->has_last_Java_frame()) {
534 p->print_frame_layout();
535 }
536 }
538 #ifndef PRODUCT
540 extern "C" void psf() { // print stack frames
541 {
542 Command c("psf");
543 JavaThread* p = JavaThread::active();
544 tty->print(" for thread: ");
545 p->print();
546 tty->cr();
547 if (p->has_last_Java_frame()) {
548 p->trace_frames();
549 }
550 }
551 }
554 extern "C" void threads() {
555 Command c("threads");
556 Threads::print(false, true);
557 }
560 extern "C" void psd() {
561 Command c("psd");
562 SystemDictionary::print();
563 }
566 extern "C" void safepoints() {
567 Command c("safepoints");
568 SafepointSynchronize::print_state();
569 }
571 #endif // !PRODUCT
573 extern "C" void pss() { // print all stacks
574 if (Thread::current() == NULL) return;
575 Command c("pss");
576 Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
577 }
579 #ifndef PRODUCT
581 extern "C" void debug() { // to set things up for compiler debugging
582 Command c("debug");
583 WizardMode = true;
584 PrintVMMessages = PrintCompilation = true;
585 PrintInlining = PrintAssembly = true;
586 tty->flush();
587 }
590 extern "C" void ndebug() { // undo debug()
591 Command c("ndebug");
592 PrintCompilation = false;
593 PrintInlining = PrintAssembly = false;
594 tty->flush();
595 }
598 extern "C" void flush() {
599 Command c("flush");
600 tty->flush();
601 }
603 extern "C" void events() {
604 Command c("events");
605 Events::print();
606 }
608 // Given a heap address that was valid before the most recent GC, if
609 // the oop that used to contain it is still live, prints the new
610 // location of the oop and the address. Useful for tracking down
611 // certain kinds of naked oop and oop map bugs.
612 extern "C" void pnl(intptr_t old_heap_addr) {
613 // Print New Location of old heap address
614 Command c("pnl");
615 #ifndef VALIDATE_MARK_SWEEP
616 tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled");
617 #else
618 MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr);
619 #endif
620 }
623 extern "C" methodOop findm(intptr_t pc) {
624 Command c("findm");
625 nmethod* nm = CodeCache::find_nmethod((address)pc);
626 return (nm == NULL) ? (methodOop)NULL : nm->method();
627 }
630 extern "C" nmethod* findnm(intptr_t addr) {
631 Command c("findnm");
632 return CodeCache::find_nmethod((address)addr);
633 }
635 static address same_page(address x, address y) {
636 intptr_t page_bits = -os::vm_page_size();
637 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) {
638 return x;
639 } else if (x > y) {
640 return (address)(intptr_t(y) | ~page_bits) + 1;
641 } else {
642 return (address)(intptr_t(y) & page_bits);
643 }
644 }
646 class LookForRefInGenClosure : public OopsInGenClosure {
647 public:
648 oop target;
649 void do_oop(oop* o) {
650 if (o != NULL && *o == target) {
651 tty->print_cr(INTPTR_FORMAT, o);
652 }
653 }
654 void do_oop(narrowOop* o) { ShouldNotReachHere(); }
655 };
658 class LookForRefInObjectClosure : public ObjectClosure {
659 private:
660 LookForRefInGenClosure look_in_object;
661 public:
662 LookForRefInObjectClosure(oop target) { look_in_object.target = target; }
663 void do_object(oop obj) {
664 obj->oop_iterate(&look_in_object);
665 }
666 };
669 static void findref(intptr_t x) {
670 CollectedHeap *ch = Universe::heap();
671 LookForRefInGenClosure lookFor;
672 lookFor.target = (oop) x;
673 LookForRefInObjectClosure look_in_object((oop) x);
675 tty->print_cr("Searching heap:");
676 ch->object_iterate(&look_in_object);
678 tty->print_cr("Searching strong roots:");
679 Universe::oops_do(&lookFor, false);
680 JNIHandles::oops_do(&lookFor); // Global (strong) JNI handles
681 Threads::oops_do(&lookFor, NULL);
682 ObjectSynchronizer::oops_do(&lookFor);
683 //FlatProfiler::oops_do(&lookFor);
684 SystemDictionary::oops_do(&lookFor);
686 tty->print_cr("Searching code cache:");
687 CodeCache::oops_do(&lookFor);
689 tty->print_cr("Done.");
690 }
692 class FindClassObjectClosure: public ObjectClosure {
693 private:
694 const char* _target;
695 public:
696 FindClassObjectClosure(const char name[]) { _target = name; }
698 virtual void do_object(oop obj) {
699 if (obj->is_klass()) {
700 Klass* k = klassOop(obj)->klass_part();
701 if (k->name() != NULL) {
702 ResourceMark rm;
703 const char* ext = k->external_name();
704 if ( strcmp(_target, ext) == 0 ) {
705 tty->print_cr("Found " INTPTR_FORMAT, obj);
706 obj->print();
707 }
708 }
709 }
710 }
711 };
713 //
714 extern "C" void findclass(const char name[]) {
715 Command c("findclass");
716 if (name != NULL) {
717 tty->print_cr("Finding class %s -> ", name);
718 FindClassObjectClosure srch(name);
719 Universe::heap()->permanent_object_iterate(&srch);
720 }
721 }
723 // Another interface that isn't ambiguous in dbx.
724 // Can we someday rename the other find to hsfind?
725 extern "C" void hsfind(intptr_t x) {
726 Command c("hsfind");
727 os::print_location(tty, x, false);
728 }
731 extern "C" void hsfindref(intptr_t x) {
732 Command c("hsfindref");
733 findref(x);
734 }
736 extern "C" void find(intptr_t x) {
737 Command c("find");
738 os::print_location(tty, x, false);
739 }
742 extern "C" void findpc(intptr_t x) {
743 Command c("findpc");
744 os::print_location(tty, x, true);
745 }
748 // int versions of all methods to avoid having to type type casts in the debugger
750 void pp(intptr_t p) { pp((void*)p); }
751 void pp(oop p) { pp((void*)p); }
753 void help() {
754 Command c("help");
755 tty->print_cr("basic");
756 tty->print_cr(" pp(void* p) - try to make sense of p");
757 tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
758 tty->print_cr(" ps() - print current thread stack");
759 tty->print_cr(" pss() - print all thread stacks");
760 tty->print_cr(" pm(int pc) - print methodOop given compiled PC");
761 tty->print_cr(" findm(intptr_t pc) - finds methodOop");
762 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
764 tty->print_cr("misc.");
765 tty->print_cr(" flush() - flushes the log file");
766 tty->print_cr(" events() - dump events from ring buffers");
769 tty->print_cr("compiler debugging");
770 tty->print_cr(" debug() - to set things up for compiler debugging");
771 tty->print_cr(" ndebug() - undo debug");
772 }
774 #if 0
776 // BobV's command parser for debugging on windows when nothing else works.
778 enum CommandID {
779 CMDID_HELP,
780 CMDID_QUIT,
781 CMDID_HSFIND,
782 CMDID_PSS,
783 CMDID_PS,
784 CMDID_PSF,
785 CMDID_FINDM,
786 CMDID_FINDNM,
787 CMDID_PP,
788 CMDID_BPT,
789 CMDID_EXIT,
790 CMDID_VERIFY,
791 CMDID_THREADS,
792 CMDID_ILLEGAL = 99
793 };
795 struct CommandParser {
796 char *name;
797 CommandID code;
798 char *description;
799 };
801 struct CommandParser CommandList[] = {
802 (char *)"help", CMDID_HELP, " Dump this list",
803 (char *)"quit", CMDID_QUIT, " Return from this routine",
804 (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address",
805 (char *)"ps", CMDID_PS, " Print Current Thread Stack Trace",
806 (char *)"pss", CMDID_PSS, " Print All Thread Stack Trace",
807 (char *)"psf", CMDID_PSF, " Print All Stack Frames",
808 (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC",
809 (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC",
810 (char *)"pp", CMDID_PP, " Find out something about a pointer",
811 (char *)"break", CMDID_BPT, " Execute a breakpoint",
812 (char *)"exitvm", CMDID_EXIT, "Exit the VM",
813 (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify",
814 (char *)"thread", CMDID_THREADS, "Dump Info on all Threads",
815 (char *)0, CMDID_ILLEGAL
816 };
819 // get_debug_command()
820 //
821 // Read a command from standard input.
822 // This is useful when you have a debugger
823 // which doesn't support calling into functions.
824 //
825 void get_debug_command()
826 {
827 ssize_t count;
828 int i,j;
829 bool gotcommand;
830 intptr_t addr;
831 char buffer[256];
832 nmethod *nm;
833 methodOop m;
835 tty->print_cr("You have entered the diagnostic command interpreter");
836 tty->print("The supported commands are:\n");
837 for ( i=0; ; i++ ) {
838 if ( CommandList[i].code == CMDID_ILLEGAL )
839 break;
840 tty->print_cr(" %s \n", CommandList[i].name );
841 }
843 while ( 1 ) {
844 gotcommand = false;
845 tty->print("Please enter a command: ");
846 count = scanf("%s", buffer) ;
847 if ( count >=0 ) {
848 for ( i=0; ; i++ ) {
849 if ( CommandList[i].code == CMDID_ILLEGAL ) {
850 if (!gotcommand) tty->print("Invalid command, please try again\n");
851 break;
852 }
853 if ( strcmp(buffer, CommandList[i].name) == 0 ) {
854 gotcommand = true;
855 switch ( CommandList[i].code ) {
856 case CMDID_PS:
857 ps();
858 break;
859 case CMDID_PSS:
860 pss();
861 break;
862 case CMDID_PSF:
863 psf();
864 break;
865 case CMDID_FINDM:
866 tty->print("Please enter the hex addr to pass to findm: ");
867 scanf("%I64X", &addr);
868 m = (methodOop)findm(addr);
869 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m);
870 break;
871 case CMDID_FINDNM:
872 tty->print("Please enter the hex addr to pass to findnm: ");
873 scanf("%I64X", &addr);
874 nm = (nmethod*)findnm(addr);
875 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm);
876 break;
877 case CMDID_PP:
878 tty->print("Please enter the hex addr to pass to pp: ");
879 scanf("%I64X", &addr);
880 pp((void*)addr);
881 break;
882 case CMDID_EXIT:
883 exit(0);
884 case CMDID_HELP:
885 tty->print("Here are the supported commands: ");
886 for ( j=0; ; j++ ) {
887 if ( CommandList[j].code == CMDID_ILLEGAL )
888 break;
889 tty->print_cr(" %s -- %s\n", CommandList[j].name,
890 CommandList[j].description );
891 }
892 break;
893 case CMDID_QUIT:
894 return;
895 break;
896 case CMDID_BPT:
897 BREAKPOINT;
898 break;
899 case CMDID_VERIFY:
900 verify();;
901 break;
902 case CMDID_THREADS:
903 threads();;
904 break;
905 case CMDID_HSFIND:
906 tty->print("Please enter the hex addr to pass to hsfind: ");
907 scanf("%I64X", &addr);
908 tty->print("Calling hsfind(0x%I64X)\n", addr);
909 hsfind(addr);
910 break;
911 default:
912 case CMDID_ILLEGAL:
913 break;
914 }
915 }
916 }
917 }
918 }
919 }
920 #endif
922 #endif // !PRODUCT