1 /* 2 * Copyright (c) 2016, 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 24 import java.io.IOException; 25 import java.util.Arrays; 26 import java.util.concurrent.CountDownLatch; 27 import java.util.Set; 28 import java.util.HashSet; 29 import static jdk.test.lib.Asserts.assertTrue; 30 31 /** 32 * @test 33 * @summary Tests AllModules JDWP command 34 * @library /test/lib 35 * @modules java.base/jdk.internal.misc 36 * @compile AllModulesCommandTestDebuggee.java 37 * @run main/othervm AllModulesCommandTest 38 */ 39 public class AllModulesCommandTest implements DebuggeeLauncher.Listener { 40 41 private DebuggeeLauncher launcher; 42 private JdwpChannel channel; 43 private CountDownLatch jdwpLatch = new CountDownLatch(1); 44 private Set<String> jdwpModuleNames = new HashSet<>(); 45 private Set<String> javaModuleNames = new HashSet<>(); 46 47 public static void main(String[] args) throws Throwable { 48 new AllModulesCommandTest().doTest(); 49 } 50 51 private void doTest() throws Throwable { 52 launcher = new DebuggeeLauncher(this); 53 launcher.launchDebuggee(); 54 // Await till the debuggee sends all the necessary modules info to check against 55 // then start the JDWP session 56 jdwpLatch.await(); 57 doJdwp(); 58 } 59 60 @Override 61 public void onDebuggeeModuleInfo(String modName) { 62 // The debuggee has sent out info about a loaded module 63 javaModuleNames.add(modName); 64 } 65 66 @Override 67 public void onDebuggeeSendingCompleted() { 68 // The debuggee has completed sending all the info 69 // We can start the JDWP session 70 jdwpLatch.countDown(); 71 } 72 73 @Override 74 public void onDebuggeeError(String message) { 75 System.err.println("Debuggee error: '" + message + "'"); 76 System.exit(1); 77 } 78 79 private void doJdwp() throws Exception { 80 try { 81 // Establish JDWP socket connection 82 channel = new JdwpChannel(); 83 channel.connect(); 84 // Send out ALLMODULES JDWP command 85 // and verify the reply 86 JdwpAllModulesReply reply = new JdwpAllModulesCmd().send(channel); 87 assertReply(reply); 88 for (int i = 0; i < reply.getModulesCount(); ++i) { 89 long modId = reply.getModuleId(i); 90 // For each module reported by JDWP get its name using the JDWP NAME command 91 getModuleName(modId); 92 // Assert the JDWP CANREAD and CLASSLOADER commands 93 assertCanRead(modId); 94 assertClassLoader(modId); 95 } 96 97 System.out.println("Module names reported by JDWP: " + Arrays.toString(jdwpModuleNames.toArray())); 98 System.out.println("Module names reported by Java: " + Arrays.toString(javaModuleNames.toArray())); 99 100 // Modules reported by the JDWP should be the same as reported by the Java API 101 if (!jdwpModuleNames.equals(javaModuleNames)) { 102 throw new RuntimeException("Modules info reported by Java API differs from that reported by JDWP."); 103 } else { 104 System.out.println("Test passed!"); 105 } 106 107 } finally { 108 launcher.terminateDebuggee(); 109 try { 110 new JdwpExitCmd(0).send(channel); 111 channel.disconnect(); 112 } catch (Exception x) { 113 } 114 } 115 } 116 117 private void getModuleName(long modId) throws IOException { 118 // Send out the JDWP NAME command and store the reply 119 JdwpModNameReply reply = new JdwpModNameCmd(modId).send(channel); 120 assertReply(reply); 121 String modName = reply.getModuleName(); 122 if (modName != null) { // JDWP reports unnamed modules, ignore them 123 jdwpModuleNames.add(modName); 124 } 125 } 126 127 private void assertReply(JdwpReply reply) { 128 // Simple assert for any JDWP reply 129 if (reply.getErrorCode() != 0) { 130 throw new RuntimeException("Unexpected reply error code " + reply.getErrorCode() + " for reply " + reply); 131 } 132 } 133 134 private void assertCanRead(long modId) throws IOException { 135 // Simple assert for the CANREAD command 136 JdwpCanReadReply reply = new JdwpCanReadCmd(modId, modId).send(channel); 137 assertReply(reply); 138 assertTrue(reply.canRead(), "canRead() reports false for reading from the same module"); 139 } 140 141 private void assertClassLoader(long modId) throws IOException { 142 // Simple assert for the CLASSLOADER command 143 JdwpClassLoaderReply reply = new JdwpClassLoaderCmd(modId).send(channel); 144 assertReply(reply); 145 long clId = reply.getClassLoaderId(); 146 assertTrue(clId >= 0, "bad classloader refId " + clId + " for module id " + modId); 147 } 148 149 }