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