1 /* 2 * Copyright (c) 2018, 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 * 51 * @library /lib / 52 * 53 * 54 * @run shell MakeJAR.sh EvilInstrument 'Can-Redefine-Classes: true' 55 * @run main/othervm -javaagent:EvilInstrument.jar jdk.jfr.event.io.EvilInstrument 56 */ 57 58 public class EvilInstrument { 59 60 CountDownLatch socketEchoReady = new CountDownLatch(1); 61 ServerSocket ss; 62 63 /** 64 * Thread that echos everything from a socket. 65 */ 66 class SocketEcho extends Thread 67 { 68 public SocketEcho() { 69 setDaemon(true); 70 } 71 72 public void run() { 73 try { 74 Socket s = ss.accept(); 75 OutputStream os = s.getOutputStream(); 76 InputStream is = s.getInputStream(); 77 socketEchoReady.countDown(); 78 for(;;) { 79 int b = is.read(); 80 os.write(b); 81 } 82 } catch(Exception ex) { 83 ex.printStackTrace(); 84 System.exit(1); 85 } 86 } 87 } 88 89 public static File createScratchFile() throws IOException { 90 return File.createTempFile("EvilTransformer", null, new File(".")).getAbsoluteFile(); 91 } 92 93 class EvilTransformer implements ClassFileTransformer { 94 File scratch; 95 Socket s; 96 volatile boolean inited = false; 97 98 public EvilTransformer() throws Exception { 99 scratch = createScratchFile(); 100 ss = new ServerSocket(0); 101 new SocketEcho().start(); 102 s = new Socket(ss.getInetAddress(), ss.getLocalPort()); 103 socketEchoReady.await(); 104 inited = true; 105 } 106 107 public byte[] transform(ClassLoader loader, String className, 108 Class<?> classBeingRedefined, 109 ProtectionDomain protectionDomain, 110 byte[] classfileBuffer) 111 { 112 if (!inited) { 113 return null; 114 } 115 // Do i/o operations during every transform call. 116 try { 117 FileOutputStream fos = new FileOutputStream(scratch); 118 fos.write(31); 119 fos.close(); 120 121 FileInputStream fis = new FileInputStream(scratch); 122 fis.read(); 123 fis.close(); 124 125 RandomAccessFile raf = new RandomAccessFile(scratch, "rw"); 126 raf.read(); 127 raf.write(31); 128 raf.close(); 129 130 s.getOutputStream().write(31); 131 s.getInputStream().read(); 132 133 } catch(Exception ex) { 134 ex.printStackTrace(); 135 System.exit(1); 136 } 137 return null; 138 } 139 } 140 141 public static void premain(String agentArgs, Instrumentation inst) { 142 new EvilInstrument().addTransformer(inst); 143 } 144 145 private void addTransformer(Instrumentation inst) { 146 try { 147 inst.addTransformer(new EvilTransformer()); 148 } catch(Exception ex) { 149 ex.printStackTrace(); 150 System.exit(1); 151 } 152 } 153 154 public static void main(String... args) throws Exception { 155 System.out.println("Hello"); 156 } 157 158 }