hotspot/agent/test/libproc/LibprocClient.java
author never
Wed, 27 Aug 2008 00:21:55 -0700
changeset 1066 717c3345024f
parent 1 489c9b5090e2
child 5547 f4b087cbb361
permissions -rw-r--r--
5108146: Merge i486 and amd64 cpu directories 6459804: Want client (c1) compiler for x86_64 (amd64) for faster start-up Reviewed-by: kvn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
489c9b5090e2 Initial load
duke
parents:
diff changeset
     2
 * Copyright 2003 Sun Microsystems, Inc.  All Rights Reserved.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
 * CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
 * have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
import sun.jvm.hotspot.oops.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
import sun.jvm.hotspot.runtime.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
import sun.jvm.hotspot.tools.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
import sun.jvm.hotspot.utilities.*;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
/**
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
   We don't run any of the "standard" SA command line tools for sanity
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
   check. This is because the standard tools print addresses in hex
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
   which could change legally. Also, textual comparison of output may
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
   not match because of other reasons as well. This tool checks
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
   validity of threads and frames logically. This class has reference
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
   frame names from "known" threads. The debuggee is assumed to run
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
   "LibprocTest.java".
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
*/
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
public class LibprocClient extends Tool {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
   public void run() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
      // try to get VM version and check
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
      String version = VM.getVM().getVMRelease();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
      Assert.that(version.startsWith("1.5"), "1.5 expected");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
      // try getting threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
      Threads threads = VM.getVM().getThreads();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
      boolean mainTested = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
      // check frames of each thread
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
      for (JavaThread cur = threads.first(); cur != null; cur = cur.next()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
         if (cur.isJavaThread()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
             String name = cur.getThreadName();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
             // testing of basic frame walking for all threads
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
             for (JavaVFrame vf = getLastJavaVFrame(cur); vf != null; vf = vf.javaSender()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
                checkFrame(vf);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
             }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
             // special testing for "known" threads. For now, only "main" thread.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
             if (name.equals("main")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
                checkMainThread(cur);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
                mainTested = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
             }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
         }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
      Assert.that(mainTested, "main thread missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
   public static void main(String[] args) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
      try {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
         LibprocClient lc = new LibprocClient();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
         lc.start(args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
         lc.getAgent().detach();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
         System.out.println("\nPASSED\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
      } catch (Exception exp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
         System.out.println("\nFAILED\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
         exp.printStackTrace();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
   // -- Internals only below this point
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
   private static JavaVFrame getLastJavaVFrame(JavaThread cur) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
      RegisterMap regMap = cur.newRegisterMap(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
      Frame f = cur.getCurrentFrameGuess();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
      if (f == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
         System.err.println(" (Unable to get a top most frame)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
         return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
      VFrame vf = VFrame.newVFrame(f, regMap, cur, true, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
      if (vf == null) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
         System.err.println(" (Unable to create vframe for topmost frame guess)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
         return null;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
      if (vf.isJavaFrame()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
         return (JavaVFrame) vf;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
      return (JavaVFrame) vf.javaSender();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
   private void checkMethodSignature(Symbol sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
      SignatureIterator itr = new SignatureIterator(sig) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
                                  public void doBool  () {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
                                  public void doChar  () {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
                                  public void doFloat () {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
                                  public void doDouble() {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
                                  public void doByte  () {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
                                  public void doShort () {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
                                  public void doInt   () {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
                                  public void doLong  () {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
                                  public void doVoid  () {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
                                  public void doObject(int begin, int end) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
                                  public void doArray (int begin, int end) {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
                              };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
      // this will throw RuntimeException for any invalid item in signature.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
      itr.iterate();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
   private void checkBCI(Method m, int bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
      if (! m.isNative()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
         byte[] buf = m.getByteCode();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
         Assert.that(bci >= 0 && bci < buf.length, "invalid bci, not in code range");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
         if (m.hasLineNumberTable()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
           int lineNum = m.getLineNumberFromBCI(bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
           Assert.that(lineNum >= 0, "expecting non-negative line number");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
         }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
   private void checkMethodHolder(Method method) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
      Klass klass = method.getMethodHolder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
      Assert.that(klass != null, "expecting non-null instance klass");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
   private void checkFrame(JavaVFrame vf) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
      Method method = vf.getMethod();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
      Assert.that(method != null, "expecting a non-null method here");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
      Assert.that(method.getName() != null, "expecting non-null method name");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
      checkMethodHolder(method);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
      checkMethodSignature(method.getSignature());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
      checkBCI(method, vf.getBCI());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
   // from the test case LibprocTest.java - in the main thread we
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
   // should see frames as below
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
   private static String[] mainThreadMethods = new String[] {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
                             "java.lang.Object.wait(long)",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
                             "java.lang.Object.wait()",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
                             "LibprocTest.main(java.lang.String[])"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
                          };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
   private void checkMainThread(JavaThread thread) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
      checkFrames(thread, mainThreadMethods);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
   private void checkFrames(JavaThread thread, String[] expectedMethodNames) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
      int i = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
      for (JavaVFrame vf = getLastJavaVFrame(thread); vf != null; vf = vf.javaSender(), i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
         Method m = vf.getMethod();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
         Assert.that(m.externalNameAndSignature().equals(expectedMethodNames[i]),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
                     "expected frame missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
}