src/share/vm/utilities/debug.cpp

Thu, 31 Mar 2011 16:54:27 -0700

author
kvn
date
Thu, 31 Mar 2011 16:54:27 -0700
changeset 2702
8010c8c623ac
parent 2497
3582bf76420e
child 2708
1d1603768966
permissions
-rw-r--r--

7032849: 7022998 changes broke hs_err compile task print
Summary: Initialize the time stamp on ostream used for hs_err dumping.
Reviewed-by: never

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

mercurial