1 /* 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "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 69 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 79 80 81 #ifdef _DEBUG 82 # ifndef ASSERT 83 configuration error: ASSERT must be defined in debug version 84 # endif // ASSERT 85 #endif // _DEBUG 86 87 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 93 94 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(); 99 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 } 108 109 #ifndef PRODUCT 110 111 #define is_token_break(ch) (isspace(ch) || (ch) == ',') 112 113 static const char* last_file_name = NULL; 114 static int last_line_no = -1; 115 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; 123 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; 129 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 } 191 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 } 204 205 #undef is_token_break 206 207 #else 208 209 // Place-holder for non-existent suppression check: 210 #define error_is_suppressed(file_name, line_no) (false) 211 212 #endif //PRODUCT 213 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 } 222 223 void report_fatal(const char* file, int line, const char* message) 224 { 225 report_vm_error(file, line, "fatal error", message); 226 } 227 228 // Used by report_vm_out_of_memory to detect recursion. 229 static jint _exiting_out_of_mem = 0; 230 231 void report_vm_out_of_memory(const char* file, int line, size_t size, 232 const char* message) { 233 if (Debugging) return; 234 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. 238 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; 242 243 if (first_time_here) { 244 Thread* thread = ThreadLocalStorage::get_thread_slow(); 245 VMError(thread, file, line, size, message).report_and_die(); 246 } 247 248 // Dump core and abort 249 vm_abort(true); 250 } 251 252 void report_should_not_call(const char* file, int line) { 253 report_vm_error(file, line, "ShouldNotCall()"); 254 } 255 256 void report_should_not_reach_here(const char* file, int line) { 257 report_vm_error(file, line, "ShouldNotReachHere()"); 258 } 259 260 void report_unimplemented(const char* file, int line) { 261 report_vm_error(file, line, "Unimplemented()"); 262 } 263 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 } 269 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 }; 283 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 } 290 291 void report_java_out_of_memory(const char* message) { 292 static jint out_of_memory_reported = 0; 293 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 } 304 305 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) { 306 VMError err(message); 307 err.report_java_out_of_memory(); 308 } 309 } 310 } 311 312 313 extern "C" void ps(); 314 315 static bool error_reported = false; 316 317 // call this when the VM is dying--it might loosen some asserts 318 void set_error_reported() { 319 error_reported = true; 320 } 321 322 bool is_error_reported() { 323 return error_reported; 324 } 325 326 #ifndef PRODUCT 327 #include <signal.h> 328 329 void test_error_handler(size_t test_num) 330 { 331 if (test_num == 0) return; 332 333 // If asserts are disabled, use the corresponding guarantee instead. 334 size_t n = test_num; 335 NOT_DEBUG(if (n <= 2) n += 2); 336 337 const char* const str = "hello"; 338 const size_t num = (size_t)os::vm_page_size(); 339 340 const char* const eol = os::line_separator(); 341 const char* const msg = "this message should be truncated during formatting"; 342 343 // Keep this in sync with test/runtime/6888954/vmerrors.sh. 344 switch (n) { 345 case 1: assert(str == NULL, "expected null"); 346 case 2: assert(num == 1023 && *str == 'X', 347 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); 348 case 3: guarantee(str == NULL, "expected null"); 349 case 4: guarantee(num == 1023 && *str == 'X', 350 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); 351 case 5: fatal("expected null"); 352 case 6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); 353 case 7: fatal(err_msg("%s%s# %s%s# %s%s# %s%s# %s%s# " 354 "%s%s# %s%s# %s%s# %s%s# %s%s# " 355 "%s%s# %s%s# %s%s# %s%s# %s", 356 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, 357 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, 358 msg, eol, msg, eol, msg, eol, msg, eol, msg)); 359 case 8: vm_exit_out_of_memory(num, "ChunkPool::allocate"); 360 case 9: ShouldNotCallThis(); 361 case 10: ShouldNotReachHere(); 362 case 11: Unimplemented(); 363 // This is last because it does not generate an hs_err* file on Windows. 364 case 12: os::signal_raise(SIGSEGV); 365 366 default: ShouldNotReachHere(); 367 } 368 } 369 #endif // #ifndef PRODUCT 370 371 // ------ helper functions for debugging go here ------------ 372 373 #ifndef PRODUCT 374 // All debug entries should be wrapped with a stack allocated 375 // Command object. It makes sure a resource mark is set and 376 // flushes the logfile to prevent file sharing problems. 377 378 class Command : public StackObj { 379 private: 380 ResourceMark rm; 381 ResetNoHandleMark rnhm; 382 HandleMark hm; 383 bool debug_save; 384 public: 385 static int level; 386 Command(const char* str) { 387 debug_save = Debugging; 388 Debugging = true; 389 if (level++ > 0) return; 390 tty->cr(); 391 tty->print_cr("\"Executing %s\"", str); 392 } 393 394 ~Command() { tty->flush(); Debugging = debug_save; level--; } 395 }; 396 397 int Command::level = 0; 398 399 extern "C" void blob(CodeBlob* cb) { 400 Command c("blob"); 401 cb->print(); 402 } 403 404 405 extern "C" void dump_vtable(address p) { 406 Command c("dump_vtable"); 407 klassOop k = (klassOop)p; 408 instanceKlass::cast(k)->vtable()->print(); 409 } 410 411 412 extern "C" void nm(intptr_t p) { 413 // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability) 414 Command c("nm"); 415 CodeBlob* cb = CodeCache::find_blob((address)p); 416 if (cb == NULL) { 417 tty->print_cr("NULL"); 418 } else { 419 cb->print(); 420 } 421 } 422 423 424 extern "C" void disnm(intptr_t p) { 425 Command c("disnm"); 426 CodeBlob* cb = CodeCache::find_blob((address) p); 427 nmethod* nm = cb->as_nmethod_or_null(); 428 if (nm) { 429 nm->print(); 430 Disassembler::decode(nm); 431 } else { 432 cb->print(); 433 Disassembler::decode(cb); 434 } 435 } 436 437 438 extern "C" void printnm(intptr_t p) { 439 char buffer[256]; 440 sprintf(buffer, "printnm: " INTPTR_FORMAT, p); 441 Command c(buffer); 442 CodeBlob* cb = CodeCache::find_blob((address) p); 443 if (cb->is_nmethod()) { 444 nmethod* nm = (nmethod*)cb; 445 nm->print_nmethod(true); 446 } 447 } 448 449 450 extern "C" void universe() { 451 Command c("universe"); 452 Universe::print(); 453 } 454 455 456 extern "C" void verify() { 457 // try to run a verify on the entire system 458 // note: this may not be safe if we're not at a safepoint; for debugging, 459 // this manipulates the safepoint settings to avoid assertion failures 460 Command c("universe verify"); 461 bool safe = SafepointSynchronize::is_at_safepoint(); 462 if (!safe) { 463 tty->print_cr("warning: not at safepoint -- verify may fail"); 464 SafepointSynchronize::set_is_at_safepoint(); 465 } 466 // Ensure Eden top is correct before verification 467 Universe::heap()->prepare_for_verify(); 468 Universe::verify(true); 469 if (!safe) SafepointSynchronize::set_is_not_at_safepoint(); 470 } 471 472 473 extern "C" void pp(void* p) { 474 Command c("pp"); 475 FlagSetting fl(PrintVMMessages, true); 476 FlagSetting f2(DisplayVMOutput, true); 477 if (Universe::heap()->is_in(p)) { 478 oop obj = oop(p); 479 obj->print(); 480 } else { 481 tty->print("%#p", p); 482 } 483 } 484 485 486 // pv: print vm-printable object 487 extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); } 488 extern "C" void findpc(intptr_t x); 489 490 extern "C" void ps() { // print stack 491 Command c("ps"); 492 493 494 // Prints the stack of the current Java thread 495 JavaThread* p = JavaThread::active(); 496 tty->print(" for thread: "); 497 p->print(); 498 tty->cr(); 499 500 if (p->has_last_Java_frame()) { 501 // If the last_Java_fp is set we are in C land and 502 // can call the standard stack_trace function. 503 p->trace_stack(); 504 } else { 505 frame f = os::current_frame(); 506 RegisterMap reg_map(p); 507 f = f.sender(®_map); 508 tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id()); 509 p->trace_stack_from(vframe::new_vframe(&f, ®_map, p)); 510 pd_ps(f); 511 } 512 513 } 514 515 extern "C" void pfl() { 516 // print frame layout 517 Command c("pfl"); 518 JavaThread* p = JavaThread::active(); 519 tty->print(" for thread: "); 520 p->print(); 521 tty->cr(); 522 if (p->has_last_Java_frame()) { 523 p->print_frame_layout(); 524 } 525 } 526 527 extern "C" void psf() { // print stack frames 528 { 529 Command c("psf"); 530 JavaThread* p = JavaThread::active(); 531 tty->print(" for thread: "); 532 p->print(); 533 tty->cr(); 534 if (p->has_last_Java_frame()) { 535 p->trace_frames(); 536 } 537 } 538 } 539 540 541 extern "C" void threads() { 542 Command c("threads"); 543 Threads::print(false, true); 544 } 545 546 547 extern "C" void psd() { 548 Command c("psd"); 549 SystemDictionary::print(); 550 } 551 552 553 extern "C" void safepoints() { 554 Command c("safepoints"); 555 SafepointSynchronize::print_state(); 556 } 557 558 559 extern "C" void pss() { // print all stacks 560 Command c("pss"); 561 Threads::print(true, true); 562 } 563 564 565 extern "C" void debug() { // to set things up for compiler debugging 566 Command c("debug"); 567 WizardMode = true; 568 PrintVMMessages = PrintCompilation = true; 569 PrintInlining = PrintAssembly = true; 570 tty->flush(); 571 } 572 573 574 extern "C" void ndebug() { // undo debug() 575 Command c("ndebug"); 576 PrintCompilation = false; 577 PrintInlining = PrintAssembly = false; 578 tty->flush(); 579 } 580 581 582 extern "C" void flush() { 583 Command c("flush"); 584 tty->flush(); 585 } 586 587 588 extern "C" void events() { 589 Command c("events"); 590 Events::print_last(tty, 50); 591 } 592 593 594 extern "C" void nevents(int n) { 595 Command c("events"); 596 Events::print_last(tty, n); 597 } 598 599 600 // Given a heap address that was valid before the most recent GC, if 601 // the oop that used to contain it is still live, prints the new 602 // location of the oop and the address. Useful for tracking down 603 // certain kinds of naked oop and oop map bugs. 604 extern "C" void pnl(intptr_t old_heap_addr) { 605 // Print New Location of old heap address 606 Command c("pnl"); 607 #ifndef VALIDATE_MARK_SWEEP 608 tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled"); 609 #else 610 MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr); 611 #endif 612 } 613 614 615 extern "C" methodOop findm(intptr_t pc) { 616 Command c("findm"); 617 nmethod* nm = CodeCache::find_nmethod((address)pc); 618 return (nm == NULL) ? (methodOop)NULL : nm->method(); 619 } 620 621 622 extern "C" nmethod* findnm(intptr_t addr) { 623 Command c("findnm"); 624 return CodeCache::find_nmethod((address)addr); 625 } 626 627 static address same_page(address x, address y) { 628 intptr_t page_bits = -os::vm_page_size(); 629 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) { 630 return x; 631 } else if (x > y) { 632 return (address)(intptr_t(y) | ~page_bits) + 1; 633 } else { 634 return (address)(intptr_t(y) & page_bits); 635 } 636 } 637 638 class LookForRefInGenClosure : public OopsInGenClosure { 639 public: 640 oop target; 641 void do_oop(oop* o) { 642 if (o != NULL && *o == target) { 643 tty->print_cr(INTPTR_FORMAT, o); 644 } 645 } 646 void do_oop(narrowOop* o) { ShouldNotReachHere(); } 647 }; 648 649 650 class LookForRefInObjectClosure : public ObjectClosure { 651 private: 652 LookForRefInGenClosure look_in_object; 653 public: 654 LookForRefInObjectClosure(oop target) { look_in_object.target = target; } 655 void do_object(oop obj) { 656 obj->oop_iterate(&look_in_object); 657 } 658 }; 659 660 661 static void findref(intptr_t x) { 662 CollectedHeap *ch = Universe::heap(); 663 LookForRefInGenClosure lookFor; 664 lookFor.target = (oop) x; 665 LookForRefInObjectClosure look_in_object((oop) x); 666 667 tty->print_cr("Searching heap:"); 668 ch->object_iterate(&look_in_object); 669 670 tty->print_cr("Searching strong roots:"); 671 Universe::oops_do(&lookFor, false); 672 JNIHandles::oops_do(&lookFor); // Global (strong) JNI handles 673 Threads::oops_do(&lookFor, NULL); 674 ObjectSynchronizer::oops_do(&lookFor); 675 //FlatProfiler::oops_do(&lookFor); 676 SystemDictionary::oops_do(&lookFor); 677 678 tty->print_cr("Searching code cache:"); 679 CodeCache::oops_do(&lookFor); 680 681 tty->print_cr("Done."); 682 } 683 684 class FindClassObjectClosure: public ObjectClosure { 685 private: 686 const char* _target; 687 public: 688 FindClassObjectClosure(const char name[]) { _target = name; } 689 690 virtual void do_object(oop obj) { 691 if (obj->is_klass()) { 692 Klass* k = klassOop(obj)->klass_part(); 693 if (k->name() != NULL) { 694 ResourceMark rm; 695 const char* ext = k->external_name(); 696 if ( strcmp(_target, ext) == 0 ) { 697 tty->print_cr("Found " INTPTR_FORMAT, obj); 698 obj->print(); 699 } 700 } 701 } 702 } 703 }; 704 705 // 706 extern "C" void findclass(const char name[]) { 707 Command c("findclass"); 708 if (name != NULL) { 709 tty->print_cr("Finding class %s -> ", name); 710 FindClassObjectClosure srch(name); 711 Universe::heap()->permanent_object_iterate(&srch); 712 } 713 } 714 715 // Another interface that isn't ambiguous in dbx. 716 // Can we someday rename the other find to hsfind? 717 extern "C" void hsfind(intptr_t x) { 718 Command c("hsfind"); 719 os::print_location(tty, x, false); 720 } 721 722 723 extern "C" void hsfindref(intptr_t x) { 724 Command c("hsfindref"); 725 findref(x); 726 } 727 728 extern "C" void find(intptr_t x) { 729 Command c("find"); 730 os::print_location(tty, x, false); 731 } 732 733 734 extern "C" void findpc(intptr_t x) { 735 Command c("findpc"); 736 os::print_location(tty, x, true); 737 } 738 739 740 // int versions of all methods to avoid having to type type casts in the debugger 741 742 void pp(intptr_t p) { pp((void*)p); } 743 void pp(oop p) { pp((void*)p); } 744 745 void help() { 746 Command c("help"); 747 tty->print_cr("basic"); 748 tty->print_cr(" pp(void* p) - try to make sense of p"); 749 tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()"); 750 tty->print_cr(" ps() - print current thread stack"); 751 tty->print_cr(" pss() - print all thread stacks"); 752 tty->print_cr(" pm(int pc) - print methodOop given compiled PC"); 753 tty->print_cr(" findm(intptr_t pc) - finds methodOop"); 754 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it"); 755 756 tty->print_cr("misc."); 757 tty->print_cr(" flush() - flushes the log file"); 758 tty->print_cr(" events() - dump last 50 events"); 759 760 761 tty->print_cr("compiler debugging"); 762 tty->print_cr(" debug() - to set things up for compiler debugging"); 763 tty->print_cr(" ndebug() - undo debug"); 764 } 765 766 #if 0 767 768 // BobV's command parser for debugging on windows when nothing else works. 769 770 enum CommandID { 771 CMDID_HELP, 772 CMDID_QUIT, 773 CMDID_HSFIND, 774 CMDID_PSS, 775 CMDID_PS, 776 CMDID_PSF, 777 CMDID_FINDM, 778 CMDID_FINDNM, 779 CMDID_PP, 780 CMDID_BPT, 781 CMDID_EXIT, 782 CMDID_VERIFY, 783 CMDID_THREADS, 784 CMDID_ILLEGAL = 99 785 }; 786 787 struct CommandParser { 788 char *name; 789 CommandID code; 790 char *description; 791 }; 792 793 struct CommandParser CommandList[] = { 794 (char *)"help", CMDID_HELP, " Dump this list", 795 (char *)"quit", CMDID_QUIT, " Return from this routine", 796 (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address", 797 (char *)"ps", CMDID_PS, " Print Current Thread Stack Trace", 798 (char *)"pss", CMDID_PSS, " Print All Thread Stack Trace", 799 (char *)"psf", CMDID_PSF, " Print All Stack Frames", 800 (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC", 801 (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC", 802 (char *)"pp", CMDID_PP, " Find out something about a pointer", 803 (char *)"break", CMDID_BPT, " Execute a breakpoint", 804 (char *)"exitvm", CMDID_EXIT, "Exit the VM", 805 (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify", 806 (char *)"thread", CMDID_THREADS, "Dump Info on all Threads", 807 (char *)0, CMDID_ILLEGAL 808 }; 809 810 811 // get_debug_command() 812 // 813 // Read a command from standard input. 814 // This is useful when you have a debugger 815 // which doesn't support calling into functions. 816 // 817 void get_debug_command() 818 { 819 ssize_t count; 820 int i,j; 821 bool gotcommand; 822 intptr_t addr; 823 char buffer[256]; 824 nmethod *nm; 825 methodOop m; 826 827 tty->print_cr("You have entered the diagnostic command interpreter"); 828 tty->print("The supported commands are:\n"); 829 for ( i=0; ; i++ ) { 830 if ( CommandList[i].code == CMDID_ILLEGAL ) 831 break; 832 tty->print_cr(" %s \n", CommandList[i].name ); 833 } 834 835 while ( 1 ) { 836 gotcommand = false; 837 tty->print("Please enter a command: "); 838 count = scanf("%s", buffer) ; 839 if ( count >=0 ) { 840 for ( i=0; ; i++ ) { 841 if ( CommandList[i].code == CMDID_ILLEGAL ) { 842 if (!gotcommand) tty->print("Invalid command, please try again\n"); 843 break; 844 } 845 if ( strcmp(buffer, CommandList[i].name) == 0 ) { 846 gotcommand = true; 847 switch ( CommandList[i].code ) { 848 case CMDID_PS: 849 ps(); 850 break; 851 case CMDID_PSS: 852 pss(); 853 break; 854 case CMDID_PSF: 855 psf(); 856 break; 857 case CMDID_FINDM: 858 tty->print("Please enter the hex addr to pass to findm: "); 859 scanf("%I64X", &addr); 860 m = (methodOop)findm(addr); 861 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m); 862 break; 863 case CMDID_FINDNM: 864 tty->print("Please enter the hex addr to pass to findnm: "); 865 scanf("%I64X", &addr); 866 nm = (nmethod*)findnm(addr); 867 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm); 868 break; 869 case CMDID_PP: 870 tty->print("Please enter the hex addr to pass to pp: "); 871 scanf("%I64X", &addr); 872 pp((void*)addr); 873 break; 874 case CMDID_EXIT: 875 exit(0); 876 case CMDID_HELP: 877 tty->print("Here are the supported commands: "); 878 for ( j=0; ; j++ ) { 879 if ( CommandList[j].code == CMDID_ILLEGAL ) 880 break; 881 tty->print_cr(" %s -- %s\n", CommandList[j].name, 882 CommandList[j].description ); 883 } 884 break; 885 case CMDID_QUIT: 886 return; 887 break; 888 case CMDID_BPT: 889 BREAKPOINT; 890 break; 891 case CMDID_VERIFY: 892 verify();; 893 break; 894 case CMDID_THREADS: 895 threads();; 896 break; 897 case CMDID_HSFIND: 898 tty->print("Please enter the hex addr to pass to hsfind: "); 899 scanf("%I64X", &addr); 900 tty->print("Calling hsfind(0x%I64X)\n", addr); 901 hsfind(addr); 902 break; 903 default: 904 case CMDID_ILLEGAL: 905 break; 906 } 907 } 908 } 909 } 910 } 911 } 912 #endif 913 914 #endif // PRODUCT