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