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(&reg_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, &reg_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