src/share/vm/utilities/debug.cpp

Mon, 09 Mar 2009 13:28:46 -0700

author
xdono
date
Mon, 09 Mar 2009 13:28:46 -0700
changeset 1014
0fbdb4381b99
parent 867
275a3b7ff0d6
child 1424
148e5441d916
permissions
-rw-r--r--

6814575: Update copyright year
Summary: Update copyright for files that have been modified in 2009, up to 03/09
Reviewed-by: katleman, tbell, ohair

     1 /*
     2  * Copyright 1997-2008 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   }
   212   // Dump core and abort
   213   vm_abort(true);
   214 }
   216 void report_vm_out_of_memory_vararg(const char* file_name, int line_no, size_t size, const char* format, ...) {
   217   char buffer[256];
   218   va_list ap;
   219   va_start(ap, format);
   220   jio_vsnprintf(buffer, sizeof(buffer), format, ap);
   221   va_end(ap);
   222   report_vm_out_of_memory(file_name, line_no, size, buffer);
   223 }
   225 void report_should_not_call(const char* file_name, int line_no) {
   226   if (Debugging || assert_is_suppressed(file_name, line_no))  return;
   227   VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotCall()", file_name, line_no);
   228   err.report_and_die();
   229 }
   232 void report_should_not_reach_here(const char* file_name, int line_no) {
   233   if (Debugging || assert_is_suppressed(file_name, line_no))  return;
   234   VMError err(ThreadLocalStorage::get_thread_slow(), "ShouldNotReachHere()", file_name, line_no);
   235   err.report_and_die();
   236 }
   239 void report_unimplemented(const char* file_name, int line_no) {
   240   if (Debugging || assert_is_suppressed(file_name, line_no))  return;
   241   VMError err(ThreadLocalStorage::get_thread_slow(), "Unimplemented()", file_name, line_no);
   242   err.report_and_die();
   243 }
   246 void report_untested(const char* file_name, int line_no, const char* msg) {
   247 #ifndef PRODUCT
   248   warning("Untested: %s in %s: %d\n", msg, file_name, line_no);
   249 #endif // PRODUCT
   250 }
   252 void report_java_out_of_memory(const char* message) {
   253   static jint out_of_memory_reported = 0;
   255   // A number of threads may attempt to report OutOfMemoryError at around the
   256   // same time. To avoid dumping the heap or executing the data collection
   257   // commands multiple times we just do it once when the first threads reports
   258   // the error.
   259   if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
   260     // create heap dump before OnOutOfMemoryError commands are executed
   261     if (HeapDumpOnOutOfMemoryError) {
   262       tty->print_cr("java.lang.OutOfMemoryError: %s", message);
   263       HeapDumper::dump_heap();
   264     }
   266     if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
   267       VMError err(message);
   268       err.report_java_out_of_memory();
   269     }
   270   }
   271 }
   274 extern "C" void ps();
   276 static bool error_reported = false;
   278 // call this when the VM is dying--it might loosen some asserts
   279 void set_error_reported() {
   280   error_reported = true;
   281 }
   283 bool is_error_reported() {
   284     return error_reported;
   285 }
   287 // ------ helper functions for debugging go here ------------
   289 #ifndef PRODUCT
   290 // All debug entries should be wrapped with a stack allocated
   291 // Command object. It makes sure a resource mark is set and
   292 // flushes the logfile to prevent file sharing problems.
   294 class Command : public StackObj {
   295  private:
   296   ResourceMark rm;
   297   ResetNoHandleMark rnhm;
   298   HandleMark   hm;
   299   bool debug_save;
   300  public:
   301   static int level;
   302   Command(const char* str) {
   303     debug_save = Debugging;
   304     Debugging = true;
   305     if (level++ > 0)  return;
   306     tty->cr();
   307     tty->print_cr("\"Executing %s\"", str);
   308   }
   310   ~Command() { tty->flush(); Debugging = debug_save; level--; }
   311 };
   313 int Command::level = 0;
   315 extern "C" void blob(CodeBlob* cb) {
   316   Command c("blob");
   317   cb->print();
   318 }
   321 extern "C" void dump_vtable(address p) {
   322   Command c("dump_vtable");
   323   klassOop k = (klassOop)p;
   324   instanceKlass::cast(k)->vtable()->print();
   325 }
   328 extern "C" void nm(intptr_t p) {
   329   // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
   330   Command c("nm");
   331   CodeBlob* cb = CodeCache::find_blob((address)p);
   332   if (cb == NULL) {
   333     tty->print_cr("NULL");
   334   } else {
   335     cb->print();
   336   }
   337 }
   340 extern "C" void disnm(intptr_t p) {
   341   Command c("disnm");
   342   CodeBlob* cb = CodeCache::find_blob((address) p);
   343   cb->print();
   344   Disassembler::decode(cb);
   345 }
   348 extern "C" void printnm(intptr_t p) {
   349   char buffer[256];
   350   sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
   351   Command c(buffer);
   352   CodeBlob* cb = CodeCache::find_blob((address) p);
   353   if (cb->is_nmethod()) {
   354     nmethod* nm = (nmethod*)cb;
   355     nm->print_nmethod(true);
   356   }
   357 }
   360 extern "C" void universe() {
   361   Command c("universe");
   362   Universe::print();
   363 }
   366 extern "C" void verify() {
   367   // try to run a verify on the entire system
   368   // note: this may not be safe if we're not at a safepoint; for debugging,
   369   // this manipulates the safepoint settings to avoid assertion failures
   370   Command c("universe verify");
   371   bool safe = SafepointSynchronize::is_at_safepoint();
   372   if (!safe) {
   373     tty->print_cr("warning: not at safepoint -- verify may fail");
   374     SafepointSynchronize::set_is_at_safepoint();
   375   }
   376   // Ensure Eden top is correct before verification
   377   Universe::heap()->prepare_for_verify();
   378   Universe::verify(true);
   379   if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
   380 }
   383 extern "C" void pp(void* p) {
   384   Command c("pp");
   385   FlagSetting fl(PrintVMMessages, true);
   386   if (Universe::heap()->is_in(p)) {
   387     oop obj = oop(p);
   388     obj->print();
   389   } else {
   390     tty->print("%#p", p);
   391   }
   392 }
   395 // pv: print vm-printable object
   396 extern "C" void pa(intptr_t p)   { ((AllocatedObj*) p)->print(); }
   397 extern "C" void findpc(intptr_t x);
   399 extern "C" void ps() { // print stack
   400   Command c("ps");
   403   // Prints the stack of the current Java thread
   404   JavaThread* p = JavaThread::active();
   405   tty->print(" for thread: ");
   406   p->print();
   407   tty->cr();
   409   if (p->has_last_Java_frame()) {
   410     // If the last_Java_fp is set we are in C land and
   411     // can call the standard stack_trace function.
   412     p->trace_stack();
   413   } else {
   414     frame f = os::current_frame();
   415     RegisterMap reg_map(p);
   416     f = f.sender(&reg_map);
   417     tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
   418     p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
   419   pd_ps(f);
   420   }
   422 }
   425 extern "C" void psf() { // print stack frames
   426   {
   427     Command c("psf");
   428     JavaThread* p = JavaThread::active();
   429     tty->print(" for thread: ");
   430     p->print();
   431     tty->cr();
   432     if (p->has_last_Java_frame()) {
   433       p->trace_frames();
   434     }
   435   }
   436 }
   439 extern "C" void threads() {
   440   Command c("threads");
   441   Threads::print(false, true);
   442 }
   445 extern "C" void psd() {
   446   Command c("psd");
   447   SystemDictionary::print();
   448 }
   451 extern "C" void safepoints() {
   452   Command c("safepoints");
   453   SafepointSynchronize::print_state();
   454 }
   457 extern "C" void pss() { // print all stacks
   458   Command c("pss");
   459   Threads::print(true, true);
   460 }
   463 extern "C" void debug() {               // to set things up for compiler debugging
   464   Command c("debug");
   465   WizardMode = true;
   466   PrintVMMessages = PrintCompilation = true;
   467   PrintInlining = PrintAssembly = true;
   468   tty->flush();
   469 }
   472 extern "C" void ndebug() {              // undo debug()
   473   Command c("ndebug");
   474   PrintCompilation = false;
   475   PrintInlining = PrintAssembly = false;
   476   tty->flush();
   477 }
   480 extern "C" void flush()  {
   481   Command c("flush");
   482   tty->flush();
   483 }
   486 extern "C" void events() {
   487   Command c("events");
   488   Events::print_last(tty, 50);
   489 }
   492 extern "C" void nevents(int n) {
   493   Command c("events");
   494   Events::print_last(tty, n);
   495 }
   498 // Given a heap address that was valid before the most recent GC, if
   499 // the oop that used to contain it is still live, prints the new
   500 // location of the oop and the address. Useful for tracking down
   501 // certain kinds of naked oop and oop map bugs.
   502 extern "C" void pnl(intptr_t old_heap_addr) {
   503   // Print New Location of old heap address
   504   Command c("pnl");
   505 #ifndef VALIDATE_MARK_SWEEP
   506   tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled");
   507 #else
   508   MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr);
   509 #endif
   510 }
   513 extern "C" methodOop findm(intptr_t pc) {
   514   Command c("findm");
   515   nmethod* nm = CodeCache::find_nmethod((address)pc);
   516   return (nm == NULL) ? (methodOop)NULL : nm->method();
   517 }
   520 extern "C" nmethod* findnm(intptr_t addr) {
   521   Command c("findnm");
   522   return  CodeCache::find_nmethod((address)addr);
   523 }
   525 static address same_page(address x, address y) {
   526   intptr_t page_bits = -os::vm_page_size();
   527   if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) {
   528     return x;
   529   } else if (x > y) {
   530     return (address)(intptr_t(y) | ~page_bits) + 1;
   531   } else {
   532     return (address)(intptr_t(y) & page_bits);
   533   }
   534 }
   537 static void find(intptr_t x, bool print_pc) {
   538   address addr = (address)x;
   540   CodeBlob* b = CodeCache::find_blob_unsafe(addr);
   541   if (b != NULL) {
   542     if (b->is_buffer_blob()) {
   543       // the interpreter is generated into a buffer blob
   544       InterpreterCodelet* i = Interpreter::codelet_containing(addr);
   545       if (i != NULL) {
   546         i->print();
   547         return;
   548       }
   549       if (Interpreter::contains(addr)) {
   550         tty->print_cr(INTPTR_FORMAT " is pointing into interpreter code (not bytecode specific)", addr);
   551         return;
   552       }
   553       //
   554       if (AdapterHandlerLibrary::contains(b)) {
   555         AdapterHandlerLibrary::print_handler(b);
   556       }
   557       // the stubroutines are generated into a buffer blob
   558       StubCodeDesc* d = StubCodeDesc::desc_for(addr);
   559       if (d != NULL) {
   560         d->print();
   561         if (print_pc) tty->cr();
   562         return;
   563       }
   564       if (StubRoutines::contains(addr)) {
   565         tty->print_cr(INTPTR_FORMAT " is pointing to an (unnamed) stub routine", addr);
   566         return;
   567       }
   568       // the InlineCacheBuffer is using stubs generated into a buffer blob
   569       if (InlineCacheBuffer::contains(addr)) {
   570         tty->print_cr(INTPTR_FORMAT " is pointing into InlineCacheBuffer", addr);
   571         return;
   572       }
   573       VtableStub* v = VtableStubs::stub_containing(addr);
   574       if (v != NULL) {
   575         v->print();
   576         return;
   577       }
   578     }
   579     if (print_pc && b->is_nmethod()) {
   580       ResourceMark rm;
   581       tty->print("%#p: Compiled ", addr);
   582       ((nmethod*)b)->method()->print_value_on(tty);
   583       tty->print("  = (CodeBlob*)" INTPTR_FORMAT, b);
   584       tty->cr();
   585       return;
   586     }
   587     if ( b->is_nmethod()) {
   588       if (b->is_zombie()) {
   589         tty->print_cr(INTPTR_FORMAT " is zombie nmethod", b);
   590       } else if (b->is_not_entrant()) {
   591         tty->print_cr(INTPTR_FORMAT " is non-entrant nmethod", b);
   592       }
   593     }
   594     b->print();
   595     return;
   596   }
   598   if (Universe::heap()->is_in(addr)) {
   599     HeapWord* p = Universe::heap()->block_start(addr);
   600     bool print = false;
   601     // If we couldn't find it it just may mean that heap wasn't parseable
   602     // See if we were just given an oop directly
   603     if (p != NULL && Universe::heap()->block_is_obj(p)) {
   604       print = true;
   605     } else if (p == NULL && ((oopDesc*)addr)->is_oop()) {
   606       p = (HeapWord*) addr;
   607       print = true;
   608     }
   609     if (print) {
   610       oop(p)->print();
   611       if (p != (HeapWord*)x && oop(p)->is_constMethod() &&
   612           constMethodOop(p)->contains(addr)) {
   613         Thread *thread = Thread::current();
   614         HandleMark hm(thread);
   615         methodHandle mh (thread, constMethodOop(p)->method());
   616         if (!mh->is_native()) {
   617           tty->print_cr("bci_from(%p) = %d; print_codes():",
   618                         addr, mh->bci_from(address(x)));
   619           mh->print_codes();
   620         }
   621       }
   622       return;
   623     }
   624   } else if (Universe::heap()->is_in_reserved(addr)) {
   625     tty->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", addr);
   626     return;
   627   }
   629   if (JNIHandles::is_global_handle((jobject) addr)) {
   630     tty->print_cr(INTPTR_FORMAT " is a global jni handle", addr);
   631     return;
   632   }
   633   if (JNIHandles::is_weak_global_handle((jobject) addr)) {
   634     tty->print_cr(INTPTR_FORMAT " is a weak global jni handle", addr);
   635     return;
   636   }
   637   if (JNIHandleBlock::any_contains((jobject) addr)) {
   638     tty->print_cr(INTPTR_FORMAT " is a local jni handle", addr);
   639     return;
   640   }
   642   for(JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
   643     // Check for privilege stack
   644     if (thread->privileged_stack_top() != NULL && thread->privileged_stack_top()->contains(addr)) {
   645       tty->print_cr(INTPTR_FORMAT " is pointing into the privilege stack for thread: " INTPTR_FORMAT, addr, thread);
   646       return;
   647     }
   648     // If the addr is a java thread print information about that.
   649     if (addr == (address)thread) {
   650        thread->print();
   651        return;
   652     }
   653   }
   655   // Try an OS specific find
   656   if (os::find(addr)) {
   657     return;
   658   }
   660   if (print_pc) {
   661     tty->print_cr(INTPTR_FORMAT ": probably in C++ code; check debugger", addr);
   662     Disassembler::decode(same_page(addr-40,addr),same_page(addr+40,addr));
   663     return;
   664   }
   666   tty->print_cr(INTPTR_FORMAT " is pointing to unknown location", addr);
   667 }
   670 class LookForRefInGenClosure : public OopsInGenClosure {
   671 public:
   672   oop target;
   673   void do_oop(oop* o) {
   674     if (o != NULL && *o == target) {
   675       tty->print_cr(INTPTR_FORMAT, o);
   676     }
   677   }
   678   void do_oop(narrowOop* o) { ShouldNotReachHere(); }
   679 };
   682 class LookForRefInObjectClosure : public ObjectClosure {
   683 private:
   684   LookForRefInGenClosure look_in_object;
   685 public:
   686   LookForRefInObjectClosure(oop target) { look_in_object.target = target; }
   687   void do_object(oop obj) {
   688     obj->oop_iterate(&look_in_object);
   689   }
   690 };
   693 static void findref(intptr_t x) {
   694   CollectedHeap *ch = Universe::heap();
   695   LookForRefInGenClosure lookFor;
   696   lookFor.target = (oop) x;
   697   LookForRefInObjectClosure look_in_object((oop) x);
   699   tty->print_cr("Searching heap:");
   700   ch->object_iterate(&look_in_object);
   702   tty->print_cr("Searching strong roots:");
   703   Universe::oops_do(&lookFor, false);
   704   JNIHandles::oops_do(&lookFor);   // Global (strong) JNI handles
   705   Threads::oops_do(&lookFor);
   706   ObjectSynchronizer::oops_do(&lookFor);
   707   //FlatProfiler::oops_do(&lookFor);
   708   SystemDictionary::oops_do(&lookFor);
   710   tty->print_cr("Done.");
   711 }
   713 class FindClassObjectClosure: public ObjectClosure {
   714   private:
   715     const char* _target;
   716   public:
   717     FindClassObjectClosure(const char name[])  { _target = name; }
   719     virtual void do_object(oop obj) {
   720       if (obj->is_klass()) {
   721         Klass* k = klassOop(obj)->klass_part();
   722         if (k->name() != NULL) {
   723           ResourceMark rm;
   724           const char* ext = k->external_name();
   725           if ( strcmp(_target, ext) == 0 ) {
   726             tty->print_cr("Found " INTPTR_FORMAT, obj);
   727             obj->print();
   728           }
   729         }
   730       }
   731     }
   732 };
   734 //
   735 extern "C" void findclass(const char name[]) {
   736   Command c("findclass");
   737   if (name != NULL) {
   738     tty->print_cr("Finding class %s -> ", name);
   739     FindClassObjectClosure srch(name);
   740     Universe::heap()->permanent_object_iterate(&srch);
   741   }
   742 }
   744 // Another interface that isn't ambiguous in dbx.
   745 // Can we someday rename the other find to hsfind?
   746 extern "C" void hsfind(intptr_t x) {
   747   Command c("hsfind");
   748   find(x, false);
   749 }
   752 extern "C" void hsfindref(intptr_t x) {
   753   Command c("hsfindref");
   754   findref(x);
   755 }
   757 extern "C" void find(intptr_t x) {
   758   Command c("find");
   759   find(x, false);
   760 }
   763 extern "C" void findpc(intptr_t x) {
   764   Command c("findpc");
   765   find(x, true);
   766 }
   769 // int versions of all methods to avoid having to type type casts in the debugger
   771 void pp(intptr_t p)          { pp((void*)p); }
   772 void pp(oop p)               { pp((void*)p); }
   774 void help() {
   775   Command c("help");
   776   tty->print_cr("basic");
   777   tty->print_cr("  pp(void* p)   - try to make sense of p");
   778   tty->print_cr("  pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
   779   tty->print_cr("  ps()          - print current thread stack");
   780   tty->print_cr("  pss()         - print all thread stacks");
   781   tty->print_cr("  pm(int pc)    - print methodOop given compiled PC");
   782   tty->print_cr("  findm(intptr_t pc) - finds methodOop");
   783   tty->print_cr("  find(intptr_t x)   - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
   785   tty->print_cr("misc.");
   786   tty->print_cr("  flush()       - flushes the log file");
   787   tty->print_cr("  events()      - dump last 50 events");
   790   tty->print_cr("compiler debugging");
   791   tty->print_cr("  debug()       - to set things up for compiler debugging");
   792   tty->print_cr("  ndebug()      - undo debug");
   793 }
   795 #if 0
   797 // BobV's command parser for debugging on windows when nothing else works.
   799 enum CommandID {
   800   CMDID_HELP,
   801   CMDID_QUIT,
   802   CMDID_HSFIND,
   803   CMDID_PSS,
   804   CMDID_PS,
   805   CMDID_PSF,
   806   CMDID_FINDM,
   807   CMDID_FINDNM,
   808   CMDID_PP,
   809   CMDID_BPT,
   810   CMDID_EXIT,
   811   CMDID_VERIFY,
   812   CMDID_THREADS,
   813   CMDID_ILLEGAL = 99
   814 };
   816 struct CommandParser {
   817    char *name;
   818    CommandID code;
   819    char *description;
   820 };
   822 struct CommandParser CommandList[] = {
   823   (char *)"help", CMDID_HELP, "  Dump this list",
   824   (char *)"quit", CMDID_QUIT, "  Return from this routine",
   825   (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address",
   826   (char *)"ps", CMDID_PS, "    Print Current Thread Stack Trace",
   827   (char *)"pss", CMDID_PSS, "   Print All Thread Stack Trace",
   828   (char *)"psf", CMDID_PSF, "   Print All Stack Frames",
   829   (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC",
   830   (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC",
   831   (char *)"pp", CMDID_PP, "    Find out something about a pointer",
   832   (char *)"break", CMDID_BPT, " Execute a breakpoint",
   833   (char *)"exitvm", CMDID_EXIT, "Exit the VM",
   834   (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify",
   835   (char *)"thread", CMDID_THREADS, "Dump Info on all Threads",
   836   (char *)0, CMDID_ILLEGAL
   837 };
   840 // get_debug_command()
   841 //
   842 // Read a command from standard input.
   843 // This is useful when you have a debugger
   844 // which doesn't support calling into functions.
   845 //
   846 void get_debug_command()
   847 {
   848   ssize_t count;
   849   int i,j;
   850   bool gotcommand;
   851   intptr_t addr;
   852   char buffer[256];
   853   nmethod *nm;
   854   methodOop m;
   856   tty->print_cr("You have entered the diagnostic command interpreter");
   857   tty->print("The supported commands are:\n");
   858   for ( i=0; ; i++ ) {
   859     if ( CommandList[i].code == CMDID_ILLEGAL )
   860       break;
   861     tty->print_cr("  %s \n", CommandList[i].name );
   862   }
   864   while ( 1 ) {
   865     gotcommand = false;
   866     tty->print("Please enter a command: ");
   867     count = scanf("%s", buffer) ;
   868     if ( count >=0 ) {
   869       for ( i=0; ; i++ ) {
   870         if ( CommandList[i].code == CMDID_ILLEGAL ) {
   871           if (!gotcommand) tty->print("Invalid command, please try again\n");
   872           break;
   873         }
   874         if ( strcmp(buffer, CommandList[i].name) == 0 ) {
   875           gotcommand = true;
   876           switch ( CommandList[i].code ) {
   877               case CMDID_PS:
   878                 ps();
   879                 break;
   880               case CMDID_PSS:
   881                 pss();
   882                 break;
   883               case CMDID_PSF:
   884                 psf();
   885                 break;
   886               case CMDID_FINDM:
   887                 tty->print("Please enter the hex addr to pass to findm: ");
   888                 scanf("%I64X", &addr);
   889                 m = (methodOop)findm(addr);
   890                 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m);
   891                 break;
   892               case CMDID_FINDNM:
   893                 tty->print("Please enter the hex addr to pass to findnm: ");
   894                 scanf("%I64X", &addr);
   895                 nm = (nmethod*)findnm(addr);
   896                 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm);
   897                 break;
   898               case CMDID_PP:
   899                 tty->print("Please enter the hex addr to pass to pp: ");
   900                 scanf("%I64X", &addr);
   901                 pp((void*)addr);
   902                 break;
   903               case CMDID_EXIT:
   904                 exit(0);
   905               case CMDID_HELP:
   906                 tty->print("Here are the supported commands: ");
   907                 for ( j=0; ; j++ ) {
   908                   if ( CommandList[j].code == CMDID_ILLEGAL )
   909                     break;
   910                   tty->print_cr("  %s --  %s\n", CommandList[j].name,
   911                                                  CommandList[j].description );
   912                 }
   913                 break;
   914               case CMDID_QUIT:
   915                 return;
   916                 break;
   917               case CMDID_BPT:
   918                 BREAKPOINT;
   919                 break;
   920               case CMDID_VERIFY:
   921                 verify();;
   922                 break;
   923               case CMDID_THREADS:
   924                 threads();;
   925                 break;
   926               case CMDID_HSFIND:
   927                 tty->print("Please enter the hex addr to pass to hsfind: ");
   928                 scanf("%I64X", &addr);
   929                 tty->print("Calling hsfind(0x%I64X)\n", addr);
   930                 hsfind(addr);
   931                 break;
   932               default:
   933               case CMDID_ILLEGAL:
   934                 break;
   935           }
   936         }
   937       }
   938     }
   939   }
   940 }
   941 #endif
   943 #endif // PRODUCT

mercurial