src/share/vm/utilities/debug.cpp

Wed, 09 Apr 2008 15:10:22 -0700

author
rasbold
date
Wed, 09 Apr 2008 15:10:22 -0700
changeset 544
9f4457a14b58
parent 435
a61af66fc99e
child 548
ba764ed4b6f2
permissions
-rw-r--r--

Merge

     1 /*
     2  * Copyright 1997-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any 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   // In case error happens before init or during shutdown
    55   if (tty == NULL) ostream_init();
    57   tty->print("%s warning: ", VM_Version::vm_name());
    58   va_list ap;
    59   va_start(ap, format);
    60   tty->vprint_cr(format, ap);
    61   va_end(ap);
    62   if (BreakAtWarning) BREAKPOINT;
    63 }
    65 #ifndef PRODUCT
    67 #define is_token_break(ch) (isspace(ch) || (ch) == ',')
    69 static const char* last_file_name = NULL;
    70 static int         last_line_no   = -1;
    72 // assert/guarantee/... may happen very early during VM initialization.
    73 // Don't rely on anything that is initialized by Threads::create_vm(). For
    74 // example, don't use tty.
    75 bool assert_is_suppressed(const char* file_name, int line_no) {
    76   // The following 1-element cache requires that passed-in
    77   // file names are always only constant literals.
    78   if (file_name == last_file_name && line_no == last_line_no)  return true;
    80   int file_name_len = (int)strlen(file_name);
    81   char separator = os::file_separator()[0];
    82   const char* base_name = strrchr(file_name, separator);
    83   if (base_name == NULL)
    84     base_name = file_name;
    86   // scan the SuppressErrorAt option
    87   const char* cp = SuppressErrorAt;
    88   for (;;) {
    89     const char* sfile;
    90     int sfile_len;
    91     int sline;
    92     bool noisy;
    93     while ((*cp) != '\0' && is_token_break(*cp))  cp++;
    94     if ((*cp) == '\0')  break;
    95     sfile = cp;
    96     while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':')  cp++;
    97     sfile_len = cp - sfile;
    98     if ((*cp) == ':')  cp++;
    99     sline = 0;
   100     while ((*cp) != '\0' && isdigit(*cp)) {
   101       sline *= 10;
   102       sline += (*cp) - '0';
   103       cp++;
   104     }
   105     // "file:line!" means the assert suppression is not silent
   106     noisy = ((*cp) == '!');
   107     while ((*cp) != '\0' && !is_token_break(*cp))  cp++;
   108     // match the line
   109     if (sline != 0) {
   110       if (sline != line_no)  continue;
   111     }
   112     // match the file
   113     if (sfile_len > 0) {
   114       const char* look = file_name;
   115       const char* look_max = file_name + file_name_len - sfile_len;
   116       const char* foundp;
   117       bool match = false;
   118       while (!match
   119              && (foundp = strchr(look, sfile[0])) != NULL
   120              && foundp <= look_max) {
   121         match = true;
   122         for (int i = 1; i < sfile_len; i++) {
   123           if (sfile[i] != foundp[i]) {
   124             match = false;
   125             break;
   126           }
   127         }
   128         look = foundp + 1;
   129       }
   130       if (!match)  continue;
   131     }
   132     // got a match!
   133     if (noisy) {
   134       fdStream out(defaultStream::output_fd());
   135       out.print_raw("[error suppressed at ");
   136       out.print_raw(base_name);
   137       char buf[16];
   138       jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
   139       out.print_raw_cr(buf);
   140     } else {
   141       // update 1-element cache for fast silent matches
   142       last_file_name = file_name;
   143       last_line_no   = line_no;
   144     }
   145     return true;
   146   }
   148   if (!is_error_reported()) {
   149     // print a friendly hint:
   150     fdStream out(defaultStream::output_fd());
   151     out.print_raw_cr("# To suppress the following error report, specify this argument");
   152     out.print_raw   ("# after -XX: or in .hotspotrc:  SuppressErrorAt=");
   153     out.print_raw   (base_name);
   154     char buf[16];
   155     jio_snprintf(buf, sizeof(buf), ":%d", line_no);
   156     out.print_raw_cr(buf);
   157   }
   158   return false;
   159 }
   161 #undef is_token_break
   163 #else
   165 // Place-holder for non-existent suppression check:
   166 #define assert_is_suppressed(file_name, line_no) (false)
   168 #endif //PRODUCT
   170 void report_assertion_failure(const char* file_name, int line_no, const char* message) {
   171   if (Debugging || assert_is_suppressed(file_name, line_no))  return;
   172   VMError err(ThreadLocalStorage::get_thread_slow(), message, file_name, line_no);
   173   err.report_and_die();
   174 }
   176 void report_fatal(const char* file_name, int line_no, const char* message) {
   177   if (Debugging || assert_is_suppressed(file_name, line_no))  return;
   178   VMError err(ThreadLocalStorage::get_thread_slow(), message, file_name, line_no);
   179   err.report_and_die();
   180 }
   182 void report_fatal_vararg(const char* file_name, int line_no, const char* format, ...) {
   183   char buffer[256];
   184   va_list ap;
   185   va_start(ap, format);
   186   jio_vsnprintf(buffer, sizeof(buffer), format, ap);
   187   va_end(ap);
   188   report_fatal(file_name, line_no, buffer);
   189 }
   192 // Used by report_vm_out_of_memory to detect recursion.
   193 static jint _exiting_out_of_mem = 0;
   195 // Just passing the flow to VMError to handle error
   196 void report_vm_out_of_memory(const char* file_name, int line_no, size_t size, const char* message) {
   197   if (Debugging || assert_is_suppressed(file_name, line_no))  return;
   199   // We try to gather additional information for the first out of memory
   200   // error only; gathering additional data might cause an allocation and a
   201   // recursive out_of_memory condition.
   203   const jint exiting = 1;
   204   // If we succeed in changing the value, we're the first one in.
   205   bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting;
   207   if (first_time_here) {
   208     Thread* thread = ThreadLocalStorage::get_thread_slow();
   209     VMError(thread, size, message, file_name, line_no).report_and_die();
   210   }
   211   vm_abort();
   212 }
   214 void report_vm_out_of_memory_vararg(const char* file_name, int line_no, size_t size, const char* format, ...) {
   215   char buffer[256];
   216   va_list ap;
   217   va_start(ap, format);
   218   jio_vsnprintf(buffer, sizeof(buffer), format, ap);
   219   va_end(ap);
   220   report_vm_out_of_memory(file_name, line_no, size, buffer);
   221 }
   223 void report_should_not_call(const char* file_name, int line_no) {
   224   if (Debugging || assert_is_suppressed(file_name, line_no))  return;
   225   VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotCall()", file_name, line_no);
   226   err.report_and_die();
   227 }
   230 void report_should_not_reach_here(const char* file_name, int line_no) {
   231   if (Debugging || assert_is_suppressed(file_name, line_no))  return;
   232   VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotReachHere()", file_name, line_no);
   233   err.report_and_die();
   234 }
   237 void report_unimplemented(const char* file_name, int line_no) {
   238   if (Debugging || assert_is_suppressed(file_name, line_no))  return;
   239   VMError err(ThreadLocalStorage::get_thread_slow(), "Unimplemented()", file_name, line_no);
   240   err.report_and_die();
   241 }
   244 void report_untested(const char* file_name, int line_no, const char* msg) {
   245 #ifndef PRODUCT
   246   warning("Untested: %s in %s: %d\n", msg, file_name, line_no);
   247 #endif // PRODUCT
   248 }
   250 void report_java_out_of_memory(const char* message) {
   251   static jint out_of_memory_reported = 0;
   253   // A number of threads may attempt to report OutOfMemoryError at around the
   254   // same time. To avoid dumping the heap or executing the data collection
   255   // commands multiple times we just do it once when the first threads reports
   256   // the error.
   257   if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
   258     // create heap dump before OnOutOfMemoryError commands are executed
   259     if (HeapDumpOnOutOfMemoryError) {
   260       tty->print_cr("java.lang.OutOfMemoryError: %s", message);
   261       HeapDumper::dump_heap();
   262     }
   264     if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
   265       VMError err(message);
   266       err.report_java_out_of_memory();
   267     }
   268   }
   269 }
   272 extern "C" void ps();
   274 static bool error_reported = false;
   276 // call this when the VM is dying--it might loosen some asserts
   277 void set_error_reported() {
   278   error_reported = true;
   279 }
   281 bool is_error_reported() {
   282     return error_reported;
   283 }
   285 // ------ helper functions for debugging go here ------------
   287 #ifndef PRODUCT
   288 // All debug entries should be wrapped with a stack allocated
   289 // Command object. It makes sure a resource mark is set and
   290 // flushes the logfile to prevent file sharing problems.
   292 class Command : public StackObj {
   293  private:
   294   ResourceMark rm;
   295   ResetNoHandleMark rnhm;
   296   HandleMark   hm;
   297   bool debug_save;
   298  public:
   299   static int level;
   300   Command(const char* str) {
   301     debug_save = Debugging;
   302     Debugging = true;
   303     if (level++ > 0)  return;
   304     tty->cr();
   305     tty->print_cr("\"Executing %s\"", str);
   306   }
   308   ~Command() { tty->flush(); Debugging = debug_save; level--; }
   309 };
   311 int Command::level = 0;
   313 extern "C" void blob(CodeBlob* cb) {
   314   Command c("blob");
   315   cb->print();
   316 }
   319 extern "C" void dump_vtable(address p) {
   320   Command c("dump_vtable");
   321   klassOop k = (klassOop)p;
   322   instanceKlass::cast(k)->vtable()->print();
   323 }
   326 extern "C" void nm(intptr_t p) {
   327   // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
   328   Command c("nm");
   329   CodeBlob* cb = CodeCache::find_blob((address)p);
   330   if (cb == NULL) {
   331     tty->print_cr("NULL");
   332   } else {
   333     cb->print();
   334   }
   335 }
   338 extern "C" void disnm(intptr_t p) {
   339   Command c("disnm");
   340   CodeBlob* cb = CodeCache::find_blob((address) p);
   341   cb->print();
   342   Disassembler::decode(cb);
   343 }
   346 extern "C" void printnm(intptr_t p) {
   347   char buffer[256];
   348   sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
   349   Command c(buffer);
   350   CodeBlob* cb = CodeCache::find_blob((address) p);
   351   if (cb->is_nmethod()) {
   352     nmethod* nm = (nmethod*)cb;
   353     nm->print_nmethod(true);
   354   }
   355 }
   358 extern "C" void universe() {
   359   Command c("universe");
   360   Universe::print();
   361 }
   364 extern "C" void verify() {
   365   // try to run a verify on the entire system
   366   // note: this may not be safe if we're not at a safepoint; for debugging,
   367   // this manipulates the safepoint settings to avoid assertion failures
   368   Command c("universe verify");
   369   bool safe = SafepointSynchronize::is_at_safepoint();
   370   if (!safe) {
   371     tty->print_cr("warning: not at safepoint -- verify may fail");
   372     SafepointSynchronize::set_is_at_safepoint();
   373   }
   374   // Ensure Eden top is correct before verification
   375   Universe::heap()->prepare_for_verify();
   376   Universe::verify(true);
   377   if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
   378 }
   381 extern "C" void pp(void* p) {
   382   Command c("pp");
   383   FlagSetting fl(PrintVMMessages, true);
   384   if (Universe::heap()->is_in(p)) {
   385     oop obj = oop(p);
   386     obj->print();
   387   } else {
   388     tty->print("%#p", p);
   389   }
   390 }
   393 // pv: print vm-printable object
   394 extern "C" void pa(intptr_t p)   { ((AllocatedObj*) p)->print(); }
   395 extern "C" void findpc(intptr_t x);
   397 extern "C" void ps() { // print stack
   398   Command c("ps");
   401   // Prints the stack of the current Java thread
   402   JavaThread* p = JavaThread::active();
   403   tty->print(" for thread: ");
   404   p->print();
   405   tty->cr();
   407   if (p->has_last_Java_frame()) {
   408     // If the last_Java_fp is set we are in C land and
   409     // can call the standard stack_trace function.
   410     p->trace_stack();
   411   } else {
   412     frame f = os::current_frame();
   413     RegisterMap reg_map(p);
   414     f = f.sender(&reg_map);
   415     tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
   416     p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
   417   pd_ps(f);
   418   }
   420 }
   423 extern "C" void psf() { // print stack frames
   424   {
   425     Command c("psf");
   426     JavaThread* p = JavaThread::active();
   427     tty->print(" for thread: ");
   428     p->print();
   429     tty->cr();
   430     if (p->has_last_Java_frame()) {
   431       p->trace_frames();
   432     }
   433   }
   434 }
   437 extern "C" void threads() {
   438   Command c("threads");
   439   Threads::print(false, true);
   440 }
   443 extern "C" void psd() {
   444   Command c("psd");
   445   SystemDictionary::print();
   446 }
   449 extern "C" void safepoints() {
   450   Command c("safepoints");
   451   SafepointSynchronize::print_state();
   452 }
   455 extern "C" void pss() { // print all stacks
   456   Command c("pss");
   457   Threads::print(true, true);
   458 }
   461 extern "C" void debug() {               // to set things up for compiler debugging
   462   Command c("debug");
   463   WizardMode = true;
   464   PrintVMMessages = PrintCompilation = true;
   465   PrintInlining = PrintAssembly = true;
   466   tty->flush();
   467 }
   470 extern "C" void ndebug() {              // undo debug()
   471   Command c("ndebug");
   472   PrintCompilation = false;
   473   PrintInlining = PrintAssembly = false;
   474   tty->flush();
   475 }
   478 extern "C" void flush()  {
   479   Command c("flush");
   480   tty->flush();
   481 }
   484 extern "C" void events() {
   485   Command c("events");
   486   Events::print_last(tty, 50);
   487 }
   490 extern "C" void nevents(int n) {
   491   Command c("events");
   492   Events::print_last(tty, n);
   493 }
   496 // Given a heap address that was valid before the most recent GC, if
   497 // the oop that used to contain it is still live, prints the new
   498 // location of the oop and the address. Useful for tracking down
   499 // certain kinds of naked oop and oop map bugs.
   500 extern "C" void pnl(intptr_t old_heap_addr) {
   501   // Print New Location of old heap address
   502   Command c("pnl");
   503 #ifndef VALIDATE_MARK_SWEEP
   504   tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled");
   505 #else
   506   MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr);
   507 #endif
   508 }
   511 extern "C" methodOop findm(intptr_t pc) {
   512   Command c("findm");
   513   nmethod* nm = CodeCache::find_nmethod((address)pc);
   514   return (nm == NULL) ? (methodOop)NULL : nm->method();
   515 }
   518 extern "C" nmethod* findnm(intptr_t addr) {
   519   Command c("findnm");
   520   return  CodeCache::find_nmethod((address)addr);
   521 }
   523 static address same_page(address x, address y) {
   524   intptr_t page_bits = -os::vm_page_size();
   525   if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) {
   526     return x;
   527   } else if (x > y) {
   528     return (address)(intptr_t(y) | ~page_bits) + 1;
   529   } else {
   530     return (address)(intptr_t(y) & page_bits);
   531   }
   532 }
   535 static void find(intptr_t x, bool print_pc) {
   536   address addr = (address)x;
   538   CodeBlob* b = CodeCache::find_blob_unsafe(addr);
   539   if (b != NULL) {
   540     if (b->is_buffer_blob()) {
   541       // the interpreter is generated into a buffer blob
   542       InterpreterCodelet* i = Interpreter::codelet_containing(addr);
   543       if (i != NULL) {
   544         i->print();
   545         return;
   546       }
   547       if (Interpreter::contains(addr)) {
   548         tty->print_cr(INTPTR_FORMAT " is pointing into interpreter code (not bytecode specific)", addr);
   549         return;
   550       }
   551       //
   552       if (AdapterHandlerLibrary::contains(b)) {
   553         AdapterHandlerLibrary::print_handler(b);
   554       }
   555       // the stubroutines are generated into a buffer blob
   556       StubCodeDesc* d = StubCodeDesc::desc_for(addr);
   557       if (d != NULL) {
   558         d->print();
   559         if (print_pc) tty->cr();
   560         return;
   561       }
   562       if (StubRoutines::contains(addr)) {
   563         tty->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) stub routine", addr);
   564         return;
   565       }
   566       // the InlineCacheBuffer is using stubs generated into a buffer blob
   567       if (InlineCacheBuffer::contains(addr)) {
   568         tty->print_cr(INTPTR_FORMAT "is pointing into InlineCacheBuffer", addr);
   569         return;
   570       }
   571       VtableStub* v = VtableStubs::stub_containing(addr);
   572       if (v != NULL) {
   573         v->print();
   574         return;
   575       }
   576     }
   577     if (print_pc && b->is_nmethod()) {
   578       ResourceMark rm;
   579       tty->print("%#p: Compiled ", addr);
   580       ((nmethod*)b)->method()->print_value_on(tty);
   581       tty->print("  = (CodeBlob*)" INTPTR_FORMAT, b);
   582       tty->cr();
   583       return;
   584     }
   585     if ( b->is_nmethod()) {
   586       if (b->is_zombie()) {
   587         tty->print_cr(INTPTR_FORMAT " is zombie nmethod", b);
   588       } else if (b->is_not_entrant()) {
   589         tty->print_cr(INTPTR_FORMAT " is non-entrant nmethod", b);
   590       }
   591     }
   592     b->print();
   593     return;
   594   }
   596   if (Universe::heap()->is_in_reserved(addr)) {
   597     HeapWord* p = Universe::heap()->block_start(addr);
   598     bool print = false;
   599     // If we couldn't find it it just may mean that heap wasn't parseable
   600     // See if we were just given an oop directly
   601     if (p != NULL && Universe::heap()->block_is_obj(p)) {
   602       print = true;
   603     } else if (p == NULL && ((oopDesc*)addr)->is_oop()) {
   604       p = (HeapWord*) addr;
   605       print = true;
   606     }
   607     if (print) {
   608       oop(p)->print();
   609       if (p != (HeapWord*)x && oop(p)->is_constMethod() &&
   610           constMethodOop(p)->contains(addr)) {
   611         Thread *thread = Thread::current();
   612         HandleMark hm(thread);
   613         methodHandle mh (thread, constMethodOop(p)->method());
   614         if (!mh->is_native()) {
   615           tty->print_cr("bci_from(%p) = %d; print_codes():",
   616                         addr, mh->bci_from(address(x)));
   617           mh->print_codes();
   618         }
   619       }
   620       return;
   621     }
   622   }
   623   if (JNIHandles::is_global_handle((jobject) addr)) {
   624     tty->print_cr(INTPTR_FORMAT "is a global jni handle", addr);
   625     return;
   626   }
   627   if (JNIHandles::is_weak_global_handle((jobject) addr)) {
   628     tty->print_cr(INTPTR_FORMAT "is a weak global jni handle", addr);
   629     return;
   630   }
   631   if (JNIHandleBlock::any_contains((jobject) addr)) {
   632     tty->print_cr(INTPTR_FORMAT "is a local jni handle", addr);
   633     return;
   634   }
   636   for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
   637     // Check for priviledge stack
   638     if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) {
   639       tty->print_cr(INTPTR_FORMAT "is pointing into the priviledge stack for thread: " INTPTR_FORMAT, addr, thread);
   640       return;
   641     }
   642     // If the addr is a java thread print information about that.
   643     if (addr == (address)thread) {
   644        thread->print();
   645        return;
   646     }
   647   }
   649   // Try an OS specific find
   650   if (os::find(addr)) {
   651     return;
   652   }
   654   if (print_pc) {
   655     tty->print_cr(INTPTR_FORMAT ": probably in C++ code; check debugger", addr);
   656     Disassembler::decode(same_page(addr-40,addr),same_page(addr+40,addr));
   657     return;
   658   }
   660   tty->print_cr(INTPTR_FORMAT "is pointing to unknown location", addr);
   661 }
   664 class LookForRefInGenClosure : public OopsInGenClosure {
   665 public:
   666   oop target;
   667   void do_oop(oop* o) {
   668     if (o != NULL && *o == target) {
   669       tty->print_cr("0x%08x", o);
   670     }
   671   }
   672 };
   675 class LookForRefInObjectClosure : public ObjectClosure {
   676 private:
   677   LookForRefInGenClosure look_in_object;
   678 public:
   679   LookForRefInObjectClosure(oop target) { look_in_object.target = target; }
   680   void do_object(oop obj) {
   681     obj->oop_iterate(&look_in_object);
   682   }
   683 };
   686 static void findref(intptr_t x) {
   687   GenCollectedHeap *gch = GenCollectedHeap::heap();
   688   LookForRefInGenClosure lookFor;
   689   lookFor.target = (oop) x;
   690   LookForRefInObjectClosure look_in_object((oop) x);
   692   tty->print_cr("Searching heap:");
   693   gch->object_iterate(&look_in_object);
   695   tty->print_cr("Searching strong roots:");
   696   Universe::oops_do(&lookFor, false);
   697   JNIHandles::oops_do(&lookFor);   // Global (strong) JNI handles
   698   Threads::oops_do(&lookFor);
   699   ObjectSynchronizer::oops_do(&lookFor);
   700   //FlatProfiler::oops_do(&lookFor);
   701   SystemDictionary::oops_do(&lookFor);
   703   tty->print_cr("Done.");
   704 }
   706 class FindClassObjectClosure: public ObjectClosure {
   707   private:
   708     const char* _target;
   709   public:
   710     FindClassObjectClosure(const char name[])  { _target = name; }
   712     virtual void do_object(oop obj) {
   713       if (obj->is_klass()) {
   714         Klass* k = klassOop(obj)->klass_part();
   715         if (k->name() != NULL) {
   716           ResourceMark rm;
   717           const char* ext = k->external_name();
   718           if ( strcmp(_target, ext) == 0 ) {
   719             tty->print_cr("Found " INTPTR_FORMAT, obj);
   720             obj->print();
   721           }
   722         }
   723       }
   724     }
   725 };
   727 //
   728 extern "C" void findclass(const char name[]) {
   729   Command c("findclass");
   730   if (name != NULL) {
   731     tty->print_cr("Finding class %s -> ", name);
   732     FindClassObjectClosure srch(name);
   733     Universe::heap()->permanent_object_iterate(&srch);
   734   }
   735 }
   737 // Another interface that isn't ambiguous in dbx.
   738 // Can we someday rename the other find to hsfind?
   739 extern "C" void hsfind(intptr_t x) {
   740   Command c("hsfind");
   741   find(x, false);
   742 }
   745 extern "C" void hsfindref(intptr_t x) {
   746   Command c("hsfindref");
   747   findref(x);
   748 }
   750 extern "C" void find(intptr_t x) {
   751   Command c("find");
   752   find(x, false);
   753 }
   756 extern "C" void findpc(intptr_t x) {
   757   Command c("findpc");
   758   find(x, true);
   759 }
   762 // int versions of all methods to avoid having to type type casts in the debugger
   764 void pp(intptr_t p)          { pp((void*)p); }
   765 void pp(oop p)               { pp((void*)p); }
   767 void help() {
   768   Command c("help");
   769   tty->print_cr("basic");
   770   tty->print_cr("  pp(void* p)   - try to make sense of p");
   771   tty->print_cr("  pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
   772   tty->print_cr("  ps()          - print current thread stack");
   773   tty->print_cr("  pss()         - print all thread stacks");
   774   tty->print_cr("  pm(int pc)    - print methodOop given compiled PC");
   775   tty->print_cr("  findm(intptr_t pc) - finds methodOop");
   776   tty->print_cr("  find(intptr_t x)   - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
   778   tty->print_cr("misc.");
   779   tty->print_cr("  flush()       - flushes the log file");
   780   tty->print_cr("  events()      - dump last 50 events");
   783   tty->print_cr("compiler debugging");
   784   tty->print_cr("  debug()       - to set things up for compiler debugging");
   785   tty->print_cr("  ndebug()      - undo debug");
   786 }
   788 #if 0
   790 // BobV's command parser for debugging on windows when nothing else works.
   792 enum CommandID {
   793   CMDID_HELP,
   794   CMDID_QUIT,
   795   CMDID_HSFIND,
   796   CMDID_PSS,
   797   CMDID_PS,
   798   CMDID_PSF,
   799   CMDID_FINDM,
   800   CMDID_FINDNM,
   801   CMDID_PP,
   802   CMDID_BPT,
   803   CMDID_EXIT,
   804   CMDID_VERIFY,
   805   CMDID_THREADS,
   806   CMDID_ILLEGAL = 99
   807 };
   809 struct CommandParser {
   810    char *name;
   811    CommandID code;
   812    char *description;
   813 };
   815 struct CommandParser CommandList[] = {
   816   (char *)"help", CMDID_HELP, "  Dump this list",
   817   (char *)"quit", CMDID_QUIT, "  Return from this routine",
   818   (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address",
   819   (char *)"ps", CMDID_PS, "    Print Current Thread Stack Trace",
   820   (char *)"pss", CMDID_PSS, "   Print All Thread Stack Trace",
   821   (char *)"psf", CMDID_PSF, "   Print All Stack Frames",
   822   (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC",
   823   (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC",
   824   (char *)"pp", CMDID_PP, "    Find out something about a pointer",
   825   (char *)"break", CMDID_BPT, " Execute a breakpoint",
   826   (char *)"exitvm", CMDID_EXIT, "Exit the VM",
   827   (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify",
   828   (char *)"thread", CMDID_THREADS, "Dump Info on all Threads",
   829   (char *)0, CMDID_ILLEGAL
   830 };
   833 // get_debug_command()
   834 //
   835 // Read a command from standard input.
   836 // This is useful when you have a debugger
   837 // which doesn't support calling into functions.
   838 //
   839 void get_debug_command()
   840 {
   841   ssize_t count;
   842   int i,j;
   843   bool gotcommand;
   844   intptr_t addr;
   845   char buffer[256];
   846   nmethod *nm;
   847   methodOop m;
   849   tty->print_cr("You have entered the diagnostic command interpreter");
   850   tty->print("The supported commands are:\n");
   851   for ( i=0; ; i++ ) {
   852     if ( CommandList[i].code == CMDID_ILLEGAL )
   853       break;
   854     tty->print_cr("  %s \n", CommandList[i].name );
   855   }
   857   while ( 1 ) {
   858     gotcommand = false;
   859     tty->print("Please enter a command: ");
   860     count = scanf("%s", buffer) ;
   861     if ( count >=0 ) {
   862       for ( i=0; ; i++ ) {
   863         if ( CommandList[i].code == CMDID_ILLEGAL ) {
   864           if (!gotcommand) tty->print("Invalid command, please try again\n");
   865           break;
   866         }
   867         if ( strcmp(buffer, CommandList[i].name) == 0 ) {
   868           gotcommand = true;
   869           switch ( CommandList[i].code ) {
   870               case CMDID_PS:
   871                 ps();
   872                 break;
   873               case CMDID_PSS:
   874                 pss();
   875                 break;
   876               case CMDID_PSF:
   877                 psf();
   878                 break;
   879               case CMDID_FINDM:
   880                 tty->print("Please enter the hex addr to pass to findm: ");
   881                 scanf("%I64X", &addr);
   882                 m = (methodOop)findm(addr);
   883                 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m);
   884                 break;
   885               case CMDID_FINDNM:
   886                 tty->print("Please enter the hex addr to pass to findnm: ");
   887                 scanf("%I64X", &addr);
   888                 nm = (nmethod*)findnm(addr);
   889                 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm);
   890                 break;
   891               case CMDID_PP:
   892                 tty->print("Please enter the hex addr to pass to pp: ");
   893                 scanf("%I64X", &addr);
   894                 pp((void*)addr);
   895                 break;
   896               case CMDID_EXIT:
   897                 exit(0);
   898               case CMDID_HELP:
   899                 tty->print("Here are the supported commands: ");
   900                 for ( j=0; ; j++ ) {
   901                   if ( CommandList[j].code == CMDID_ILLEGAL )
   902                     break;
   903                   tty->print_cr("  %s --  %s\n", CommandList[j].name,
   904                                                  CommandList[j].description );
   905                 }
   906                 break;
   907               case CMDID_QUIT:
   908                 return;
   909                 break;
   910               case CMDID_BPT:
   911                 BREAKPOINT;
   912                 break;
   913               case CMDID_VERIFY:
   914                 verify();;
   915                 break;
   916               case CMDID_THREADS:
   917                 threads();;
   918                 break;
   919               case CMDID_HSFIND:
   920                 tty->print("Please enter the hex addr to pass to hsfind: ");
   921                 scanf("%I64X", &addr);
   922                 tty->print("Calling hsfind(0x%I64X)\n", addr);
   923                 hsfind(addr);
   924                 break;
   925               default:
   926               case CMDID_ILLEGAL:
   927                 break;
   928           }
   929         }
   930       }
   931     }
   932   }
   933 }
   934 #endif
   936 #endif // PRODUCT

mercurial