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/thread.inline.hpp"
  48 #include "runtime/vframe.hpp"
  49 #include "services/heapDumper.hpp"
  50 #include "utilities/defaultStream.hpp"
  51 #include "utilities/events.hpp"
  52 #include "utilities/top.hpp"
  53 #include "utilities/vmError.hpp"
  54 #ifdef TARGET_OS_FAMILY_linux
  55 # include "os_linux.inline.hpp"
  56 #endif
  57 #ifdef TARGET_OS_FAMILY_solaris
  58 # include "os_solaris.inline.hpp"
  59 #endif
  60 #ifdef TARGET_OS_FAMILY_windows
  61 # include "os_windows.inline.hpp"
  62 #endif
  63 #ifdef TARGET_OS_FAMILY_bsd
  64 # include "os_bsd.inline.hpp"
  65 #endif
  66 
  67 #ifndef ASSERT
  68 #  ifdef _DEBUG
  69    // NOTE: don't turn the lines below into a comment -- if you're getting
  70    // a compile error here, change the settings to define ASSERT
  71    ASSERT should be defined when _DEBUG is defined.  It is not intended to be used for debugging
  72    functions that do not slow down the system too much and thus can be left in optimized code.
  73    On the other hand, the code should not be included in a production version.
  74 #  endif // _DEBUG
  75 #endif // ASSERT
  76 
  77 
  78 #ifdef _DEBUG
  79 #  ifndef ASSERT
  80      configuration error: ASSERT must be defined in debug version
  81 #  endif // ASSERT
  82 #endif // _DEBUG
  83 
  84 
  85 #ifdef PRODUCT
  86 #  if -defined _DEBUG || -defined ASSERT
  87      configuration error: ASSERT et al. must not be defined in PRODUCT version
  88 #  endif
  89 #endif // PRODUCT
  90 
  91 FormatBufferResource::FormatBufferResource(const char * format, ...)
  92   : FormatBufferBase((char*)resource_allocate_bytes(RES_BUFSZ)) {
  93   va_list argp;
  94   va_start(argp, format);
  95   jio_vsnprintf(_buf, RES_BUFSZ, format, argp);
  96   va_end(argp);
  97 }
  98 
  99 void warning(const char* format, ...) {
 100   if (PrintWarnings) {
 101     FILE* const err = defaultStream::error_stream();
 102     jio_fprintf(err, "%s warning: ", VM_Version::vm_name());
 103     va_list ap;
 104     va_start(ap, format);
 105     vfprintf(err, format, ap);
 106     va_end(ap);
 107     fputc('\n', err);
 108   }
 109   if (BreakAtWarning) BREAKPOINT;
 110 }
 111 
 112 #ifndef PRODUCT
 113 
 114 #define is_token_break(ch) (isspace(ch) || (ch) == ',')
 115 
 116 static const char* last_file_name = NULL;
 117 static int         last_line_no   = -1;
 118 
 119 // assert/guarantee/... may happen very early during VM initialization.
 120 // Don't rely on anything that is initialized by Threads::create_vm(). For
 121 // example, don't use tty.
 122 bool error_is_suppressed(const char* file_name, int line_no) {
 123   // The following 1-element cache requires that passed-in
 124   // file names are always only constant literals.
 125   if (file_name == last_file_name && line_no == last_line_no)  return true;
 126 
 127   int file_name_len = (int)strlen(file_name);
 128   char separator = os::file_separator()[0];
 129   const char* base_name = strrchr(file_name, separator);
 130   if (base_name == NULL)
 131     base_name = file_name;
 132 
 133   // scan the SuppressErrorAt option
 134   const char* cp = SuppressErrorAt;
 135   for (;;) {
 136     const char* sfile;
 137     int sfile_len;
 138     int sline;
 139     bool noisy;
 140     while ((*cp) != '\0' && is_token_break(*cp))  cp++;
 141     if ((*cp) == '\0')  break;
 142     sfile = cp;
 143     while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':')  cp++;
 144     sfile_len = cp - sfile;
 145     if ((*cp) == ':')  cp++;
 146     sline = 0;
 147     while ((*cp) != '\0' && isdigit(*cp)) {
 148       sline *= 10;
 149       sline += (*cp) - '0';
 150       cp++;
 151     }
 152     // "file:line!" means the assert suppression is not silent
 153     noisy = ((*cp) == '!');
 154     while ((*cp) != '\0' && !is_token_break(*cp))  cp++;
 155     // match the line
 156     if (sline != 0) {
 157       if (sline != line_no)  continue;
 158     }
 159     // match the file
 160     if (sfile_len > 0) {
 161       const char* look = file_name;
 162       const char* look_max = file_name + file_name_len - sfile_len;
 163       const char* foundp;
 164       bool match = false;
 165       while (!match
 166              && (foundp = strchr(look, sfile[0])) != NULL
 167              && foundp <= look_max) {
 168         match = true;
 169         for (int i = 1; i < sfile_len; i++) {
 170           if (sfile[i] != foundp[i]) {
 171             match = false;
 172             break;
 173           }
 174         }
 175         look = foundp + 1;
 176       }
 177       if (!match)  continue;
 178     }
 179     // got a match!
 180     if (noisy) {
 181       fdStream out(defaultStream::output_fd());
 182       out.print_raw("[error suppressed at ");
 183       out.print_raw(base_name);
 184       char buf[16];
 185       jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
 186       out.print_raw_cr(buf);
 187     } else {
 188       // update 1-element cache for fast silent matches
 189       last_file_name = file_name;
 190       last_line_no   = line_no;
 191     }
 192     return true;
 193   }
 194 
 195   if (!is_error_reported()) {
 196     // print a friendly hint:
 197     fdStream out(defaultStream::output_fd());
 198     out.print_raw_cr("# To suppress the following error report, specify this argument");
 199     out.print_raw   ("# after -XX: or in .hotspotrc:  SuppressErrorAt=");
 200     out.print_raw   (base_name);
 201     char buf[16];
 202     jio_snprintf(buf, sizeof(buf), ":%d", line_no);
 203     out.print_raw_cr(buf);
 204   }
 205   return false;
 206 }
 207 
 208 #undef is_token_break
 209 
 210 #else
 211 
 212 // Place-holder for non-existent suppression check:
 213 #define error_is_suppressed(file_name, line_no) (false)
 214 
 215 #endif // !PRODUCT
 216 
 217 void report_vm_error(const char* file, int line, const char* error_msg,
 218                      const char* detail_msg)
 219 {
 220   if (Debugging || error_is_suppressed(file, line)) return;
 221   Thread* const thread = ThreadLocalStorage::get_thread_slow();
 222   VMError err(thread, file, line, error_msg, detail_msg);
 223   err.report_and_die();
 224 }
 225 
 226 void report_fatal(const char* file, int line, const char* message)
 227 {
 228   report_vm_error(file, line, "fatal error", message);
 229 }
 230 
 231 // Used by report_vm_out_of_memory to detect recursion.
 232 static jint _exiting_out_of_mem = 0;
 233 
 234 void report_vm_out_of_memory(const char* file, int line, size_t size,
 235                              const char* message) {
 236   if (Debugging) return;
 237 
 238   // We try to gather additional information for the first out of memory
 239   // error only; gathering additional data might cause an allocation and a
 240   // recursive out_of_memory condition.
 241 
 242   const jint exiting = 1;
 243   // If we succeed in changing the value, we're the first one in.
 244   bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting;
 245 
 246   if (first_time_here) {
 247     Thread* thread = ThreadLocalStorage::get_thread_slow();
 248     VMError(thread, file, line, size, message).report_and_die();
 249   }
 250 
 251   // Dump core and abort
 252   vm_abort(true);
 253 }
 254 
 255 void report_should_not_call(const char* file, int line) {
 256   report_vm_error(file, line, "ShouldNotCall()");
 257 }
 258 
 259 void report_should_not_reach_here(const char* file, int line) {
 260   report_vm_error(file, line, "ShouldNotReachHere()");
 261 }
 262 
 263 void report_should_not_reach_here2(const char* file, int line, const char* message) {
 264   report_vm_error(file, line, "ShouldNotReachHere()", message);
 265 }
 266 
 267 void report_unimplemented(const char* file, int line) {
 268   report_vm_error(file, line, "Unimplemented()");
 269 }
 270 
 271 void report_untested(const char* file, int line, const char* message) {
 272 #ifndef PRODUCT
 273   warning("Untested: %s in %s: %d\n", message, file, line);
 274 #endif // !PRODUCT
 275 }
 276 
 277 void report_out_of_shared_space(SharedSpaceType shared_space) {
 278   static const char* name[] = {
 279     "native memory for metadata",
 280     "shared read only space",
 281     "shared read write space",
 282     "shared miscellaneous data space"
 283   };
 284   static const char* flag[] = {
 285     "Metaspace",
 286     "SharedReadOnlySize",
 287     "SharedReadWriteSize",
 288     "SharedMiscDataSize"
 289   };
 290 
 291    warning("\nThe %s is not large enough\n"
 292            "to preload requested classes. Use -XX:%s=\n"
 293            "to increase the initial size of %s.\n",
 294            name[shared_space], flag[shared_space], name[shared_space]);
 295    exit(2);
 296 }
 297 
 298 void report_java_out_of_memory(const char* message) {
 299   static jint out_of_memory_reported = 0;
 300 
 301   // A number of threads may attempt to report OutOfMemoryError at around the
 302   // same time. To avoid dumping the heap or executing the data collection
 303   // commands multiple times we just do it once when the first threads reports
 304   // the error.
 305   if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
 306     // create heap dump before OnOutOfMemoryError commands are executed
 307     if (HeapDumpOnOutOfMemoryError) {
 308       tty->print_cr("java.lang.OutOfMemoryError: %s", message);
 309       HeapDumper::dump_heap_from_oome();
 310     }
 311 
 312     if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
 313       VMError err(message);
 314       err.report_java_out_of_memory();
 315     }
 316   }
 317 }
 318 
 319 static bool error_reported = false;
 320 
 321 // call this when the VM is dying--it might loosen some asserts
 322 void set_error_reported() {
 323   error_reported = true;
 324 }
 325 
 326 bool is_error_reported() {
 327     return error_reported;
 328 }
 329 
 330 #ifndef PRODUCT
 331 #include <signal.h>
 332 
 333 void test_error_handler(size_t test_num)
 334 {
 335   if (test_num == 0) return;
 336 
 337   // If asserts are disabled, use the corresponding guarantee instead.
 338   size_t n = test_num;
 339   NOT_DEBUG(if (n <= 2) n += 2);
 340 
 341   const char* const str = "hello";
 342   const size_t      num = (size_t)os::vm_page_size();
 343 
 344   const char* const eol = os::line_separator();
 345   const char* const msg = "this message should be truncated during formatting";
 346 
 347   // Keep this in sync with test/runtime/6888954/vmerrors.sh.
 348   switch (n) {
 349     case  1: assert(str == NULL, "expected null");
 350     case  2: assert(num == 1023 && *str == 'X',
 351                     err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 352     case  3: guarantee(str == NULL, "expected null");
 353     case  4: guarantee(num == 1023 && *str == 'X',
 354                        err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 355     case  5: fatal("expected null");
 356     case  6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
 357     case  7: fatal(err_msg("%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 358                            "%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
 359                            "%s%s#    %s%s#    %s%s#    %s%s#    %s",
 360                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 361                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
 362                            msg, eol, msg, eol, msg, eol, msg, eol, msg));
 363     case  8: vm_exit_out_of_memory(num, "ChunkPool::allocate");
 364     case  9: ShouldNotCallThis();
 365     case 10: ShouldNotReachHere();
 366     case 11: Unimplemented();
 367     // This is last because it does not generate an hs_err* file on Windows.
 368     case 12: os::signal_raise(SIGSEGV);
 369 
 370     default: ShouldNotReachHere();
 371   }
 372 }
 373 #endif // !PRODUCT
 374 
 375 // ------ helper functions for debugging go here ------------
 376 
 377 // All debug entries should be wrapped with a stack allocated
 378 // Command object. It makes sure a resource mark is set and
 379 // flushes the logfile to prevent file sharing problems.
 380 
 381 class Command : public StackObj {
 382  private:
 383   ResourceMark rm;
 384   ResetNoHandleMark rnhm;
 385   HandleMark   hm;
 386   bool debug_save;
 387  public:
 388   static int level;
 389   Command(const char* str) {
 390     debug_save = Debugging;
 391     Debugging = true;
 392     if (level++ > 0)  return;
 393     tty->cr();
 394     tty->print_cr("\"Executing %s\"", str);
 395   }
 396 
 397   ~Command() {
 398         tty->flush();
 399         Debugging = debug_save;
 400         level--;
 401   }
 402 };
 403 
 404 int Command::level = 0;
 405 
 406 #ifndef PRODUCT
 407 
 408 extern "C" void blob(CodeBlob* cb) {
 409   Command c("blob");
 410   cb->print();
 411 }
 412 
 413 
 414 extern "C" void dump_vtable(address p) {
 415   Command c("dump_vtable");
 416   Klass* k = (Klass*)p;
 417   InstanceKlass::cast(k)->vtable()->print();
 418 }
 419 
 420 
 421 extern "C" void nm(intptr_t p) {
 422   // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
 423   Command c("nm");
 424   CodeBlob* cb = CodeCache::find_blob((address)p);
 425   if (cb == NULL) {
 426     tty->print_cr("NULL");
 427   } else {
 428     cb->print();
 429   }
 430 }
 431 
 432 
 433 extern "C" void disnm(intptr_t p) {
 434   Command c("disnm");
 435   CodeBlob* cb = CodeCache::find_blob((address) p);
 436   nmethod* nm = cb->as_nmethod_or_null();
 437   if (nm) {
 438     nm->print();
 439     Disassembler::decode(nm);
 440   } else {
 441     cb->print();
 442     Disassembler::decode(cb);
 443   }
 444 }
 445 
 446 
 447 extern "C" void printnm(intptr_t p) {
 448   char buffer[256];
 449   sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
 450   Command c(buffer);
 451   CodeBlob* cb = CodeCache::find_blob((address) p);
 452   if (cb->is_nmethod()) {
 453     nmethod* nm = (nmethod*)cb;
 454     nm->print_nmethod(true);
 455   }
 456 }
 457 
 458 
 459 extern "C" void universe() {
 460   Command c("universe");
 461   Universe::print();
 462 }
 463 
 464 
 465 extern "C" void verify() {
 466   // try to run a verify on the entire system
 467   // note: this may not be safe if we're not at a safepoint; for debugging,
 468   // this manipulates the safepoint settings to avoid assertion failures
 469   Command c("universe verify");
 470   bool safe = SafepointSynchronize::is_at_safepoint();
 471   if (!safe) {
 472     tty->print_cr("warning: not at safepoint -- verify may fail");
 473     SafepointSynchronize::set_is_at_safepoint();
 474   }
 475   // Ensure Eden top is correct before verification
 476   Universe::heap()->prepare_for_verify();
 477   Universe::verify();
 478   if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
 479 }
 480 
 481 
 482 extern "C" void pp(void* p) {
 483   Command c("pp");
 484   FlagSetting fl(PrintVMMessages, true);
 485   FlagSetting f2(DisplayVMOutput, true);
 486   if (Universe::heap()->is_in(p)) {
 487     oop obj = oop(p);
 488     obj->print();
 489   } else {
 490     tty->print(PTR_FORMAT, p);
 491   }
 492 }
 493 
 494 
 495 // pv: print vm-printable object
 496 extern "C" void pa(intptr_t p)   { ((AllocatedObj*) p)->print(); }
 497 extern "C" void findpc(intptr_t x);
 498 
 499 #endif // !PRODUCT
 500 
 501 extern "C" void ps() { // print stack
 502   if (Thread::current() == NULL) return;
 503   Command c("ps");
 504 
 505 
 506   // Prints the stack of the current Java thread
 507   JavaThread* p = JavaThread::active();
 508   tty->print(" for thread: ");
 509   p->print();
 510   tty->cr();
 511 
 512   if (p->has_last_Java_frame()) {
 513     // If the last_Java_fp is set we are in C land and
 514     // can call the standard stack_trace function.
 515 #ifdef PRODUCT
 516     p->print_stack();
 517   } else {
 518     tty->print_cr("Cannot find the last Java frame, printing stack disabled.");
 519 #else // !PRODUCT
 520     p->trace_stack();
 521   } else {
 522     frame f = os::current_frame();
 523     RegisterMap reg_map(p);
 524     f = f.sender(&reg_map);
 525     tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
 526     p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
 527   pd_ps(f);
 528 #endif // PRODUCT
 529   }
 530 
 531 }
 532 
 533 extern "C" void pfl() {
 534   // print frame layout
 535   Command c("pfl");
 536   JavaThread* p = JavaThread::active();
 537   tty->print(" for thread: ");
 538   p->print();
 539   tty->cr();
 540   if (p->has_last_Java_frame()) {
 541     p->print_frame_layout();
 542   }
 543 }
 544 
 545 #ifndef PRODUCT
 546 
 547 extern "C" void psf() { // print stack frames
 548   {
 549     Command c("psf");
 550     JavaThread* p = JavaThread::active();
 551     tty->print(" for thread: ");
 552     p->print();
 553     tty->cr();
 554     if (p->has_last_Java_frame()) {
 555       p->trace_frames();
 556     }
 557   }
 558 }
 559 
 560 
 561 extern "C" void threads() {
 562   Command c("threads");
 563   Threads::print(false, true);
 564 }
 565 
 566 
 567 extern "C" void psd() {
 568   Command c("psd");
 569   SystemDictionary::print();
 570 }
 571 
 572 
 573 extern "C" void safepoints() {
 574   Command c("safepoints");
 575   SafepointSynchronize::print_state();
 576 }
 577 
 578 #endif // !PRODUCT
 579 
 580 extern "C" void pss() { // print all stacks
 581   if (Thread::current() == NULL) return;
 582   Command c("pss");
 583   Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
 584 }
 585 
 586 #ifndef PRODUCT
 587 
 588 extern "C" void debug() {               // to set things up for compiler debugging
 589   Command c("debug");
 590   WizardMode = true;
 591   PrintVMMessages = PrintCompilation = true;
 592   PrintInlining = PrintAssembly = true;
 593   tty->flush();
 594 }
 595 
 596 
 597 extern "C" void ndebug() {              // undo debug()
 598   Command c("ndebug");
 599   PrintCompilation = false;
 600   PrintInlining = PrintAssembly = false;
 601   tty->flush();
 602 }
 603 
 604 
 605 extern "C" void flush()  {
 606   Command c("flush");
 607   tty->flush();
 608 }
 609 
 610 extern "C" void events() {
 611   Command c("events");
 612   Events::print();
 613 }
 614 
 615 // Given a heap address that was valid before the most recent GC, if
 616 // the oop that used to contain it is still live, prints the new
 617 // location of the oop and the address. Useful for tracking down
 618 // certain kinds of naked oop and oop map bugs.
 619 extern "C" void pnl(intptr_t old_heap_addr) {
 620   // Print New Location of old heap address
 621   Command c("pnl");
 622 #ifndef VALIDATE_MARK_SWEEP
 623   tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled");
 624 #else
 625   MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr);
 626 #endif
 627 }
 628 
 629 
 630 extern "C" Method* findm(intptr_t pc) {
 631   Command c("findm");
 632   nmethod* nm = CodeCache::find_nmethod((address)pc);
 633   return (nm == NULL) ? (Method*)NULL : nm->method();
 634 }
 635 
 636 
 637 extern "C" nmethod* findnm(intptr_t addr) {
 638   Command c("findnm");
 639   return  CodeCache::find_nmethod((address)addr);
 640 }
 641 
 642 static address same_page(address x, address y) {
 643   intptr_t page_bits = -os::vm_page_size();
 644   if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) {
 645     return x;
 646   } else if (x > y) {
 647     return (address)(intptr_t(y) | ~page_bits) + 1;
 648   } else {
 649     return (address)(intptr_t(y) & page_bits);
 650   }
 651 }
 652 
 653 
 654 // Another interface that isn't ambiguous in dbx.
 655 // Can we someday rename the other find to hsfind?
 656 extern "C" void hsfind(intptr_t x) {
 657   Command c("hsfind");
 658   os::print_location(tty, x, false);
 659 }
 660 
 661 
 662 extern "C" void find(intptr_t x) {
 663   Command c("find");
 664   os::print_location(tty, x, false);
 665 }
 666 
 667 
 668 extern "C" void findpc(intptr_t x) {
 669   Command c("findpc");
 670   os::print_location(tty, x, true);
 671 }
 672 
 673 
 674 // Need method pointer to find bcp, when not in permgen.
 675 extern "C" void findbcp(intptr_t method, intptr_t bcp) {
 676   Command c("findbcp");
 677   Method* mh = (Method*)method;
 678   if (!mh->is_native()) {
 679     tty->print_cr("bci_from(%p) = %d; print_codes():",
 680                         mh, mh->bci_from(address(bcp)));
 681     mh->print_codes_on(tty);
 682   }
 683 }
 684 
 685 // int versions of all methods to avoid having to type type casts in the debugger
 686 
 687 void pp(intptr_t p)          { pp((void*)p); }
 688 void pp(oop p)               { pp((void*)p); }
 689 
 690 void help() {
 691   Command c("help");
 692   tty->print_cr("basic");
 693   tty->print_cr("  pp(void* p)   - try to make sense of p");
 694   tty->print_cr("  pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
 695   tty->print_cr("  ps()          - print current thread stack");
 696   tty->print_cr("  pss()         - print all thread stacks");
 697   tty->print_cr("  pm(int pc)    - print Method* given compiled PC");
 698   tty->print_cr("  findm(intptr_t pc) - finds Method*");
 699   tty->print_cr("  find(intptr_t x)   - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
 700 
 701   tty->print_cr("misc.");
 702   tty->print_cr("  flush()       - flushes the log file");
 703   tty->print_cr("  events()      - dump events from ring buffers");
 704 
 705 
 706   tty->print_cr("compiler debugging");
 707   tty->print_cr("  debug()       - to set things up for compiler debugging");
 708   tty->print_cr("  ndebug()      - undo debug");
 709 }
 710 
 711 #if 0
 712 
 713 // BobV's command parser for debugging on windows when nothing else works.
 714 
 715 enum CommandID {
 716   CMDID_HELP,
 717   CMDID_QUIT,
 718   CMDID_HSFIND,
 719   CMDID_PSS,
 720   CMDID_PS,
 721   CMDID_PSF,
 722   CMDID_FINDM,
 723   CMDID_FINDNM,
 724   CMDID_PP,
 725   CMDID_BPT,
 726   CMDID_EXIT,
 727   CMDID_VERIFY,
 728   CMDID_THREADS,
 729   CMDID_ILLEGAL = 99
 730 };
 731 
 732 struct CommandParser {
 733    char *name;
 734    CommandID code;
 735    char *description;
 736 };
 737 
 738 struct CommandParser CommandList[] = {
 739   (char *)"help", CMDID_HELP, "  Dump this list",
 740   (char *)"quit", CMDID_QUIT, "  Return from this routine",
 741   (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address",
 742   (char *)"ps", CMDID_PS, "    Print Current Thread Stack Trace",
 743   (char *)"pss", CMDID_PSS, "   Print All Thread Stack Trace",
 744   (char *)"psf", CMDID_PSF, "   Print All Stack Frames",
 745   (char *)"findm", CMDID_FINDM, " Find a Method* from a PC",
 746   (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC",
 747   (char *)"pp", CMDID_PP, "    Find out something about a pointer",
 748   (char *)"break", CMDID_BPT, " Execute a breakpoint",
 749   (char *)"exitvm", CMDID_EXIT, "Exit the VM",
 750   (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify",
 751   (char *)"thread", CMDID_THREADS, "Dump Info on all Threads",
 752   (char *)0, CMDID_ILLEGAL
 753 };
 754 
 755 
 756 // get_debug_command()
 757 //
 758 // Read a command from standard input.
 759 // This is useful when you have a debugger
 760 // which doesn't support calling into functions.
 761 //
 762 void get_debug_command()
 763 {
 764   ssize_t count;
 765   int i,j;
 766   bool gotcommand;
 767   intptr_t addr;
 768   char buffer[256];
 769   nmethod *nm;
 770   Method* m;
 771 
 772   tty->print_cr("You have entered the diagnostic command interpreter");
 773   tty->print("The supported commands are:\n");
 774   for ( i=0; ; i++ ) {
 775     if ( CommandList[i].code == CMDID_ILLEGAL )
 776       break;
 777     tty->print_cr("  %s \n", CommandList[i].name );
 778   }
 779 
 780   while ( 1 ) {
 781     gotcommand = false;
 782     tty->print("Please enter a command: ");
 783     count = scanf("%s", buffer) ;
 784     if ( count >=0 ) {
 785       for ( i=0; ; i++ ) {
 786         if ( CommandList[i].code == CMDID_ILLEGAL ) {
 787           if (!gotcommand) tty->print("Invalid command, please try again\n");
 788           break;
 789         }
 790         if ( strcmp(buffer, CommandList[i].name) == 0 ) {
 791           gotcommand = true;
 792           switch ( CommandList[i].code ) {
 793               case CMDID_PS:
 794                 ps();
 795                 break;
 796               case CMDID_PSS:
 797                 pss();
 798                 break;
 799               case CMDID_PSF:
 800                 psf();
 801                 break;
 802               case CMDID_FINDM:
 803                 tty->print("Please enter the hex addr to pass to findm: ");
 804                 scanf("%I64X", &addr);
 805                 m = (Method*)findm(addr);
 806                 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m);
 807                 break;
 808               case CMDID_FINDNM:
 809                 tty->print("Please enter the hex addr to pass to findnm: ");
 810                 scanf("%I64X", &addr);
 811                 nm = (nmethod*)findnm(addr);
 812                 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm);
 813                 break;
 814               case CMDID_PP:
 815                 tty->print("Please enter the hex addr to pass to pp: ");
 816                 scanf("%I64X", &addr);
 817                 pp((void*)addr);
 818                 break;
 819               case CMDID_EXIT:
 820                 exit(0);
 821               case CMDID_HELP:
 822                 tty->print("Here are the supported commands: ");
 823                 for ( j=0; ; j++ ) {
 824                   if ( CommandList[j].code == CMDID_ILLEGAL )
 825                     break;
 826                   tty->print_cr("  %s --  %s\n", CommandList[j].name,
 827                                                  CommandList[j].description );
 828                 }
 829                 break;
 830               case CMDID_QUIT:
 831                 return;
 832                 break;
 833               case CMDID_BPT:
 834                 BREAKPOINT;
 835                 break;
 836               case CMDID_VERIFY:
 837                 verify();;
 838                 break;
 839               case CMDID_THREADS:
 840                 threads();;
 841                 break;
 842               case CMDID_HSFIND:
 843                 tty->print("Please enter the hex addr to pass to hsfind: ");
 844                 scanf("%I64X", &addr);
 845                 tty->print("Calling hsfind(0x%I64X)\n", addr);
 846                 hsfind(addr);
 847                 break;
 848               default:
 849               case CMDID_ILLEGAL:
 850                 break;
 851           }
 852         }
 853       }
 854     }
 855   }
 856 }
 857 #endif
 858 
 859 #endif // !PRODUCT