debug.cpp revision 356:1ee8caae33af
1/* 2 * Copyright 1997-2008 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25# include "incls/_precompiled.incl" 26# include "incls/_debug.cpp.incl" 27 28#ifndef ASSERT 29# ifdef _DEBUG 30 // NOTE: don't turn the lines below into a comment -- if you're getting 31 // a compile error here, change the settings to define ASSERT 32 ASSERT should be defined when _DEBUG is defined. It is not intended to be used for debugging 33 functions that do not slow down the system too much and thus can be left in optimized code. 34 On the other hand, the code should not be included in a production version. 35# endif // _DEBUG 36#endif // ASSERT 37 38 39#ifdef _DEBUG 40# ifndef ASSERT 41 configuration error: ASSERT must be defined in debug version 42# endif // ASSERT 43#endif // _DEBUG 44 45 46#ifdef PRODUCT 47# if -defined _DEBUG || -defined ASSERT 48 configuration error: ASSERT et al. must not be defined in PRODUCT version 49# endif 50#endif // PRODUCT 51 52 53void warning(const char* format, ...) { 54 // In case error happens before init or during shutdown 55 if (tty == NULL) ostream_init(); 56 57 tty->print("%s warning: ", VM_Version::vm_name()); 58 va_list ap; 59 va_start(ap, format); 60 tty->vprint_cr(format, ap); 61 va_end(ap); 62 if (BreakAtWarning) BREAKPOINT; 63} 64 65#ifndef PRODUCT 66 67#define is_token_break(ch) (isspace(ch) || (ch) == ',') 68 69static const char* last_file_name = NULL; 70static int last_line_no = -1; 71 72// assert/guarantee/... may happen very early during VM initialization. 73// Don't rely on anything that is initialized by Threads::create_vm(). For 74// example, don't use tty. 75bool assert_is_suppressed(const char* file_name, int line_no) { 76 // The following 1-element cache requires that passed-in 77 // file names are always only constant literals. 78 if (file_name == last_file_name && line_no == last_line_no) return true; 79 80 int file_name_len = (int)strlen(file_name); 81 char separator = os::file_separator()[0]; 82 const char* base_name = strrchr(file_name, separator); 83 if (base_name == NULL) 84 base_name = file_name; 85 86 // scan the SuppressErrorAt option 87 const char* cp = SuppressErrorAt; 88 for (;;) { 89 const char* sfile; 90 int sfile_len; 91 int sline; 92 bool noisy; 93 while ((*cp) != '\0' && is_token_break(*cp)) cp++; 94 if ((*cp) == '\0') break; 95 sfile = cp; 96 while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':') cp++; 97 sfile_len = cp - sfile; 98 if ((*cp) == ':') cp++; 99 sline = 0; 100 while ((*cp) != '\0' && isdigit(*cp)) { 101 sline *= 10; 102 sline += (*cp) - '0'; 103 cp++; 104 } 105 // "file:line!" means the assert suppression is not silent 106 noisy = ((*cp) == '!'); 107 while ((*cp) != '\0' && !is_token_break(*cp)) cp++; 108 // match the line 109 if (sline != 0) { 110 if (sline != line_no) continue; 111 } 112 // match the file 113 if (sfile_len > 0) { 114 const char* look = file_name; 115 const char* look_max = file_name + file_name_len - sfile_len; 116 const char* foundp; 117 bool match = false; 118 while (!match 119 && (foundp = strchr(look, sfile[0])) != NULL 120 && foundp <= look_max) { 121 match = true; 122 for (int i = 1; i < sfile_len; i++) { 123 if (sfile[i] != foundp[i]) { 124 match = false; 125 break; 126 } 127 } 128 look = foundp + 1; 129 } 130 if (!match) continue; 131 } 132 // got a match! 133 if (noisy) { 134 fdStream out(defaultStream::output_fd()); 135 out.print_raw("[error suppressed at "); 136 out.print_raw(base_name); 137 char buf[16]; 138 jio_snprintf(buf, sizeof(buf), ":%d]", line_no); 139 out.print_raw_cr(buf); 140 } else { 141 // update 1-element cache for fast silent matches 142 last_file_name = file_name; 143 last_line_no = line_no; 144 } 145 return true; 146 } 147 148 if (!is_error_reported()) { 149 // print a friendly hint: 150 fdStream out(defaultStream::output_fd()); 151 out.print_raw_cr("# To suppress the following error report, specify this argument"); 152 out.print_raw ("# after -XX: or in .hotspotrc: SuppressErrorAt="); 153 out.print_raw (base_name); 154 char buf[16]; 155 jio_snprintf(buf, sizeof(buf), ":%d", line_no); 156 out.print_raw_cr(buf); 157 } 158 return false; 159} 160 161#undef is_token_break 162 163#else 164 165// Place-holder for non-existent suppression check: 166#define assert_is_suppressed(file_name, line_no) (false) 167 168#endif //PRODUCT 169 170void report_assertion_failure(const char* file_name, int line_no, const char* message) { 171 if (Debugging || assert_is_suppressed(file_name, line_no)) return; 172 VMError err(ThreadLocalStorage::get_thread_slow(), message, file_name, line_no); 173 err.report_and_die(); 174} 175 176void report_fatal(const char* file_name, int line_no, const char* message) { 177 if (Debugging || assert_is_suppressed(file_name, line_no)) return; 178 VMError err(ThreadLocalStorage::get_thread_slow(), message, file_name, line_no); 179 err.report_and_die(); 180} 181 182void report_fatal_vararg(const char* file_name, int line_no, const char* format, ...) { 183 char buffer[256]; 184 va_list ap; 185 va_start(ap, format); 186 jio_vsnprintf(buffer, sizeof(buffer), format, ap); 187 va_end(ap); 188 report_fatal(file_name, line_no, buffer); 189} 190 191 192// Used by report_vm_out_of_memory to detect recursion. 193static jint _exiting_out_of_mem = 0; 194 195// Just passing the flow to VMError to handle error 196void report_vm_out_of_memory(const char* file_name, int line_no, size_t size, const char* message) { 197 if (Debugging || assert_is_suppressed(file_name, line_no)) return; 198 199 // We try to gather additional information for the first out of memory 200 // error only; gathering additional data might cause an allocation and a 201 // recursive out_of_memory condition. 202 203 const jint exiting = 1; 204 // If we succeed in changing the value, we're the first one in. 205 bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting; 206 207 if (first_time_here) { 208 Thread* thread = ThreadLocalStorage::get_thread_slow(); 209 VMError(thread, size, message, file_name, line_no).report_and_die(); 210 } 211 212 // Dump core and abort 213 vm_abort(true); 214} 215 216void report_vm_out_of_memory_vararg(const char* file_name, int line_no, size_t size, const char* format, ...) { 217 char buffer[256]; 218 va_list ap; 219 va_start(ap, format); 220 jio_vsnprintf(buffer, sizeof(buffer), format, ap); 221 va_end(ap); 222 report_vm_out_of_memory(file_name, line_no, size, buffer); 223} 224 225void report_should_not_call(const char* file_name, int line_no) { 226 if (Debugging || assert_is_suppressed(file_name, line_no)) return; 227 VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotCall()", file_name, line_no); 228 err.report_and_die(); 229} 230 231 232void report_should_not_reach_here(const char* file_name, int line_no) { 233 if (Debugging || assert_is_suppressed(file_name, line_no)) return; 234 VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotReachHere()", file_name, line_no); 235 err.report_and_die(); 236} 237 238 239void report_unimplemented(const char* file_name, int line_no) { 240 if (Debugging || assert_is_suppressed(file_name, line_no)) return; 241 VMError err(ThreadLocalStorage::get_thread_slow(), "Unimplemented()", file_name, line_no); 242 err.report_and_die(); 243} 244 245 246void report_untested(const char* file_name, int line_no, const char* msg) { 247#ifndef PRODUCT 248 warning("Untested: %s in %s: %d\n", msg, file_name, line_no); 249#endif // PRODUCT 250} 251 252void report_java_out_of_memory(const char* message) { 253 static jint out_of_memory_reported = 0; 254 255 // A number of threads may attempt to report OutOfMemoryError at around the 256 // same time. To avoid dumping the heap or executing the data collection 257 // commands multiple times we just do it once when the first threads reports 258 // the error. 259 if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) { 260 // create heap dump before OnOutOfMemoryError commands are executed 261 if (HeapDumpOnOutOfMemoryError) { 262 tty->print_cr("java.lang.OutOfMemoryError: %s", message); 263 HeapDumper::dump_heap(); 264 } 265 266 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) { 267 VMError err(message); 268 err.report_java_out_of_memory(); 269 } 270 } 271} 272 273 274extern "C" void ps(); 275 276static bool error_reported = false; 277 278// call this when the VM is dying--it might loosen some asserts 279void set_error_reported() { 280 error_reported = true; 281} 282 283bool is_error_reported() { 284 return error_reported; 285} 286 287// ------ helper functions for debugging go here ------------ 288 289#ifndef PRODUCT 290// All debug entries should be wrapped with a stack allocated 291// Command object. It makes sure a resource mark is set and 292// flushes the logfile to prevent file sharing problems. 293 294class Command : public StackObj { 295 private: 296 ResourceMark rm; 297 ResetNoHandleMark rnhm; 298 HandleMark hm; 299 bool debug_save; 300 public: 301 static int level; 302 Command(const char* str) { 303 debug_save = Debugging; 304 Debugging = true; 305 if (level++ > 0) return; 306 tty->cr(); 307 tty->print_cr("\"Executing %s\"", str); 308 } 309 310 ~Command() { tty->flush(); Debugging = debug_save; level--; } 311}; 312 313int Command::level = 0; 314 315extern "C" void blob(CodeBlob* cb) { 316 Command c("blob"); 317 cb->print(); 318} 319 320 321extern "C" void dump_vtable(address p) { 322 Command c("dump_vtable"); 323 klassOop k = (klassOop)p; 324 instanceKlass::cast(k)->vtable()->print(); 325} 326 327 328extern "C" void nm(intptr_t p) { 329 // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability) 330 Command c("nm"); 331 CodeBlob* cb = CodeCache::find_blob((address)p); 332 if (cb == NULL) { 333 tty->print_cr("NULL"); 334 } else { 335 cb->print(); 336 } 337} 338 339 340extern "C" void disnm(intptr_t p) { 341 Command c("disnm"); 342 CodeBlob* cb = CodeCache::find_blob((address) p); 343 cb->print(); 344 Disassembler::decode(cb); 345} 346 347 348extern "C" void printnm(intptr_t p) { 349 char buffer[256]; 350 sprintf(buffer, "printnm: " INTPTR_FORMAT, p); 351 Command c(buffer); 352 CodeBlob* cb = CodeCache::find_blob((address) p); 353 if (cb->is_nmethod()) { 354 nmethod* nm = (nmethod*)cb; 355 nm->print_nmethod(true); 356 } 357} 358 359 360extern "C" void universe() { 361 Command c("universe"); 362 Universe::print(); 363} 364 365 366extern "C" void verify() { 367 // try to run a verify on the entire system 368 // note: this may not be safe if we're not at a safepoint; for debugging, 369 // this manipulates the safepoint settings to avoid assertion failures 370 Command c("universe verify"); 371 bool safe = SafepointSynchronize::is_at_safepoint(); 372 if (!safe) { 373 tty->print_cr("warning: not at safepoint -- verify may fail"); 374 SafepointSynchronize::set_is_at_safepoint(); 375 } 376 // Ensure Eden top is correct before verification 377 Universe::heap()->prepare_for_verify(); 378 Universe::verify(true); 379 if (!safe) SafepointSynchronize::set_is_not_at_safepoint(); 380} 381 382 383extern "C" void pp(void* p) { 384 Command c("pp"); 385 FlagSetting fl(PrintVMMessages, true); 386 if (Universe::heap()->is_in(p)) { 387 oop obj = oop(p); 388 obj->print(); 389 } else { 390 tty->print("%#p", p); 391 } 392} 393 394 395// pv: print vm-printable object 396extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); } 397extern "C" void findpc(intptr_t x); 398 399extern "C" void ps() { // print stack 400 Command c("ps"); 401 402 403 // Prints the stack of the current Java thread 404 JavaThread* p = JavaThread::active(); 405 tty->print(" for thread: "); 406 p->print(); 407 tty->cr(); 408 409 if (p->has_last_Java_frame()) { 410 // If the last_Java_fp is set we are in C land and 411 // can call the standard stack_trace function. 412 p->trace_stack(); 413 } else { 414 frame f = os::current_frame(); 415 RegisterMap reg_map(p); 416 f = f.sender(®_map); 417 tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id()); 418 p->trace_stack_from(vframe::new_vframe(&f, ®_map, p)); 419 pd_ps(f); 420 } 421 422} 423 424 425extern "C" void psf() { // print stack frames 426 { 427 Command c("psf"); 428 JavaThread* p = JavaThread::active(); 429 tty->print(" for thread: "); 430 p->print(); 431 tty->cr(); 432 if (p->has_last_Java_frame()) { 433 p->trace_frames(); 434 } 435 } 436} 437 438 439extern "C" void threads() { 440 Command c("threads"); 441 Threads::print(false, true); 442} 443 444 445extern "C" void psd() { 446 Command c("psd"); 447 SystemDictionary::print(); 448} 449 450 451extern "C" void safepoints() { 452 Command c("safepoints"); 453 SafepointSynchronize::print_state(); 454} 455 456 457extern "C" void pss() { // print all stacks 458 Command c("pss"); 459 Threads::print(true, true); 460} 461 462 463extern "C" void debug() { // to set things up for compiler debugging 464 Command c("debug"); 465 WizardMode = true; 466 PrintVMMessages = PrintCompilation = true; 467 PrintInlining = PrintAssembly = true; 468 tty->flush(); 469} 470 471 472extern "C" void ndebug() { // undo debug() 473 Command c("ndebug"); 474 PrintCompilation = false; 475 PrintInlining = PrintAssembly = false; 476 tty->flush(); 477} 478 479 480extern "C" void flush() { 481 Command c("flush"); 482 tty->flush(); 483} 484 485 486extern "C" void events() { 487 Command c("events"); 488 Events::print_last(tty, 50); 489} 490 491 492extern "C" void nevents(int n) { 493 Command c("events"); 494 Events::print_last(tty, n); 495} 496 497 498// Given a heap address that was valid before the most recent GC, if 499// the oop that used to contain it is still live, prints the new 500// location of the oop and the address. Useful for tracking down 501// certain kinds of naked oop and oop map bugs. 502extern "C" void pnl(intptr_t old_heap_addr) { 503 // Print New Location of old heap address 504 Command c("pnl"); 505#ifndef VALIDATE_MARK_SWEEP 506 tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled"); 507#else 508 MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr); 509#endif 510} 511 512 513extern "C" methodOop findm(intptr_t pc) { 514 Command c("findm"); 515 nmethod* nm = CodeCache::find_nmethod((address)pc); 516 return (nm == NULL) ? (methodOop)NULL : nm->method(); 517} 518 519 520extern "C" nmethod* findnm(intptr_t addr) { 521 Command c("findnm"); 522 return CodeCache::find_nmethod((address)addr); 523} 524 525static address same_page(address x, address y) { 526 intptr_t page_bits = -os::vm_page_size(); 527 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) { 528 return x; 529 } else if (x > y) { 530 return (address)(intptr_t(y) | ~page_bits) + 1; 531 } else { 532 return (address)(intptr_t(y) & page_bits); 533 } 534} 535 536 537static void find(intptr_t x, bool print_pc) { 538 address addr = (address)x; 539 540 CodeBlob* b = CodeCache::find_blob_unsafe(addr); 541 if (b != NULL) { 542 if (b->is_buffer_blob()) { 543 // the interpreter is generated into a buffer blob 544 InterpreterCodelet* i = Interpreter::codelet_containing(addr); 545 if (i != NULL) { 546 i->print(); 547 return; 548 } 549 if (Interpreter::contains(addr)) { 550 tty->print_cr(INTPTR_FORMAT " is pointing into interpreter code (not bytecode specific)", addr); 551 return; 552 } 553 // 554 if (AdapterHandlerLibrary::contains(b)) { 555 AdapterHandlerLibrary::print_handler(b); 556 } 557 // the stubroutines are generated into a buffer blob 558 StubCodeDesc* d = StubCodeDesc::desc_for(addr); 559 if (d != NULL) { 560 d->print(); 561 if (print_pc) tty->cr(); 562 return; 563 } 564 if (StubRoutines::contains(addr)) { 565 tty->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) stub routine", addr); 566 return; 567 } 568 // the InlineCacheBuffer is using stubs generated into a buffer blob 569 if (InlineCacheBuffer::contains(addr)) { 570 tty->print_cr(INTPTR_FORMAT "is pointing into InlineCacheBuffer", addr); 571 return; 572 } 573 VtableStub* v = VtableStubs::stub_containing(addr); 574 if (v != NULL) { 575 v->print(); 576 return; 577 } 578 } 579 if (print_pc && b->is_nmethod()) { 580 ResourceMark rm; 581 tty->print("%#p: Compiled ", addr); 582 ((nmethod*)b)->method()->print_value_on(tty); 583 tty->print(" = (CodeBlob*)" INTPTR_FORMAT, b); 584 tty->cr(); 585 return; 586 } 587 if ( b->is_nmethod()) { 588 if (b->is_zombie()) { 589 tty->print_cr(INTPTR_FORMAT " is zombie nmethod", b); 590 } else if (b->is_not_entrant()) { 591 tty->print_cr(INTPTR_FORMAT " is non-entrant nmethod", b); 592 } 593 } 594 b->print(); 595 return; 596 } 597 598 if (Universe::heap()->is_in_reserved(addr)) { 599 HeapWord* p = Universe::heap()->block_start(addr); 600 bool print = false; 601 // If we couldn't find it it just may mean that heap wasn't parseable 602 // See if we were just given an oop directly 603 if (p != NULL && Universe::heap()->block_is_obj(p)) { 604 print = true; 605 } else if (p == NULL && ((oopDesc*)addr)->is_oop()) { 606 p = (HeapWord*) addr; 607 print = true; 608 } 609 if (print) { 610 oop(p)->print(); 611 if (p != (HeapWord*)x && oop(p)->is_constMethod() && 612 constMethodOop(p)->contains(addr)) { 613 Thread *thread = Thread::current(); 614 HandleMark hm(thread); 615 methodHandle mh (thread, constMethodOop(p)->method()); 616 if (!mh->is_native()) { 617 tty->print_cr("bci_from(%p) = %d; print_codes():", 618 addr, mh->bci_from(address(x))); 619 mh->print_codes(); 620 } 621 } 622 return; 623 } 624 } 625 if (JNIHandles::is_global_handle((jobject) addr)) { 626 tty->print_cr(INTPTR_FORMAT "is a global jni handle", addr); 627 return; 628 } 629 if (JNIHandles::is_weak_global_handle((jobject) addr)) { 630 tty->print_cr(INTPTR_FORMAT "is a weak global jni handle", addr); 631 return; 632 } 633 if (JNIHandleBlock::any_contains((jobject) addr)) { 634 tty->print_cr(INTPTR_FORMAT "is a local jni handle", addr); 635 return; 636 } 637 638 for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) { 639 // Check for priviledge stack 640 if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) { 641 tty->print_cr(INTPTR_FORMAT "is pointing into the priviledge stack for thread: " INTPTR_FORMAT, addr, thread); 642 return; 643 } 644 // If the addr is a java thread print information about that. 645 if (addr == (address)thread) { 646 thread->print(); 647 return; 648 } 649 } 650 651 // Try an OS specific find 652 if (os::find(addr)) { 653 return; 654 } 655 656 if (print_pc) { 657 tty->print_cr(INTPTR_FORMAT ": probably in C++ code; check debugger", addr); 658 Disassembler::decode(same_page(addr-40,addr),same_page(addr+40,addr)); 659 return; 660 } 661 662 tty->print_cr(INTPTR_FORMAT "is pointing to unknown location", addr); 663} 664 665 666class LookForRefInGenClosure : public OopsInGenClosure { 667public: 668 oop target; 669 void do_oop(oop* o) { 670 if (o != NULL && *o == target) { 671 tty->print_cr(INTPTR_FORMAT, o); 672 } 673 } 674 void do_oop(narrowOop* o) { ShouldNotReachHere(); } 675}; 676 677 678class LookForRefInObjectClosure : public ObjectClosure { 679private: 680 LookForRefInGenClosure look_in_object; 681public: 682 LookForRefInObjectClosure(oop target) { look_in_object.target = target; } 683 void do_object(oop obj) { 684 obj->oop_iterate(&look_in_object); 685 } 686}; 687 688 689static void findref(intptr_t x) { 690 CollectedHeap *ch = Universe::heap(); 691 LookForRefInGenClosure lookFor; 692 lookFor.target = (oop) x; 693 LookForRefInObjectClosure look_in_object((oop) x); 694 695 tty->print_cr("Searching heap:"); 696 ch->object_iterate(&look_in_object); 697 698 tty->print_cr("Searching strong roots:"); 699 Universe::oops_do(&lookFor, false); 700 JNIHandles::oops_do(&lookFor); // Global (strong) JNI handles 701 Threads::oops_do(&lookFor); 702 ObjectSynchronizer::oops_do(&lookFor); 703 //FlatProfiler::oops_do(&lookFor); 704 SystemDictionary::oops_do(&lookFor); 705 706 tty->print_cr("Done."); 707} 708 709class FindClassObjectClosure: public ObjectClosure { 710 private: 711 const char* _target; 712 public: 713 FindClassObjectClosure(const char name[]) { _target = name; } 714 715 virtual void do_object(oop obj) { 716 if (obj->is_klass()) { 717 Klass* k = klassOop(obj)->klass_part(); 718 if (k->name() != NULL) { 719 ResourceMark rm; 720 const char* ext = k->external_name(); 721 if ( strcmp(_target, ext) == 0 ) { 722 tty->print_cr("Found " INTPTR_FORMAT, obj); 723 obj->print(); 724 } 725 } 726 } 727 } 728}; 729 730// 731extern "C" void findclass(const char name[]) { 732 Command c("findclass"); 733 if (name != NULL) { 734 tty->print_cr("Finding class %s -> ", name); 735 FindClassObjectClosure srch(name); 736 Universe::heap()->permanent_object_iterate(&srch); 737 } 738} 739 740// Another interface that isn't ambiguous in dbx. 741// Can we someday rename the other find to hsfind? 742extern "C" void hsfind(intptr_t x) { 743 Command c("hsfind"); 744 find(x, false); 745} 746 747 748extern "C" void hsfindref(intptr_t x) { 749 Command c("hsfindref"); 750 findref(x); 751} 752 753extern "C" void find(intptr_t x) { 754 Command c("find"); 755 find(x, false); 756} 757 758 759extern "C" void findpc(intptr_t x) { 760 Command c("findpc"); 761 find(x, true); 762} 763 764 765// int versions of all methods to avoid having to type type casts in the debugger 766 767void pp(intptr_t p) { pp((void*)p); } 768void pp(oop p) { pp((void*)p); } 769 770void help() { 771 Command c("help"); 772 tty->print_cr("basic"); 773 tty->print_cr(" pp(void* p) - try to make sense of p"); 774 tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()"); 775 tty->print_cr(" ps() - print current thread stack"); 776 tty->print_cr(" pss() - print all thread stacks"); 777 tty->print_cr(" pm(int pc) - print methodOop given compiled PC"); 778 tty->print_cr(" findm(intptr_t pc) - finds methodOop"); 779 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it"); 780 781 tty->print_cr("misc."); 782 tty->print_cr(" flush() - flushes the log file"); 783 tty->print_cr(" events() - dump last 50 events"); 784 785 786 tty->print_cr("compiler debugging"); 787 tty->print_cr(" debug() - to set things up for compiler debugging"); 788 tty->print_cr(" ndebug() - undo debug"); 789} 790 791#if 0 792 793// BobV's command parser for debugging on windows when nothing else works. 794 795enum CommandID { 796 CMDID_HELP, 797 CMDID_QUIT, 798 CMDID_HSFIND, 799 CMDID_PSS, 800 CMDID_PS, 801 CMDID_PSF, 802 CMDID_FINDM, 803 CMDID_FINDNM, 804 CMDID_PP, 805 CMDID_BPT, 806 CMDID_EXIT, 807 CMDID_VERIFY, 808 CMDID_THREADS, 809 CMDID_ILLEGAL = 99 810}; 811 812struct CommandParser { 813 char *name; 814 CommandID code; 815 char *description; 816}; 817 818struct CommandParser CommandList[] = { 819 (char *)"help", CMDID_HELP, " Dump this list", 820 (char *)"quit", CMDID_QUIT, " Return from this routine", 821 (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address", 822 (char *)"ps", CMDID_PS, " Print Current Thread Stack Trace", 823 (char *)"pss", CMDID_PSS, " Print All Thread Stack Trace", 824 (char *)"psf", CMDID_PSF, " Print All Stack Frames", 825 (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC", 826 (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC", 827 (char *)"pp", CMDID_PP, " Find out something about a pointer", 828 (char *)"break", CMDID_BPT, " Execute a breakpoint", 829 (char *)"exitvm", CMDID_EXIT, "Exit the VM", 830 (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify", 831 (char *)"thread", CMDID_THREADS, "Dump Info on all Threads", 832 (char *)0, CMDID_ILLEGAL 833}; 834 835 836// get_debug_command() 837// 838// Read a command from standard input. 839// This is useful when you have a debugger 840// which doesn't support calling into functions. 841// 842void get_debug_command() 843{ 844 ssize_t count; 845 int i,j; 846 bool gotcommand; 847 intptr_t addr; 848 char buffer[256]; 849 nmethod *nm; 850 methodOop m; 851 852 tty->print_cr("You have entered the diagnostic command interpreter"); 853 tty->print("The supported commands are:\n"); 854 for ( i=0; ; i++ ) { 855 if ( CommandList[i].code == CMDID_ILLEGAL ) 856 break; 857 tty->print_cr(" %s \n", CommandList[i].name ); 858 } 859 860 while ( 1 ) { 861 gotcommand = false; 862 tty->print("Please enter a command: "); 863 count = scanf("%s", buffer) ; 864 if ( count >=0 ) { 865 for ( i=0; ; i++ ) { 866 if ( CommandList[i].code == CMDID_ILLEGAL ) { 867 if (!gotcommand) tty->print("Invalid command, please try again\n"); 868 break; 869 } 870 if ( strcmp(buffer, CommandList[i].name) == 0 ) { 871 gotcommand = true; 872 switch ( CommandList[i].code ) { 873 case CMDID_PS: 874 ps(); 875 break; 876 case CMDID_PSS: 877 pss(); 878 break; 879 case CMDID_PSF: 880 psf(); 881 break; 882 case CMDID_FINDM: 883 tty->print("Please enter the hex addr to pass to findm: "); 884 scanf("%I64X", &addr); 885 m = (methodOop)findm(addr); 886 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m); 887 break; 888 case CMDID_FINDNM: 889 tty->print("Please enter the hex addr to pass to findnm: "); 890 scanf("%I64X", &addr); 891 nm = (nmethod*)findnm(addr); 892 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm); 893 break; 894 case CMDID_PP: 895 tty->print("Please enter the hex addr to pass to pp: "); 896 scanf("%I64X", &addr); 897 pp((void*)addr); 898 break; 899 case CMDID_EXIT: 900 exit(0); 901 case CMDID_HELP: 902 tty->print("Here are the supported commands: "); 903 for ( j=0; ; j++ ) { 904 if ( CommandList[j].code == CMDID_ILLEGAL ) 905 break; 906 tty->print_cr(" %s -- %s\n", CommandList[j].name, 907 CommandList[j].description ); 908 } 909 break; 910 case CMDID_QUIT: 911 return; 912 break; 913 case CMDID_BPT: 914 BREAKPOINT; 915 break; 916 case CMDID_VERIFY: 917 verify();; 918 break; 919 case CMDID_THREADS: 920 threads();; 921 break; 922 case CMDID_HSFIND: 923 tty->print("Please enter the hex addr to pass to hsfind: "); 924 scanf("%I64X", &addr); 925 tty->print("Calling hsfind(0x%I64X)\n", addr); 926 hsfind(addr); 927 break; 928 default: 929 case CMDID_ILLEGAL: 930 break; 931 } 932 } 933 } 934 } 935 } 936} 937#endif 938 939#endif // PRODUCT 940