debug.cpp revision 1410:f03d0a26bf83
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 error_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 error_is_suppressed(file_name, line_no) (false) 167 168#endif //PRODUCT 169 170void report_vm_error(const char* file, int line, const char* error_msg, 171 const char* detail_msg) 172{ 173 if (Debugging || error_is_suppressed(file, line)) return; 174 Thread* const thread = ThreadLocalStorage::get_thread_slow(); 175 VMError err(thread, file, line, error_msg, detail_msg); 176 err.report_and_die(); 177} 178 179void report_fatal(const char* file, int line, const char* message) 180{ 181 report_vm_error(file, line, "fatal error", message); 182} 183 184// Used by report_vm_out_of_memory to detect recursion. 185static jint _exiting_out_of_mem = 0; 186 187void report_vm_out_of_memory(const char* file, int line, size_t size, 188 const char* message) { 189 if (Debugging || error_is_suppressed(file, line)) return; 190 191 // We try to gather additional information for the first out of memory 192 // error only; gathering additional data might cause an allocation and a 193 // recursive out_of_memory condition. 194 195 const jint exiting = 1; 196 // If we succeed in changing the value, we're the first one in. 197 bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting; 198 199 if (first_time_here) { 200 Thread* thread = ThreadLocalStorage::get_thread_slow(); 201 VMError(thread, file, line, size, message).report_and_die(); 202 } 203 204 // Dump core and abort 205 vm_abort(true); 206} 207 208void report_should_not_call(const char* file, int line) { 209 report_vm_error(file, line, "ShouldNotCall()"); 210} 211 212void report_should_not_reach_here(const char* file, int line) { 213 report_vm_error(file, line, "ShouldNotReachHere()"); 214} 215 216void report_unimplemented(const char* file, int line) { 217 report_vm_error(file, line, "Unimplemented()"); 218} 219 220void report_untested(const char* file, int line, const char* message) { 221#ifndef PRODUCT 222 warning("Untested: %s in %s: %d\n", message, file, line); 223#endif // PRODUCT 224} 225 226void report_java_out_of_memory(const char* message) { 227 static jint out_of_memory_reported = 0; 228 229 // A number of threads may attempt to report OutOfMemoryError at around the 230 // same time. To avoid dumping the heap or executing the data collection 231 // commands multiple times we just do it once when the first threads reports 232 // the error. 233 if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) { 234 // create heap dump before OnOutOfMemoryError commands are executed 235 if (HeapDumpOnOutOfMemoryError) { 236 tty->print_cr("java.lang.OutOfMemoryError: %s", message); 237 HeapDumper::dump_heap(); 238 } 239 240 if (OnOutOfMemoryError && OnOutOfMemoryError[0]) { 241 VMError err(message); 242 err.report_java_out_of_memory(); 243 } 244 } 245} 246 247 248extern "C" void ps(); 249 250static bool error_reported = false; 251 252// call this when the VM is dying--it might loosen some asserts 253void set_error_reported() { 254 error_reported = true; 255} 256 257bool is_error_reported() { 258 return error_reported; 259} 260 261#ifndef PRODUCT 262#include <signal.h> 263 264void test_error_handler(size_t test_num) 265{ 266 if (test_num == 0) return; 267 268 // If asserts are disabled, use the corresponding guarantee instead. 269 size_t n = test_num; 270 NOT_DEBUG(if (n <= 2) n += 2); 271 272 const char* const str = "hello"; 273 const size_t num = (size_t)os::vm_page_size(); 274 275 const char* const eol = os::line_separator(); 276 const char* const msg = "this message should be truncated during formatting"; 277 278 // Keep this in sync with test/runtime/6888954/vmerrors.sh. 279 switch (n) { 280 case 1: assert(str == NULL, "expected null"); 281 case 2: assert(num == 1023 && *str == 'X', 282 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); 283 case 3: guarantee(str == NULL, "expected null"); 284 case 4: guarantee(num == 1023 && *str == 'X', 285 err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); 286 case 5: fatal("expected null"); 287 case 6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str)); 288 case 7: fatal(err_msg("%s%s# %s%s# %s%s# %s%s# %s%s# " 289 "%s%s# %s%s# %s%s# %s%s# %s%s# " 290 "%s%s# %s%s# %s%s# %s%s# %s", 291 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, 292 msg, eol, msg, eol, msg, eol, msg, eol, msg, eol, 293 msg, eol, msg, eol, msg, eol, msg, eol, msg)); 294 case 8: vm_exit_out_of_memory(num, "ChunkPool::allocate"); 295 case 9: ShouldNotCallThis(); 296 case 10: ShouldNotReachHere(); 297 case 11: Unimplemented(); 298 // This is last because it does not generate an hs_err* file on Windows. 299 case 12: os::signal_raise(SIGSEGV); 300 301 default: ShouldNotReachHere(); 302 } 303} 304#endif // #ifndef PRODUCT 305 306// ------ helper functions for debugging go here ------------ 307 308#ifndef PRODUCT 309// All debug entries should be wrapped with a stack allocated 310// Command object. It makes sure a resource mark is set and 311// flushes the logfile to prevent file sharing problems. 312 313class Command : public StackObj { 314 private: 315 ResourceMark rm; 316 ResetNoHandleMark rnhm; 317 HandleMark hm; 318 bool debug_save; 319 public: 320 static int level; 321 Command(const char* str) { 322 debug_save = Debugging; 323 Debugging = true; 324 if (level++ > 0) return; 325 tty->cr(); 326 tty->print_cr("\"Executing %s\"", str); 327 } 328 329 ~Command() { tty->flush(); Debugging = debug_save; level--; } 330}; 331 332int Command::level = 0; 333 334extern "C" void blob(CodeBlob* cb) { 335 Command c("blob"); 336 cb->print(); 337} 338 339 340extern "C" void dump_vtable(address p) { 341 Command c("dump_vtable"); 342 klassOop k = (klassOop)p; 343 instanceKlass::cast(k)->vtable()->print(); 344} 345 346 347extern "C" void nm(intptr_t p) { 348 // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability) 349 Command c("nm"); 350 CodeBlob* cb = CodeCache::find_blob((address)p); 351 if (cb == NULL) { 352 tty->print_cr("NULL"); 353 } else { 354 cb->print(); 355 } 356} 357 358 359extern "C" void disnm(intptr_t p) { 360 Command c("disnm"); 361 CodeBlob* cb = CodeCache::find_blob((address) p); 362 cb->print(); 363 Disassembler::decode(cb); 364} 365 366 367extern "C" void printnm(intptr_t p) { 368 char buffer[256]; 369 sprintf(buffer, "printnm: " INTPTR_FORMAT, p); 370 Command c(buffer); 371 CodeBlob* cb = CodeCache::find_blob((address) p); 372 if (cb->is_nmethod()) { 373 nmethod* nm = (nmethod*)cb; 374 nm->print_nmethod(true); 375 } 376} 377 378 379extern "C" void universe() { 380 Command c("universe"); 381 Universe::print(); 382} 383 384 385extern "C" void verify() { 386 // try to run a verify on the entire system 387 // note: this may not be safe if we're not at a safepoint; for debugging, 388 // this manipulates the safepoint settings to avoid assertion failures 389 Command c("universe verify"); 390 bool safe = SafepointSynchronize::is_at_safepoint(); 391 if (!safe) { 392 tty->print_cr("warning: not at safepoint -- verify may fail"); 393 SafepointSynchronize::set_is_at_safepoint(); 394 } 395 // Ensure Eden top is correct before verification 396 Universe::heap()->prepare_for_verify(); 397 Universe::verify(true); 398 if (!safe) SafepointSynchronize::set_is_not_at_safepoint(); 399} 400 401 402extern "C" void pp(void* p) { 403 Command c("pp"); 404 FlagSetting fl(PrintVMMessages, true); 405 if (Universe::heap()->is_in(p)) { 406 oop obj = oop(p); 407 obj->print(); 408 } else { 409 tty->print("%#p", p); 410 } 411} 412 413 414// pv: print vm-printable object 415extern "C" void pa(intptr_t p) { ((AllocatedObj*) p)->print(); } 416extern "C" void findpc(intptr_t x); 417 418extern "C" void ps() { // print stack 419 Command c("ps"); 420 421 422 // Prints the stack of the current Java thread 423 JavaThread* p = JavaThread::active(); 424 tty->print(" for thread: "); 425 p->print(); 426 tty->cr(); 427 428 if (p->has_last_Java_frame()) { 429 // If the last_Java_fp is set we are in C land and 430 // can call the standard stack_trace function. 431 p->trace_stack(); 432 } else { 433 frame f = os::current_frame(); 434 RegisterMap reg_map(p); 435 f = f.sender(®_map); 436 tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id()); 437 p->trace_stack_from(vframe::new_vframe(&f, ®_map, p)); 438 pd_ps(f); 439 } 440 441} 442 443 444extern "C" void psf() { // print stack frames 445 { 446 Command c("psf"); 447 JavaThread* p = JavaThread::active(); 448 tty->print(" for thread: "); 449 p->print(); 450 tty->cr(); 451 if (p->has_last_Java_frame()) { 452 p->trace_frames(); 453 } 454 } 455} 456 457 458extern "C" void threads() { 459 Command c("threads"); 460 Threads::print(false, true); 461} 462 463 464extern "C" void psd() { 465 Command c("psd"); 466 SystemDictionary::print(); 467} 468 469 470extern "C" void safepoints() { 471 Command c("safepoints"); 472 SafepointSynchronize::print_state(); 473} 474 475 476extern "C" void pss() { // print all stacks 477 Command c("pss"); 478 Threads::print(true, true); 479} 480 481 482extern "C" void debug() { // to set things up for compiler debugging 483 Command c("debug"); 484 WizardMode = true; 485 PrintVMMessages = PrintCompilation = true; 486 PrintInlining = PrintAssembly = true; 487 tty->flush(); 488} 489 490 491extern "C" void ndebug() { // undo debug() 492 Command c("ndebug"); 493 PrintCompilation = false; 494 PrintInlining = PrintAssembly = false; 495 tty->flush(); 496} 497 498 499extern "C" void flush() { 500 Command c("flush"); 501 tty->flush(); 502} 503 504 505extern "C" void events() { 506 Command c("events"); 507 Events::print_last(tty, 50); 508} 509 510 511extern "C" void nevents(int n) { 512 Command c("events"); 513 Events::print_last(tty, n); 514} 515 516 517// Given a heap address that was valid before the most recent GC, if 518// the oop that used to contain it is still live, prints the new 519// location of the oop and the address. Useful for tracking down 520// certain kinds of naked oop and oop map bugs. 521extern "C" void pnl(intptr_t old_heap_addr) { 522 // Print New Location of old heap address 523 Command c("pnl"); 524#ifndef VALIDATE_MARK_SWEEP 525 tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled"); 526#else 527 MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr); 528#endif 529} 530 531 532extern "C" methodOop findm(intptr_t pc) { 533 Command c("findm"); 534 nmethod* nm = CodeCache::find_nmethod((address)pc); 535 return (nm == NULL) ? (methodOop)NULL : nm->method(); 536} 537 538 539extern "C" nmethod* findnm(intptr_t addr) { 540 Command c("findnm"); 541 return CodeCache::find_nmethod((address)addr); 542} 543 544static address same_page(address x, address y) { 545 intptr_t page_bits = -os::vm_page_size(); 546 if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) { 547 return x; 548 } else if (x > y) { 549 return (address)(intptr_t(y) | ~page_bits) + 1; 550 } else { 551 return (address)(intptr_t(y) & page_bits); 552 } 553} 554 555 556static void find(intptr_t x, bool print_pc) { 557 address addr = (address)x; 558 559 CodeBlob* b = CodeCache::find_blob_unsafe(addr); 560 if (b != NULL) { 561 if (b->is_buffer_blob()) { 562 // the interpreter is generated into a buffer blob 563 InterpreterCodelet* i = Interpreter::codelet_containing(addr); 564 if (i != NULL) { 565 i->print(); 566 return; 567 } 568 if (Interpreter::contains(addr)) { 569 tty->print_cr(INTPTR_FORMAT " is pointing into interpreter code (not bytecode specific)", addr); 570 return; 571 } 572 // 573 if (AdapterHandlerLibrary::contains(b)) { 574 AdapterHandlerLibrary::print_handler(b); 575 } 576 // the stubroutines are generated into a buffer blob 577 StubCodeDesc* d = StubCodeDesc::desc_for(addr); 578 if (d != NULL) { 579 d->print(); 580 if (print_pc) tty->cr(); 581 return; 582 } 583 if (StubRoutines::contains(addr)) { 584 tty->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) stub routine", addr); 585 return; 586 } 587 // the InlineCacheBuffer is using stubs generated into a buffer blob 588 if (InlineCacheBuffer::contains(addr)) { 589 tty->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr); 590 return; 591 } 592 VtableStub* v = VtableStubs::stub_containing(addr); 593 if (v != NULL) { 594 v->print(); 595 return; 596 } 597 } 598 if (print_pc && b->is_nmethod()) { 599 ResourceMark rm; 600 tty->print("%#p: Compiled ", addr); 601 ((nmethod*)b)->method()->print_value_on(tty); 602 tty->print(" = (CodeBlob*)" INTPTR_FORMAT, b); 603 tty->cr(); 604 return; 605 } 606 if ( b->is_nmethod()) { 607 if (b->is_zombie()) { 608 tty->print_cr(INTPTR_FORMAT " is zombie nmethod", b); 609 } else if (b->is_not_entrant()) { 610 tty->print_cr(INTPTR_FORMAT " is non-entrant nmethod", b); 611 } 612 } 613 b->print(); 614 return; 615 } 616 617 if (Universe::heap()->is_in(addr)) { 618 HeapWord* p = Universe::heap()->block_start(addr); 619 bool print = false; 620 // If we couldn't find it it just may mean that heap wasn't parseable 621 // See if we were just given an oop directly 622 if (p != NULL && Universe::heap()->block_is_obj(p)) { 623 print = true; 624 } else if (p == NULL && ((oopDesc*)addr)->is_oop()) { 625 p = (HeapWord*) addr; 626 print = true; 627 } 628 if (print) { 629 oop(p)->print(); 630 if (p != (HeapWord*)x && oop(p)->is_constMethod() && 631 constMethodOop(p)->contains(addr)) { 632 Thread *thread = Thread::current(); 633 HandleMark hm(thread); 634 methodHandle mh (thread, constMethodOop(p)->method()); 635 if (!mh->is_native()) { 636 tty->print_cr("bci_from(%p) = %d; print_codes():", 637 addr, mh->bci_from(address(x))); 638 mh->print_codes(); 639 } 640 } 641 return; 642 } 643 } else if (Universe::heap()->is_in_reserved(addr)) { 644 tty->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", addr); 645 return; 646 } 647 648 if (JNIHandles::is_global_handle((jobject) addr)) { 649 tty->print_cr(INTPTR_FORMAT " is a global jni handle", addr); 650 return; 651 } 652 if (JNIHandles::is_weak_global_handle((jobject) addr)) { 653 tty->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr); 654 return; 655 } 656 if (JNIHandleBlock::any_contains((jobject) addr)) { 657 tty->print_cr(INTPTR_FORMAT " is a local jni handle", addr); 658 return; 659 } 660 661 for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) { 662 // Check for privilege stack 663 if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) { 664 tty->print_cr(INTPTR_FORMAT " is pointing into the privilege stack for thread: " INTPTR_FORMAT, addr, thread); 665 return; 666 } 667 // If the addr is a java thread print information about that. 668 if (addr == (address)thread) { 669 thread->print(); 670 return; 671 } 672 } 673 674 // Try an OS specific find 675 if (os::find(addr)) { 676 return; 677 } 678 679 if (print_pc) { 680 tty->print_cr(INTPTR_FORMAT ": probably in C++ code; check debugger", addr); 681 Disassembler::decode(same_page(addr-40,addr),same_page(addr+40,addr)); 682 return; 683 } 684 685 tty->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr); 686} 687 688 689class LookForRefInGenClosure : public OopsInGenClosure { 690public: 691 oop target; 692 void do_oop(oop* o) { 693 if (o != NULL && *o == target) { 694 tty->print_cr(INTPTR_FORMAT, o); 695 } 696 } 697 void do_oop(narrowOop* o) { ShouldNotReachHere(); } 698}; 699 700 701class LookForRefInObjectClosure : public ObjectClosure { 702private: 703 LookForRefInGenClosure look_in_object; 704public: 705 LookForRefInObjectClosure(oop target) { look_in_object.target = target; } 706 void do_object(oop obj) { 707 obj->oop_iterate(&look_in_object); 708 } 709}; 710 711 712static void findref(intptr_t x) { 713 CollectedHeap *ch = Universe::heap(); 714 LookForRefInGenClosure lookFor; 715 lookFor.target = (oop) x; 716 LookForRefInObjectClosure look_in_object((oop) x); 717 718 tty->print_cr("Searching heap:"); 719 ch->object_iterate(&look_in_object); 720 721 tty->print_cr("Searching strong roots:"); 722 Universe::oops_do(&lookFor, false); 723 JNIHandles::oops_do(&lookFor); // Global (strong) JNI handles 724 Threads::oops_do(&lookFor, NULL); 725 ObjectSynchronizer::oops_do(&lookFor); 726 //FlatProfiler::oops_do(&lookFor); 727 SystemDictionary::oops_do(&lookFor); 728 729 tty->print_cr("Searching code cache:"); 730 CodeCache::oops_do(&lookFor); 731 732 tty->print_cr("Done."); 733} 734 735class FindClassObjectClosure: public ObjectClosure { 736 private: 737 const char* _target; 738 public: 739 FindClassObjectClosure(const char name[]) { _target = name; } 740 741 virtual void do_object(oop obj) { 742 if (obj->is_klass()) { 743 Klass* k = klassOop(obj)->klass_part(); 744 if (k->name() != NULL) { 745 ResourceMark rm; 746 const char* ext = k->external_name(); 747 if ( strcmp(_target, ext) == 0 ) { 748 tty->print_cr("Found " INTPTR_FORMAT, obj); 749 obj->print(); 750 } 751 } 752 } 753 } 754}; 755 756// 757extern "C" void findclass(const char name[]) { 758 Command c("findclass"); 759 if (name != NULL) { 760 tty->print_cr("Finding class %s -> ", name); 761 FindClassObjectClosure srch(name); 762 Universe::heap()->permanent_object_iterate(&srch); 763 } 764} 765 766// Another interface that isn't ambiguous in dbx. 767// Can we someday rename the other find to hsfind? 768extern "C" void hsfind(intptr_t x) { 769 Command c("hsfind"); 770 find(x, false); 771} 772 773 774extern "C" void hsfindref(intptr_t x) { 775 Command c("hsfindref"); 776 findref(x); 777} 778 779extern "C" void find(intptr_t x) { 780 Command c("find"); 781 find(x, false); 782} 783 784 785extern "C" void findpc(intptr_t x) { 786 Command c("findpc"); 787 find(x, true); 788} 789 790 791// int versions of all methods to avoid having to type type casts in the debugger 792 793void pp(intptr_t p) { pp((void*)p); } 794void pp(oop p) { pp((void*)p); } 795 796void help() { 797 Command c("help"); 798 tty->print_cr("basic"); 799 tty->print_cr(" pp(void* p) - try to make sense of p"); 800 tty->print_cr(" pv(intptr_t p)- ((PrintableResourceObj*) p)->print()"); 801 tty->print_cr(" ps() - print current thread stack"); 802 tty->print_cr(" pss() - print all thread stacks"); 803 tty->print_cr(" pm(int pc) - print methodOop given compiled PC"); 804 tty->print_cr(" findm(intptr_t pc) - finds methodOop"); 805 tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it"); 806 807 tty->print_cr("misc."); 808 tty->print_cr(" flush() - flushes the log file"); 809 tty->print_cr(" events() - dump last 50 events"); 810 811 812 tty->print_cr("compiler debugging"); 813 tty->print_cr(" debug() - to set things up for compiler debugging"); 814 tty->print_cr(" ndebug() - undo debug"); 815} 816 817#if 0 818 819// BobV's command parser for debugging on windows when nothing else works. 820 821enum CommandID { 822 CMDID_HELP, 823 CMDID_QUIT, 824 CMDID_HSFIND, 825 CMDID_PSS, 826 CMDID_PS, 827 CMDID_PSF, 828 CMDID_FINDM, 829 CMDID_FINDNM, 830 CMDID_PP, 831 CMDID_BPT, 832 CMDID_EXIT, 833 CMDID_VERIFY, 834 CMDID_THREADS, 835 CMDID_ILLEGAL = 99 836}; 837 838struct CommandParser { 839 char *name; 840 CommandID code; 841 char *description; 842}; 843 844struct CommandParser CommandList[] = { 845 (char *)"help", CMDID_HELP, " Dump this list", 846 (char *)"quit", CMDID_QUIT, " Return from this routine", 847 (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address", 848 (char *)"ps", CMDID_PS, " Print Current Thread Stack Trace", 849 (char *)"pss", CMDID_PSS, " Print All Thread Stack Trace", 850 (char *)"psf", CMDID_PSF, " Print All Stack Frames", 851 (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC", 852 (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC", 853 (char *)"pp", CMDID_PP, " Find out something about a pointer", 854 (char *)"break", CMDID_BPT, " Execute a breakpoint", 855 (char *)"exitvm", CMDID_EXIT, "Exit the VM", 856 (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify", 857 (char *)"thread", CMDID_THREADS, "Dump Info on all Threads", 858 (char *)0, CMDID_ILLEGAL 859}; 860 861 862// get_debug_command() 863// 864// Read a command from standard input. 865// This is useful when you have a debugger 866// which doesn't support calling into functions. 867// 868void get_debug_command() 869{ 870 ssize_t count; 871 int i,j; 872 bool gotcommand; 873 intptr_t addr; 874 char buffer[256]; 875 nmethod *nm; 876 methodOop m; 877 878 tty->print_cr("You have entered the diagnostic command interpreter"); 879 tty->print("The supported commands are:\n"); 880 for ( i=0; ; i++ ) { 881 if ( CommandList[i].code == CMDID_ILLEGAL ) 882 break; 883 tty->print_cr(" %s \n", CommandList[i].name ); 884 } 885 886 while ( 1 ) { 887 gotcommand = false; 888 tty->print("Please enter a command: "); 889 count = scanf("%s", buffer) ; 890 if ( count >=0 ) { 891 for ( i=0; ; i++ ) { 892 if ( CommandList[i].code == CMDID_ILLEGAL ) { 893 if (!gotcommand) tty->print("Invalid command, please try again\n"); 894 break; 895 } 896 if ( strcmp(buffer, CommandList[i].name) == 0 ) { 897 gotcommand = true; 898 switch ( CommandList[i].code ) { 899 case CMDID_PS: 900 ps(); 901 break; 902 case CMDID_PSS: 903 pss(); 904 break; 905 case CMDID_PSF: 906 psf(); 907 break; 908 case CMDID_FINDM: 909 tty->print("Please enter the hex addr to pass to findm: "); 910 scanf("%I64X", &addr); 911 m = (methodOop)findm(addr); 912 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m); 913 break; 914 case CMDID_FINDNM: 915 tty->print("Please enter the hex addr to pass to findnm: "); 916 scanf("%I64X", &addr); 917 nm = (nmethod*)findnm(addr); 918 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm); 919 break; 920 case CMDID_PP: 921 tty->print("Please enter the hex addr to pass to pp: "); 922 scanf("%I64X", &addr); 923 pp((void*)addr); 924 break; 925 case CMDID_EXIT: 926 exit(0); 927 case CMDID_HELP: 928 tty->print("Here are the supported commands: "); 929 for ( j=0; ; j++ ) { 930 if ( CommandList[j].code == CMDID_ILLEGAL ) 931 break; 932 tty->print_cr(" %s -- %s\n", CommandList[j].name, 933 CommandList[j].description ); 934 } 935 break; 936 case CMDID_QUIT: 937 return; 938 break; 939 case CMDID_BPT: 940 BREAKPOINT; 941 break; 942 case CMDID_VERIFY: 943 verify();; 944 break; 945 case CMDID_THREADS: 946 threads();; 947 break; 948 case CMDID_HSFIND: 949 tty->print("Please enter the hex addr to pass to hsfind: "); 950 scanf("%I64X", &addr); 951 tty->print("Calling hsfind(0x%I64X)\n", addr); 952 hsfind(addr); 953 break; 954 default: 955 case CMDID_ILLEGAL: 956 break; 957 } 958 } 959 } 960 } 961 } 962} 963#endif 964 965#endif // PRODUCT 966