src/share/vm/utilities/debug.cpp

Thu, 13 Oct 2011 09:35:42 -0700

author
dcubed
date
Thu, 13 Oct 2011 09:35:42 -0700
changeset 3202
436b4a3231bf
parent 3156
f08d439fab8c
child 3499
aa3d708d67c4
permissions
-rw-r--r--

7098194: integrate macosx-port changes
Summary: Integrate bsd-port/hotspot and macosx-port/hotspot changes as of 2011.09.29.
Reviewed-by: kvn, dholmes, never, phh
Contributed-by: Christos Zoulas <christos@zoulas.com>, Greg Lewis <glewis@eyesbeyond.com>, Kurt Miller <kurt@intricatesoftware.com>, Alexander Strange <astrange@apple.com>, Mike Swingler <swingler@apple.com>, Roger Hoover <rhoover@apple.com>, Victor Hernandez <vhernandez@apple.com>, Pratik Solanki <psolanki@apple.com>

     1 /*
     2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "classfile/systemDictionary.hpp"
    27 #include "code/codeCache.hpp"
    28 #include "code/icBuffer.hpp"
    29 #include "code/nmethod.hpp"
    30 #include "code/vtableStubs.hpp"
    31 #include "compiler/compileBroker.hpp"
    32 #include "compiler/disassembler.hpp"
    33 #include "gc_implementation/shared/markSweep.hpp"
    34 #include "gc_interface/collectedHeap.hpp"
    35 #include "interpreter/bytecodeHistogram.hpp"
    36 #include "interpreter/interpreter.hpp"
    37 #include "memory/resourceArea.hpp"
    38 #include "memory/universe.hpp"
    39 #include "oops/oop.inline.hpp"
    40 #include "prims/privilegedStack.hpp"
    41 #include "runtime/arguments.hpp"
    42 #include "runtime/frame.hpp"
    43 #include "runtime/java.hpp"
    44 #include "runtime/sharedRuntime.hpp"
    45 #include "runtime/stubCodeGenerator.hpp"
    46 #include "runtime/stubRoutines.hpp"
    47 #include "runtime/vframe.hpp"
    48 #include "services/heapDumper.hpp"
    49 #include "utilities/defaultStream.hpp"
    50 #include "utilities/events.hpp"
    51 #include "utilities/top.hpp"
    52 #include "utilities/vmError.hpp"
    53 #ifdef TARGET_OS_FAMILY_linux
    54 # include "os_linux.inline.hpp"
    55 # include "thread_linux.inline.hpp"
    56 #endif
    57 #ifdef TARGET_OS_FAMILY_solaris
    58 # include "os_solaris.inline.hpp"
    59 # include "thread_solaris.inline.hpp"
    60 #endif
    61 #ifdef TARGET_OS_FAMILY_windows
    62 # include "os_windows.inline.hpp"
    63 # include "thread_windows.inline.hpp"
    64 #endif
    65 #ifdef TARGET_OS_FAMILY_bsd
    66 # include "os_bsd.inline.hpp"
    67 # include "thread_bsd.inline.hpp"
    68 #endif
    70 #ifndef ASSERT
    71 #  ifdef _DEBUG
    72    // NOTE: don't turn the lines below into a comment -- if you're getting
    73    // a compile error here, change the settings to define ASSERT
    74    ASSERT should be defined when _DEBUG is defined.  It is not intended to be used for debugging
    75    functions that do not slow down the system too much and thus can be left in optimized code.
    76    On the other hand, the code should not be included in a production version.
    77 #  endif // _DEBUG
    78 #endif // ASSERT
    81 #ifdef _DEBUG
    82 #  ifndef ASSERT
    83      configuration error: ASSERT must be defined in debug version
    84 #  endif // ASSERT
    85 #endif // _DEBUG
    88 #ifdef PRODUCT
    89 #  if -defined _DEBUG || -defined ASSERT
    90      configuration error: ASSERT et al. must not be defined in PRODUCT version
    91 #  endif
    92 #endif // PRODUCT
    95 void warning(const char* format, ...) {
    96   if (PrintWarnings) {
    97     // In case error happens before init or during shutdown
    98     if (tty == NULL) ostream_init();
   100     tty->print("%s warning: ", VM_Version::vm_name());
   101     va_list ap;
   102     va_start(ap, format);
   103     tty->vprint_cr(format, ap);
   104     va_end(ap);
   105   }
   106   if (BreakAtWarning) BREAKPOINT;
   107 }
   109 #ifndef PRODUCT
   111 #define is_token_break(ch) (isspace(ch) || (ch) == ',')
   113 static const char* last_file_name = NULL;
   114 static int         last_line_no   = -1;
   116 // assert/guarantee/... may happen very early during VM initialization.
   117 // Don't rely on anything that is initialized by Threads::create_vm(). For
   118 // example, don't use tty.
   119 bool error_is_suppressed(const char* file_name, int line_no) {
   120   // The following 1-element cache requires that passed-in
   121   // file names are always only constant literals.
   122   if (file_name == last_file_name && line_no == last_line_no)  return true;
   124   int file_name_len = (int)strlen(file_name);
   125   char separator = os::file_separator()[0];
   126   const char* base_name = strrchr(file_name, separator);
   127   if (base_name == NULL)
   128     base_name = file_name;
   130   // scan the SuppressErrorAt option
   131   const char* cp = SuppressErrorAt;
   132   for (;;) {
   133     const char* sfile;
   134     int sfile_len;
   135     int sline;
   136     bool noisy;
   137     while ((*cp) != '\0' && is_token_break(*cp))  cp++;
   138     if ((*cp) == '\0')  break;
   139     sfile = cp;
   140     while ((*cp) != '\0' && !is_token_break(*cp) && (*cp) != ':')  cp++;
   141     sfile_len = cp - sfile;
   142     if ((*cp) == ':')  cp++;
   143     sline = 0;
   144     while ((*cp) != '\0' && isdigit(*cp)) {
   145       sline *= 10;
   146       sline += (*cp) - '0';
   147       cp++;
   148     }
   149     // "file:line!" means the assert suppression is not silent
   150     noisy = ((*cp) == '!');
   151     while ((*cp) != '\0' && !is_token_break(*cp))  cp++;
   152     // match the line
   153     if (sline != 0) {
   154       if (sline != line_no)  continue;
   155     }
   156     // match the file
   157     if (sfile_len > 0) {
   158       const char* look = file_name;
   159       const char* look_max = file_name + file_name_len - sfile_len;
   160       const char* foundp;
   161       bool match = false;
   162       while (!match
   163              && (foundp = strchr(look, sfile[0])) != NULL
   164              && foundp <= look_max) {
   165         match = true;
   166         for (int i = 1; i < sfile_len; i++) {
   167           if (sfile[i] != foundp[i]) {
   168             match = false;
   169             break;
   170           }
   171         }
   172         look = foundp + 1;
   173       }
   174       if (!match)  continue;
   175     }
   176     // got a match!
   177     if (noisy) {
   178       fdStream out(defaultStream::output_fd());
   179       out.print_raw("[error suppressed at ");
   180       out.print_raw(base_name);
   181       char buf[16];
   182       jio_snprintf(buf, sizeof(buf), ":%d]", line_no);
   183       out.print_raw_cr(buf);
   184     } else {
   185       // update 1-element cache for fast silent matches
   186       last_file_name = file_name;
   187       last_line_no   = line_no;
   188     }
   189     return true;
   190   }
   192   if (!is_error_reported()) {
   193     // print a friendly hint:
   194     fdStream out(defaultStream::output_fd());
   195     out.print_raw_cr("# To suppress the following error report, specify this argument");
   196     out.print_raw   ("# after -XX: or in .hotspotrc:  SuppressErrorAt=");
   197     out.print_raw   (base_name);
   198     char buf[16];
   199     jio_snprintf(buf, sizeof(buf), ":%d", line_no);
   200     out.print_raw_cr(buf);
   201   }
   202   return false;
   203 }
   205 #undef is_token_break
   207 #else
   209 // Place-holder for non-existent suppression check:
   210 #define error_is_suppressed(file_name, line_no) (false)
   212 #endif // !PRODUCT
   214 void report_vm_error(const char* file, int line, const char* error_msg,
   215                      const char* detail_msg)
   216 {
   217   if (Debugging || error_is_suppressed(file, line)) return;
   218   Thread* const thread = ThreadLocalStorage::get_thread_slow();
   219   VMError err(thread, file, line, error_msg, detail_msg);
   220   err.report_and_die();
   221 }
   223 void report_fatal(const char* file, int line, const char* message)
   224 {
   225   report_vm_error(file, line, "fatal error", message);
   226 }
   228 // Used by report_vm_out_of_memory to detect recursion.
   229 static jint _exiting_out_of_mem = 0;
   231 void report_vm_out_of_memory(const char* file, int line, size_t size,
   232                              const char* message) {
   233   if (Debugging) return;
   235   // We try to gather additional information for the first out of memory
   236   // error only; gathering additional data might cause an allocation and a
   237   // recursive out_of_memory condition.
   239   const jint exiting = 1;
   240   // If we succeed in changing the value, we're the first one in.
   241   bool first_time_here = Atomic::xchg(exiting, &_exiting_out_of_mem) != exiting;
   243   if (first_time_here) {
   244     Thread* thread = ThreadLocalStorage::get_thread_slow();
   245     VMError(thread, file, line, size, message).report_and_die();
   246   }
   248   // Dump core and abort
   249   vm_abort(true);
   250 }
   252 void report_should_not_call(const char* file, int line) {
   253   report_vm_error(file, line, "ShouldNotCall()");
   254 }
   256 void report_should_not_reach_here(const char* file, int line) {
   257   report_vm_error(file, line, "ShouldNotReachHere()");
   258 }
   260 void report_unimplemented(const char* file, int line) {
   261   report_vm_error(file, line, "Unimplemented()");
   262 }
   264 void report_untested(const char* file, int line, const char* message) {
   265 #ifndef PRODUCT
   266   warning("Untested: %s in %s: %d\n", message, file, line);
   267 #endif // !PRODUCT
   268 }
   270 void report_out_of_shared_space(SharedSpaceType shared_space) {
   271   static const char* name[] = {
   272     "permanent generation",
   273     "shared read only space",
   274     "shared read write space",
   275     "shared miscellaneous data space"
   276   };
   277   static const char* flag[] = {
   278     "PermGen",
   279     "SharedReadOnlySize",
   280     "SharedReadWriteSize",
   281     "SharedMiscDataSize"
   282   };
   284    warning("\nThe %s is not large enough\n"
   285            "to preload requested classes. Use -XX:%s=\n"
   286            "to increase the initial size of %s.\n",
   287            name[shared_space], flag[shared_space], name[shared_space]);
   288    exit(2);
   289 }
   291 void report_java_out_of_memory(const char* message) {
   292   static jint out_of_memory_reported = 0;
   294   // A number of threads may attempt to report OutOfMemoryError at around the
   295   // same time. To avoid dumping the heap or executing the data collection
   296   // commands multiple times we just do it once when the first threads reports
   297   // the error.
   298   if (Atomic::cmpxchg(1, &out_of_memory_reported, 0) == 0) {
   299     // create heap dump before OnOutOfMemoryError commands are executed
   300     if (HeapDumpOnOutOfMemoryError) {
   301       tty->print_cr("java.lang.OutOfMemoryError: %s", message);
   302       HeapDumper::dump_heap_from_oome();
   303     }
   305     if (OnOutOfMemoryError && OnOutOfMemoryError[0]) {
   306       VMError err(message);
   307       err.report_java_out_of_memory();
   308     }
   309   }
   310 }
   312 static bool error_reported = false;
   314 // call this when the VM is dying--it might loosen some asserts
   315 void set_error_reported() {
   316   error_reported = true;
   317 }
   319 bool is_error_reported() {
   320     return error_reported;
   321 }
   323 #ifndef PRODUCT
   324 #include <signal.h>
   326 void test_error_handler(size_t test_num)
   327 {
   328   if (test_num == 0) return;
   330   // If asserts are disabled, use the corresponding guarantee instead.
   331   size_t n = test_num;
   332   NOT_DEBUG(if (n <= 2) n += 2);
   334   const char* const str = "hello";
   335   const size_t      num = (size_t)os::vm_page_size();
   337   const char* const eol = os::line_separator();
   338   const char* const msg = "this message should be truncated during formatting";
   340   // Keep this in sync with test/runtime/6888954/vmerrors.sh.
   341   switch (n) {
   342     case  1: assert(str == NULL, "expected null");
   343     case  2: assert(num == 1023 && *str == 'X',
   344                     err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
   345     case  3: guarantee(str == NULL, "expected null");
   346     case  4: guarantee(num == 1023 && *str == 'X',
   347                        err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
   348     case  5: fatal("expected null");
   349     case  6: fatal(err_msg("num=" SIZE_FORMAT " str=\"%s\"", num, str));
   350     case  7: fatal(err_msg("%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
   351                            "%s%s#    %s%s#    %s%s#    %s%s#    %s%s#    "
   352                            "%s%s#    %s%s#    %s%s#    %s%s#    %s",
   353                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
   354                            msg, eol, msg, eol, msg, eol, msg, eol, msg, eol,
   355                            msg, eol, msg, eol, msg, eol, msg, eol, msg));
   356     case  8: vm_exit_out_of_memory(num, "ChunkPool::allocate");
   357     case  9: ShouldNotCallThis();
   358     case 10: ShouldNotReachHere();
   359     case 11: Unimplemented();
   360     // This is last because it does not generate an hs_err* file on Windows.
   361     case 12: os::signal_raise(SIGSEGV);
   363     default: ShouldNotReachHere();
   364   }
   365 }
   366 #endif // !PRODUCT
   368 // ------ helper functions for debugging go here ------------
   370 // All debug entries should be wrapped with a stack allocated
   371 // Command object. It makes sure a resource mark is set and
   372 // flushes the logfile to prevent file sharing problems.
   374 class Command : public StackObj {
   375  private:
   376   ResourceMark rm;
   377   ResetNoHandleMark rnhm;
   378   HandleMark   hm;
   379   bool debug_save;
   380  public:
   381   static int level;
   382   Command(const char* str) {
   383     debug_save = Debugging;
   384     Debugging = true;
   385     if (level++ > 0)  return;
   386     tty->cr();
   387     tty->print_cr("\"Executing %s\"", str);
   388   }
   390   ~Command() {
   391         tty->flush();
   392         Debugging = debug_save;
   393         level--;
   394   }
   395 };
   397 int Command::level = 0;
   399 #ifndef PRODUCT
   401 extern "C" void blob(CodeBlob* cb) {
   402   Command c("blob");
   403   cb->print();
   404 }
   407 extern "C" void dump_vtable(address p) {
   408   Command c("dump_vtable");
   409   klassOop k = (klassOop)p;
   410   instanceKlass::cast(k)->vtable()->print();
   411 }
   414 extern "C" void nm(intptr_t p) {
   415   // Actually we look through all CodeBlobs (the nm name has been kept for backwards compatability)
   416   Command c("nm");
   417   CodeBlob* cb = CodeCache::find_blob((address)p);
   418   if (cb == NULL) {
   419     tty->print_cr("NULL");
   420   } else {
   421     cb->print();
   422   }
   423 }
   426 extern "C" void disnm(intptr_t p) {
   427   Command c("disnm");
   428   CodeBlob* cb = CodeCache::find_blob((address) p);
   429   nmethod* nm = cb->as_nmethod_or_null();
   430   if (nm) {
   431     nm->print();
   432     Disassembler::decode(nm);
   433   } else {
   434     cb->print();
   435     Disassembler::decode(cb);
   436   }
   437 }
   440 extern "C" void printnm(intptr_t p) {
   441   char buffer[256];
   442   sprintf(buffer, "printnm: " INTPTR_FORMAT, p);
   443   Command c(buffer);
   444   CodeBlob* cb = CodeCache::find_blob((address) p);
   445   if (cb->is_nmethod()) {
   446     nmethod* nm = (nmethod*)cb;
   447     nm->print_nmethod(true);
   448   }
   449 }
   452 extern "C" void universe() {
   453   Command c("universe");
   454   Universe::print();
   455 }
   458 extern "C" void verify() {
   459   // try to run a verify on the entire system
   460   // note: this may not be safe if we're not at a safepoint; for debugging,
   461   // this manipulates the safepoint settings to avoid assertion failures
   462   Command c("universe verify");
   463   bool safe = SafepointSynchronize::is_at_safepoint();
   464   if (!safe) {
   465     tty->print_cr("warning: not at safepoint -- verify may fail");
   466     SafepointSynchronize::set_is_at_safepoint();
   467   }
   468   // Ensure Eden top is correct before verification
   469   Universe::heap()->prepare_for_verify();
   470   Universe::verify(true);
   471   if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
   472 }
   475 extern "C" void pp(void* p) {
   476   Command c("pp");
   477   FlagSetting fl(PrintVMMessages, true);
   478   FlagSetting f2(DisplayVMOutput, true);
   479   if (Universe::heap()->is_in(p)) {
   480     oop obj = oop(p);
   481     obj->print();
   482   } else {
   483     tty->print(PTR_FORMAT, p);
   484   }
   485 }
   488 // pv: print vm-printable object
   489 extern "C" void pa(intptr_t p)   { ((AllocatedObj*) p)->print(); }
   490 extern "C" void findpc(intptr_t x);
   492 #endif // !PRODUCT
   494 extern "C" void ps() { // print stack
   495   if (Thread::current() == NULL) return;
   496   Command c("ps");
   499   // Prints the stack of the current Java thread
   500   JavaThread* p = JavaThread::active();
   501   tty->print(" for thread: ");
   502   p->print();
   503   tty->cr();
   505   if (p->has_last_Java_frame()) {
   506     // If the last_Java_fp is set we are in C land and
   507     // can call the standard stack_trace function.
   508 #ifdef PRODUCT
   509     p->print_stack();
   510   } else {
   511     tty->print_cr("Cannot find the last Java frame, printing stack disabled.");
   512 #else // !PRODUCT
   513     p->trace_stack();
   514   } else {
   515     frame f = os::current_frame();
   516     RegisterMap reg_map(p);
   517     f = f.sender(&reg_map);
   518     tty->print("(guessing starting frame id=%#p based on current fp)\n", f.id());
   519     p->trace_stack_from(vframe::new_vframe(&f, &reg_map, p));
   520   pd_ps(f);
   521 #endif // PRODUCT
   522   }
   524 }
   526 extern "C" void pfl() {
   527   // print frame layout
   528   Command c("pfl");
   529   JavaThread* p = JavaThread::active();
   530   tty->print(" for thread: ");
   531   p->print();
   532   tty->cr();
   533   if (p->has_last_Java_frame()) {
   534     p->print_frame_layout();
   535   }
   536 }
   538 #ifndef PRODUCT
   540 extern "C" void psf() { // print stack frames
   541   {
   542     Command c("psf");
   543     JavaThread* p = JavaThread::active();
   544     tty->print(" for thread: ");
   545     p->print();
   546     tty->cr();
   547     if (p->has_last_Java_frame()) {
   548       p->trace_frames();
   549     }
   550   }
   551 }
   554 extern "C" void threads() {
   555   Command c("threads");
   556   Threads::print(false, true);
   557 }
   560 extern "C" void psd() {
   561   Command c("psd");
   562   SystemDictionary::print();
   563 }
   566 extern "C" void safepoints() {
   567   Command c("safepoints");
   568   SafepointSynchronize::print_state();
   569 }
   571 #endif // !PRODUCT
   573 extern "C" void pss() { // print all stacks
   574   if (Thread::current() == NULL) return;
   575   Command c("pss");
   576   Threads::print(true, PRODUCT_ONLY(false) NOT_PRODUCT(true));
   577 }
   579 #ifndef PRODUCT
   581 extern "C" void debug() {               // to set things up for compiler debugging
   582   Command c("debug");
   583   WizardMode = true;
   584   PrintVMMessages = PrintCompilation = true;
   585   PrintInlining = PrintAssembly = true;
   586   tty->flush();
   587 }
   590 extern "C" void ndebug() {              // undo debug()
   591   Command c("ndebug");
   592   PrintCompilation = false;
   593   PrintInlining = PrintAssembly = false;
   594   tty->flush();
   595 }
   598 extern "C" void flush()  {
   599   Command c("flush");
   600   tty->flush();
   601 }
   604 extern "C" void events() {
   605   Command c("events");
   606   Events::print_last(tty, 50);
   607 }
   610 extern "C" void nevents(int n) {
   611   Command c("events");
   612   Events::print_last(tty, n);
   613 }
   616 // Given a heap address that was valid before the most recent GC, if
   617 // the oop that used to contain it is still live, prints the new
   618 // location of the oop and the address. Useful for tracking down
   619 // certain kinds of naked oop and oop map bugs.
   620 extern "C" void pnl(intptr_t old_heap_addr) {
   621   // Print New Location of old heap address
   622   Command c("pnl");
   623 #ifndef VALIDATE_MARK_SWEEP
   624   tty->print_cr("Requires build with VALIDATE_MARK_SWEEP defined (debug build) and RecordMarkSweepCompaction enabled");
   625 #else
   626   MarkSweep::print_new_location_of_heap_address((HeapWord*) old_heap_addr);
   627 #endif
   628 }
   631 extern "C" methodOop findm(intptr_t pc) {
   632   Command c("findm");
   633   nmethod* nm = CodeCache::find_nmethod((address)pc);
   634   return (nm == NULL) ? (methodOop)NULL : nm->method();
   635 }
   638 extern "C" nmethod* findnm(intptr_t addr) {
   639   Command c("findnm");
   640   return  CodeCache::find_nmethod((address)addr);
   641 }
   643 static address same_page(address x, address y) {
   644   intptr_t page_bits = -os::vm_page_size();
   645   if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) {
   646     return x;
   647   } else if (x > y) {
   648     return (address)(intptr_t(y) | ~page_bits) + 1;
   649   } else {
   650     return (address)(intptr_t(y) & page_bits);
   651   }
   652 }
   654 class LookForRefInGenClosure : public OopsInGenClosure {
   655 public:
   656   oop target;
   657   void do_oop(oop* o) {
   658     if (o != NULL && *o == target) {
   659       tty->print_cr(INTPTR_FORMAT, o);
   660     }
   661   }
   662   void do_oop(narrowOop* o) { ShouldNotReachHere(); }
   663 };
   666 class LookForRefInObjectClosure : public ObjectClosure {
   667 private:
   668   LookForRefInGenClosure look_in_object;
   669 public:
   670   LookForRefInObjectClosure(oop target) { look_in_object.target = target; }
   671   void do_object(oop obj) {
   672     obj->oop_iterate(&look_in_object);
   673   }
   674 };
   677 static void findref(intptr_t x) {
   678   CollectedHeap *ch = Universe::heap();
   679   LookForRefInGenClosure lookFor;
   680   lookFor.target = (oop) x;
   681   LookForRefInObjectClosure look_in_object((oop) x);
   683   tty->print_cr("Searching heap:");
   684   ch->object_iterate(&look_in_object);
   686   tty->print_cr("Searching strong roots:");
   687   Universe::oops_do(&lookFor, false);
   688   JNIHandles::oops_do(&lookFor);   // Global (strong) JNI handles
   689   Threads::oops_do(&lookFor, NULL);
   690   ObjectSynchronizer::oops_do(&lookFor);
   691   //FlatProfiler::oops_do(&lookFor);
   692   SystemDictionary::oops_do(&lookFor);
   694   tty->print_cr("Searching code cache:");
   695   CodeCache::oops_do(&lookFor);
   697   tty->print_cr("Done.");
   698 }
   700 class FindClassObjectClosure: public ObjectClosure {
   701   private:
   702     const char* _target;
   703   public:
   704     FindClassObjectClosure(const char name[])  { _target = name; }
   706     virtual void do_object(oop obj) {
   707       if (obj->is_klass()) {
   708         Klass* k = klassOop(obj)->klass_part();
   709         if (k->name() != NULL) {
   710           ResourceMark rm;
   711           const char* ext = k->external_name();
   712           if ( strcmp(_target, ext) == 0 ) {
   713             tty->print_cr("Found " INTPTR_FORMAT, obj);
   714             obj->print();
   715           }
   716         }
   717       }
   718     }
   719 };
   721 //
   722 extern "C" void findclass(const char name[]) {
   723   Command c("findclass");
   724   if (name != NULL) {
   725     tty->print_cr("Finding class %s -> ", name);
   726     FindClassObjectClosure srch(name);
   727     Universe::heap()->permanent_object_iterate(&srch);
   728   }
   729 }
   731 // Another interface that isn't ambiguous in dbx.
   732 // Can we someday rename the other find to hsfind?
   733 extern "C" void hsfind(intptr_t x) {
   734   Command c("hsfind");
   735   os::print_location(tty, x, false);
   736 }
   739 extern "C" void hsfindref(intptr_t x) {
   740   Command c("hsfindref");
   741   findref(x);
   742 }
   744 extern "C" void find(intptr_t x) {
   745   Command c("find");
   746   os::print_location(tty, x, false);
   747 }
   750 extern "C" void findpc(intptr_t x) {
   751   Command c("findpc");
   752   os::print_location(tty, x, true);
   753 }
   756 // int versions of all methods to avoid having to type type casts in the debugger
   758 void pp(intptr_t p)          { pp((void*)p); }
   759 void pp(oop p)               { pp((void*)p); }
   761 void help() {
   762   Command c("help");
   763   tty->print_cr("basic");
   764   tty->print_cr("  pp(void* p)   - try to make sense of p");
   765   tty->print_cr("  pv(intptr_t p)- ((PrintableResourceObj*) p)->print()");
   766   tty->print_cr("  ps()          - print current thread stack");
   767   tty->print_cr("  pss()         - print all thread stacks");
   768   tty->print_cr("  pm(int pc)    - print methodOop given compiled PC");
   769   tty->print_cr("  findm(intptr_t pc) - finds methodOop");
   770   tty->print_cr("  find(intptr_t x)   - finds & prints nmethod/stub/bytecode/oop based on pointer into it");
   772   tty->print_cr("misc.");
   773   tty->print_cr("  flush()       - flushes the log file");
   774   tty->print_cr("  events()      - dump last 50 events");
   777   tty->print_cr("compiler debugging");
   778   tty->print_cr("  debug()       - to set things up for compiler debugging");
   779   tty->print_cr("  ndebug()      - undo debug");
   780 }
   782 #if 0
   784 // BobV's command parser for debugging on windows when nothing else works.
   786 enum CommandID {
   787   CMDID_HELP,
   788   CMDID_QUIT,
   789   CMDID_HSFIND,
   790   CMDID_PSS,
   791   CMDID_PS,
   792   CMDID_PSF,
   793   CMDID_FINDM,
   794   CMDID_FINDNM,
   795   CMDID_PP,
   796   CMDID_BPT,
   797   CMDID_EXIT,
   798   CMDID_VERIFY,
   799   CMDID_THREADS,
   800   CMDID_ILLEGAL = 99
   801 };
   803 struct CommandParser {
   804    char *name;
   805    CommandID code;
   806    char *description;
   807 };
   809 struct CommandParser CommandList[] = {
   810   (char *)"help", CMDID_HELP, "  Dump this list",
   811   (char *)"quit", CMDID_QUIT, "  Return from this routine",
   812   (char *)"hsfind", CMDID_HSFIND, "Perform an hsfind on an address",
   813   (char *)"ps", CMDID_PS, "    Print Current Thread Stack Trace",
   814   (char *)"pss", CMDID_PSS, "   Print All Thread Stack Trace",
   815   (char *)"psf", CMDID_PSF, "   Print All Stack Frames",
   816   (char *)"findm", CMDID_FINDM, " Find a methodOop from a PC",
   817   (char *)"findnm", CMDID_FINDNM, "Find an nmethod from a PC",
   818   (char *)"pp", CMDID_PP, "    Find out something about a pointer",
   819   (char *)"break", CMDID_BPT, " Execute a breakpoint",
   820   (char *)"exitvm", CMDID_EXIT, "Exit the VM",
   821   (char *)"verify", CMDID_VERIFY, "Perform a Heap Verify",
   822   (char *)"thread", CMDID_THREADS, "Dump Info on all Threads",
   823   (char *)0, CMDID_ILLEGAL
   824 };
   827 // get_debug_command()
   828 //
   829 // Read a command from standard input.
   830 // This is useful when you have a debugger
   831 // which doesn't support calling into functions.
   832 //
   833 void get_debug_command()
   834 {
   835   ssize_t count;
   836   int i,j;
   837   bool gotcommand;
   838   intptr_t addr;
   839   char buffer[256];
   840   nmethod *nm;
   841   methodOop m;
   843   tty->print_cr("You have entered the diagnostic command interpreter");
   844   tty->print("The supported commands are:\n");
   845   for ( i=0; ; i++ ) {
   846     if ( CommandList[i].code == CMDID_ILLEGAL )
   847       break;
   848     tty->print_cr("  %s \n", CommandList[i].name );
   849   }
   851   while ( 1 ) {
   852     gotcommand = false;
   853     tty->print("Please enter a command: ");
   854     count = scanf("%s", buffer) ;
   855     if ( count >=0 ) {
   856       for ( i=0; ; i++ ) {
   857         if ( CommandList[i].code == CMDID_ILLEGAL ) {
   858           if (!gotcommand) tty->print("Invalid command, please try again\n");
   859           break;
   860         }
   861         if ( strcmp(buffer, CommandList[i].name) == 0 ) {
   862           gotcommand = true;
   863           switch ( CommandList[i].code ) {
   864               case CMDID_PS:
   865                 ps();
   866                 break;
   867               case CMDID_PSS:
   868                 pss();
   869                 break;
   870               case CMDID_PSF:
   871                 psf();
   872                 break;
   873               case CMDID_FINDM:
   874                 tty->print("Please enter the hex addr to pass to findm: ");
   875                 scanf("%I64X", &addr);
   876                 m = (methodOop)findm(addr);
   877                 tty->print("findm(0x%I64X) returned 0x%I64X\n", addr, m);
   878                 break;
   879               case CMDID_FINDNM:
   880                 tty->print("Please enter the hex addr to pass to findnm: ");
   881                 scanf("%I64X", &addr);
   882                 nm = (nmethod*)findnm(addr);
   883                 tty->print("findnm(0x%I64X) returned 0x%I64X\n", addr, nm);
   884                 break;
   885               case CMDID_PP:
   886                 tty->print("Please enter the hex addr to pass to pp: ");
   887                 scanf("%I64X", &addr);
   888                 pp((void*)addr);
   889                 break;
   890               case CMDID_EXIT:
   891                 exit(0);
   892               case CMDID_HELP:
   893                 tty->print("Here are the supported commands: ");
   894                 for ( j=0; ; j++ ) {
   895                   if ( CommandList[j].code == CMDID_ILLEGAL )
   896                     break;
   897                   tty->print_cr("  %s --  %s\n", CommandList[j].name,
   898                                                  CommandList[j].description );
   899                 }
   900                 break;
   901               case CMDID_QUIT:
   902                 return;
   903                 break;
   904               case CMDID_BPT:
   905                 BREAKPOINT;
   906                 break;
   907               case CMDID_VERIFY:
   908                 verify();;
   909                 break;
   910               case CMDID_THREADS:
   911                 threads();;
   912                 break;
   913               case CMDID_HSFIND:
   914                 tty->print("Please enter the hex addr to pass to hsfind: ");
   915                 scanf("%I64X", &addr);
   916                 tty->print("Calling hsfind(0x%I64X)\n", addr);
   917                 hsfind(addr);
   918                 break;
   919               default:
   920               case CMDID_ILLEGAL:
   921                 break;
   922           }
   923         }
   924       }
   925     }
   926   }
   927 }
   928 #endif
   930 #endif // !PRODUCT

mercurial