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