1 /* 2 * Copyright (c) 2018, 2019, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package jdk.jfr.event.io; 27 28 import java.io.File; 29 import java.io.FileInputStream; 30 import java.io.FileOutputStream; 31 import java.io.IOException; 32 import java.io.InputStream; 33 import java.io.OutputStream; 34 import java.io.RandomAccessFile; 35 import java.lang.instrument.ClassFileTransformer; 36 import java.lang.instrument.Instrumentation; 37 import java.net.ServerSocket; 38 import java.net.Socket; 39 import java.security.ProtectionDomain; 40 import java.util.concurrent.CountDownLatch; 41 42 43 /** 44 * @test 45 * @key jfr 46 * @summary This test runs JFR with a javaagent that reads/writes files and 47 * sockets during every class definition. This is to verify that the i/o 48 * instrumentation in JFR does not interfere with javaagents. 49 * 50 * @library /lib/testlibrary 51 * @modules java.instrument 52 * 53 * @run shell MakeJAR.sh EvilInstrument 'Can-Redefine-Classes: true' 54 * @run main/othervm -javaagent:EvilInstrument.jar jdk.jfr.event.io.EvilInstrument 55 */ 56 57 public class EvilInstrument { 58 59 CountDownLatch socketEchoReady = new CountDownLatch(1); 60 ServerSocket ss; 61 62 /** 63 * Thread that echos everything from a socket. 64 */ 65 class SocketEcho extends Thread 66 { 67 public SocketEcho() { 68 setDaemon(true); 69 } 70 71 public void run() { 72 try { 73 Socket s = ss.accept(); 74 OutputStream os = s.getOutputStream(); 75 InputStream is = s.getInputStream(); 76 socketEchoReady.countDown(); 77 for(;;) { 78 int b = is.read(); 79 os.write(b); 80 } 81 } catch(Exception ex) { 82 ex.printStackTrace(); 83 System.exit(1); 84 } 85 } 86 } 87 88 public static File createScratchFile() throws IOException { 89 return File.createTempFile("EvilTransformer", null, new File(".")).getAbsoluteFile(); 90 } 91 92 class EvilTransformer implements ClassFileTransformer { 93 File scratch; 94 Socket s; 95 volatile boolean inited = false; 96 97 public EvilTransformer() throws Exception { 98 scratch = createScratchFile(); 99 ss = new ServerSocket(0); 100 new SocketEcho().start(); 101 s = new Socket(ss.getInetAddress(), ss.getLocalPort()); 102 socketEchoReady.await(); 103 inited = true; 104 } 105 106 public byte[] transform(ClassLoader loader, String className, 107 Class<?> classBeingRedefined, 108 ProtectionDomain protectionDomain, 109 byte[] classfileBuffer) 110 { 111 if (!inited) { 112 return null; 113 } 114 // Do i/o operations during every transform call. 115 try { 116 FileOutputStream fos = new FileOutputStream(scratch); 117 fos.write(31); 118 fos.close(); 119 120 FileInputStream fis = new FileInputStream(scratch); 121 fis.read(); 122 fis.close(); 123 124 RandomAccessFile raf = new RandomAccessFile(scratch, "rw"); 125 raf.read(); 126 raf.write(31); 127 raf.close(); 128 129 s.getOutputStream().write(31); 130 s.getInputStream().read(); 131 132 } catch(Exception ex) { 133 ex.printStackTrace(); 134 System.exit(1); 135 } 136 return null; 137 } 138 } 139 140 public static void premain(String agentArgs, Instrumentation inst) { 141 new EvilInstrument().addTransformer(inst); 142 } 143 144 private void addTransformer(Instrumentation inst) { 145 try { 146 inst.addTransformer(new EvilTransformer()); 147 } catch(Exception ex) { 148 ex.printStackTrace(); 149 System.exit(1); 150 } 151 } 152 153 public static void main(String... args) throws Exception { 154 System.out.println("Hello"); 155 } 156 157 }