1 /* 2 * Copyright (c) 1997, 2013, 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 Thread* thread = ThreadLocalStorage::get_thread_slow(); 239 VMError(thread, file, line, size, message).report_and_die(); 240 241 // The UseOSErrorReporting option in report_and_die() may allow a return to here. 242 // If so then we'll have to figure out how to handle it. 243 guarantee(false, "report_and_die() should not return here"); 244 } 245 246 void report_should_not_call(const char* file, int line) { 247 report_vm_error(file, line, "ShouldNotCall()"); 248 } 249 250 void report_should_not_reach_here(const char* file, int line) { 251 report_vm_error(file, line, "ShouldNotReachHere()"); 252 } 253 254 void report_should_not_reach_here2(const char* file, int line, const char* message) { 255 report_vm_error(file, line, "ShouldNotReachHere()", message); 256 } 257 258 void report_unimplemented(const char* file, int line) { 259 report_vm_error(file, line, "Unimplemented()"); 260 } 261 262 void report_untested(const char* file, int line, const char* message) { 263 #ifndef PRODUCT 264 warning("Untested: %s in %s: %d\n", message, file, line); 265 #endif // !PRODUCT 266 } 267 268 void report_out_of_shared_space(SharedSpaceType shared_space) { 269 static const char* name[] = { 270 "native memory for metadata", 271 "shared read only space", 272 "shared read write space", 273 "shared miscellaneous data space" 274 }; 275 static const char* flag[] = { 276 "Metaspace", 277 "SharedReadOnlySize", 278 "SharedReadWriteSize", 279 "SharedMiscDataSize" 280 }; 281 282 warning("\nThe %s is not large enough\n" 283 "to preload requested classes. Use -XX:%s=\n" 284 "to increase the initial size of %s.\n", 285 name[shared_space], flag[shared_space], name[shared_space]); 286 exit(2); 287 } 288 289 void report_java_out_of_memory(const char* message) { 290 static jint out_of_memory_reported = 0; 291 292 // A number of threads may attempt to report OutOfMemoryError at around the 293 // same time. To avoid dumping the heap or executing the data collection 294 // commands multiple times we just do it once when the first threads reports 295 // the error. 296 if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) { 297 // create heap dump before OnOutOfMemoryError commands are executed 298 if (HeapDumpOnOutOfMemoryError) { 299 tty->print_cr("java.lang.OutOfMemoryError: %s", message); 300 HeapDumper::dump_heap_from_oome(); 301 } 302 303 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) { 304 VMError err(message); 305 err.report_java_out_of_memory(); 306 } 307 } 308 } 309 310 static bool error_reported = false; 311 312 // call this when the VM is dying--it might loosen some asserts 313 void set_error_reported() { 314 error_reported = true; 315 } 316 317 bool is_error_reported() { 318 return error_reported; 319 } 320 321 #ifndef PRODUCT 322 #include <signal.h> 323 324 void test_error_handler(size_t test_num) 325 { 326 if (test_num == 0) return; 327 328 // If asserts are disabled, use the corresponding guarantee instead. 329 size_t n = test_num; 330 NOT_DEBUG(if (n <= 2) n += 2); 331 332 const char* const str = "hello"; 333 const size_t num = (size_t)os::vm_page_size(); 334 335 const char* const eol = os::line_separator(); 336 const char* const msg = "this message should be truncated during formatting"; 337 338 // Keep this in sync with test/runtime/6888954/vmerrors.sh. 339 switch (n) { 340 case 1: assert(str == NULL, "expected null"); 341 case 2: assert(num == 1023 && *str == 'X', 342 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); 343 case 3: guarantee(str == NULL, "expected null"); 344 case 4: guarantee(num == 1023 && *str == 'X', 345 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); 346 case 5: fatal("expected null"); 347 case 6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); 348 case 7: fatal(err_msg("%s%s# %s%s# %s%s# %s%s# %s%s# " 349 "%s%s# %s%s# %s%s# %s%s# %s%s# " 350 "%s%s# %s%s# %s%s# %s%s# %s", 351 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, 352 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, 353 msg, eol, msg, eol, msg, eol, msg, eol, msg)); 354 case 8: vm_exit_out_of_memory(num, "ChunkPool::allocate"); 355 case 9: ShouldNotCallThis(); 356 case 10: ShouldNotReachHere(); 357 case 11: Unimplemented(); 358 // This is last because it does not generate an hs_err* file on Windows. 359 case 12: os::signal_raise(SIGSEGV); 360 361 default: ShouldNotReachHere(); 362 } 363 } 364 #endif // !PRODUCT 365 366 // ------ helper functions for debugging go here ------------ 367 368 // All debug entries should be wrapped with a stack allocated 369 // Command object. It makes sure a resource mark is set and 370 // flushes the logfile to prevent file sharing problems. 371 372 class Command : public StackObj { 373 private: 374 ResourceMark rm; 375 ResetNoHandleMark rnhm; 376 HandleMark hm; 377 bool debug_save; 378 public: 379 static int level; 380 Command(const char* str) { 381 debug_save = Debugging; 382 Debugging = true; 383 if (level++ > 0) return; 384 tty->cr(); 385 tty->print_cr("\"Executing %s\"", str); 386 } 387 388 ~Command() { 389 tty->flush(); 390 Debugging = debug_save; 391 level--; 392 } 393 }; 394 395 int Command::level = 0; 396 397 #ifndef PRODUCT 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 Klass* k = (Klass*)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(); 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(PTR_FORMAT, 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 #endif // !PRODUCT 491 492 extern "C" void ps() { // print stack 493 if (Thread::current() == NULL) return; 494 Command c("ps"); 495 496 497 // Prints the stack of the current Java thread 498 JavaThread* p = JavaThread::active(); 499 tty->print(" for thread: "); 500 p->print(); 501 tty->cr(); 502 503 if (p->has_last_Java_frame()) { 504 // If the last_Java_fp is set we are in C land and 505 // can call the standard stack_trace function. 506 #ifdef PRODUCT 507 p->print_stack(); 508 } else { 509 tty->print_cr("Cannot find the last Java frame, printing stack disabled."); 510 #else // !PRODUCT 511 p->trace_stack(); 512 } else { 513 frame f = os::current_frame(); 514 RegisterMap reg_map(p); 515 f = f.sender(®_map); 516 tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id()); 517 p->trace_stack_from(vframe::new_vframe(&f, ®_map, p)); 518 pd_ps(f); 519 #endif // PRODUCT 520 } 521 522 } 523 524 extern "C" void pfl() { 525 // print frame layout 526 Command c("pfl"); 527 JavaThread* p = JavaThread::active(); 528 tty->print(" for thread: "); 529 p->print(); 530 tty->cr(); 531 if (p->has_last_Java_frame()) { 532 p->print_frame_layout(); 533 } 534 } 535 536 #ifndef PRODUCT 537 538 extern "C" void psf() { // print stack frames 539 { 540 Command c("psf"); 541 JavaThread* p = JavaThread::active(); 542 tty->print(" for thread: "); 543 p->print(); 544 tty->cr(); 545 if (p->has_last_Java_frame()) { 546 p->trace_frames(); 547 } 548 } 549 } 550 551 552 extern "C" void threads() { 553 Command c("threads"); 554 Threads::print(false, true); 555 } 556 557 558 extern "C" void psd() { 559 Command c("psd"); 560 SystemDictionary::print(); 561 } 562 563 564 extern "C" void safepoints() { 565 Command c("safepoints"); 566 SafepointSynchronize::print_state(); 567 } 568 569 #endif // !PRODUCT 570 571 extern "C" void pss() { // print all stacks 572 if (Thread::current() == NULL) return; 573 Command c("pss"); 574 Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true)); 575 } 576 577 #ifndef PRODUCT 578 579 extern "C" void debug() { // to set things up for compiler debugging 580 Command c("debug"); 581 WizardMode = true; 582 PrintVMMessages = PrintCompilation = true; 583 PrintInlining = PrintAssembly = true; 584 tty->flush(); 585 } 586 587 588 extern "C" void ndebug() { // undo debug() 589 Command c("ndebug"); 590 PrintCompilation = false; 591 PrintInlining = PrintAssembly = false; 592 tty->flush(); 593 } 594 595 596 extern "C" void flush() { 597 Command c("flush"); 598 tty->flush(); 599 } 600 601 extern "C" void events() { 602 Command c("events"); 603 Events::print(); 604 } 605 606 extern "C" Method* findm(intptr_t pc) { 607 Command c("findm"); 608 nmethod* nm = CodeCache::find_nmethod((address)pc); 609 return (nm == NULL) ? (Method*)NULL : nm->method(); 610 } 611 612 613 extern "C" nmethod* findnm(intptr_t addr) { 614 Command c("findnm"); 615 return CodeCache::find_nmethod((address)addr); 616 } 617 618 static address same_page(address x, address y) { 619 intptr_t page_bits = -os::vm_page_size(); 620 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) { 621 return x; 622 } else if (x > y) { 623 return (address)(intptr_t(y) | ~page_bits) + 1; 624 } else { 625 return (address)(intptr_t(y) & page_bits); 626 } 627 } 628 629 630 // Another interface that isn't ambiguous in dbx. 631 // Can we someday rename the other find to hsfind? 632 extern "C" void hsfind(intptr_t x) { 633 Command c("hsfind"); 634 os::print_location(tty, x, false); 635 } 636 637 638 extern "C" void find(intptr_t x) { 639 Command c("find"); 640 os::print_location(tty, x, false); 641 } 642 643 644 extern "C" void findpc(intptr_t x) { 645 Command c("findpc"); 646 os::print_location(tty, x, true); 647 } 648 649 650 // Need method pointer to find bcp, when not in permgen. 651 extern "C" void findbcp(intptr_t method, intptr_t bcp) { 652 Command c("findbcp"); 653 Method* mh = (Method*)method; 654 if (!mh->is_native()) { 655 tty->print_cr("bci_from(%p) = %d; print_codes():", 656 mh, mh->bci_from(address(bcp))); 657 mh->print_codes_on(tty); 658 } 659 } 660 661 // int versions of all methods to avoid having to type type casts in the debugger 662 663 void pp(intptr_t p) { pp((void*)p); } 664 void pp(oop p) { pp((void*)p); } 665 666 void help() { 667 Command c("help"); 668 tty->print_cr("basic"); 669 tty->print_cr(" pp(void* p) - try to make sense of p"); 670 tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()"); 671 tty->print_cr(" ps() - print current thread stack"); 672 tty->print_cr(" pss() - print all thread stacks"); 673 tty->print_cr(" pm(int pc) - print Method* given compiled PC"); 674 tty->print_cr(" findm(intptr_t pc) - finds Method*"); 675 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it"); 676 677 tty->print_cr("misc."); 678 tty->print_cr(" flush() - flushes the log file"); 679 tty->print_cr(" events() - dump events from ring buffers"); 680 681 682 tty->print_cr("compiler debugging"); 683 tty->print_cr(" debug() - to set things up for compiler debugging"); 684 tty->print_cr(" ndebug() - undo debug"); 685 } 686 687 #if 0 688 689 // BobV's command parser for debugging on windows when nothing else works. 690 691 enum CommandID { 692 CMDID_HELP, 693 CMDID_QUIT, 694 CMDID_HSFIND, 695 CMDID_PSS, 696 CMDID_PS, 697 CMDID_PSF, 698 CMDID_FINDM, 699 CMDID_FINDNM, 700 CMDID_PP, 701 CMDID_BPT, 702 CMDID_EXIT, 703 CMDID_VERIFY, 704 CMDID_THREADS, 705 CMDID_ILLEGAL = 99 706 }; 707 708 struct CommandParser { 709 char *name; 710 CommandID code; 711 char *description; 712 }; 713 714 struct CommandParser CommandList[] = { 715 (char *)"help", CMDID_HELP, " Dump this list", 716 (char *)"quit", CMDID_QUIT, " Return from this routine", 717 (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address", 718 (char *)"ps", CMDID_PS, " Print Current Thread Stack Trace", 719 (char *)"pss", CMDID_PSS, " Print All Thread Stack Trace", 720 (char *)"psf", CMDID_PSF, " Print All Stack Frames", 721 (char *)"findm", CMDID_FINDM, " Find a Method* from a PC", 722 (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC", 723 (char *)"pp", CMDID_PP, " Find out something about a pointer", 724 (char *)"break", CMDID_BPT, " Execute a breakpoint", 725 (char *)"exitvm", CMDID_EXIT, "Exit the VM", 726 (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify", 727 (char *)"thread", CMDID_THREADS, "Dump Info on all Threads", 728 (char *)0, CMDID_ILLEGAL 729 }; 730 731 732 // get_debug_command() 733 // 734 // Read a command from standard input. 735 // This is useful when you have a debugger 736 // which doesn't support calling into functions. 737 // 738 void get_debug_command() 739 { 740 ssize_t count; 741 int i,j; 742 bool gotcommand; 743 intptr_t addr; 744 char buffer[256]; 745 nmethod *nm; 746 Method* m; 747 748 tty->print_cr("You have entered the diagnostic command interpreter"); 749 tty->print("The supported commands are:\n"); 750 for ( i=0; ; i++ ) { 751 if ( CommandList[i].code == CMDID_ILLEGAL ) 752 break; 753 tty->print_cr(" %s \n", CommandList[i].name ); 754 } 755 756 while ( 1 ) { 757 gotcommand = false; 758 tty->print("Please enter a command: "); 759 count = scanf("%s", buffer) ; 760 if ( count >=0 ) { 761 for ( i=0; ; i++ ) { 762 if ( CommandList[i].code == CMDID_ILLEGAL ) { 763 if (!gotcommand) tty->print("Invalid command, please try again\n"); 764 break; 765 } 766 if ( strcmp(buffer, CommandList[i].name) == 0 ) { 767 gotcommand = true; 768 switch ( CommandList[i].code ) { 769 case CMDID_PS: 770 ps(); 771 break; 772 case CMDID_PSS: 773 pss(); 774 break; 775 case CMDID_PSF: 776 psf(); 777 break; 778 case CMDID_FINDM: 779 tty->print("Please enter the hex addr to pass to findm: "); 780 scanf("%I64X", &addr); 781 m = (Method*)findm(addr); 782 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m); 783 break; 784 case CMDID_FINDNM: 785 tty->print("Please enter the hex addr to pass to findnm: "); 786 scanf("%I64X", &addr); 787 nm = (nmethod*)findnm(addr); 788 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm); 789 break; 790 case CMDID_PP: 791 tty->print("Please enter the hex addr to pass to pp: "); 792 scanf("%I64X", &addr); 793 pp((void*)addr); 794 break; 795 case CMDID_EXIT: 796 exit(0); 797 case CMDID_HELP: 798 tty->print("Here are the supported commands: "); 799 for ( j=0; ; j++ ) { 800 if ( CommandList[j].code == CMDID_ILLEGAL ) 801 break; 802 tty->print_cr(" %s -- %s\n", CommandList[j].name, 803 CommandList[j].description ); 804 } 805 break; 806 case CMDID_QUIT: 807 return; 808 break; 809 case CMDID_BPT: 810 BREAKPOINT; 811 break; 812 case CMDID_VERIFY: 813 verify();; 814 break; 815 case CMDID_THREADS: 816 threads();; 817 break; 818 case CMDID_HSFIND: 819 tty->print("Please enter the hex addr to pass to hsfind: "); 820 scanf("%I64X", &addr); 821 tty->print("Calling hsfind(0x%I64X)\n", addr); 822 hsfind(addr); 823 break; 824 default: 825 case CMDID_ILLEGAL: 826 break; 827 } 828 } 829 } 830 } 831 } 832 } 833 #endif 834 835 #endif // !PRODUCT