src/share/vm/utilities/debug.cpp

Tue, 12 Oct 2010 10:57:33 -0400

author
kamg
date
Tue, 12 Oct 2010 10:57:33 -0400
changeset 2225
c77b5c592eab
parent 2130
30f67acf635d
child 2314
f95d63e2154a
permissions
-rw-r--r--

6392697: Additional flag needed to supress Hotspot warning messages
Summary: Apply PrintJvmWarnings flag to all warnings
Reviewed-by: coleenp, phh

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

mercurial