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