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