NativeMethodPrefixAgent.java revision 12973:2e63fa2efdb1
1/* 2 * Copyright (c) 2005, 2015, 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/** 25 * @test 26 * @bug 6263319 27 * @summary test setNativeMethodPrefix 28 * @author Robert Field, Sun Microsystems 29 * 30 * @modules java.base/jdk.internal.org.objectweb.asm 31 * java.management 32 * java.instrument 33 * @run shell/timeout=240 MakeJAR2.sh NativeMethodPrefixAgent NativeMethodPrefixApp 'Can-Retransform-Classes: true' 'Can-Set-Native-Method-Prefix: true' 34 * @run main/othervm -javaagent:NativeMethodPrefixAgent.jar NativeMethodPrefixApp 35 */ 36 37import java.lang.instrument.*; 38import java.security.ProtectionDomain; 39import java.io.*; 40 41import asmlib.*; 42 43class NativeMethodPrefixAgent { 44 45 static ClassFileTransformer t0, t1, t2; 46 static Instrumentation inst; 47 48 static class Tr implements ClassFileTransformer { 49 final String trname; 50 final int transformId; 51 52 Tr(int transformId) { 53 this.trname = "tr" + transformId; 54 this.transformId = transformId; 55 } 56 57 public byte[] 58 transform( 59 ClassLoader loader, 60 String className, 61 Class<?> classBeingRedefined, 62 ProtectionDomain protectionDomain, 63 byte[] classfileBuffer) { 64 boolean redef = classBeingRedefined != null; 65 System.out.println(trname + ": " + 66 (redef? "Retransforming " : "Loading ") + className); 67 if (className != null) { 68 try { 69 byte[] newcf = Instrumentor.instrFor(classfileBuffer) 70 .addNativeMethodTrackingInjection( 71 "wrapped_" + trname + "_", 72 (h)->{ 73 h.push(h.getName()); 74 h.push(transformId); 75 h.invokeStatic("bootreporter/StringIdCallbackReporter", "tracker", "(Ljava/lang/String;I)V", false); 76 }) 77 .apply(); 78 /*** debugging ... 79 if (newcf != null) { 80 String fname = trname + (redef?"_redef" : "") + "/" + className; 81 System.err.println("dumping to: " + fname); 82 write_buffer(fname + "_before.class", classfileBuffer); 83 write_buffer(fname + "_instr.class", newcf); 84 } 85 ***/ 86 87 return redef? null : newcf; 88 } catch (Throwable ex) { 89 System.err.println("ERROR: Injection failure: " + ex); 90 ex.printStackTrace(); 91 System.err.println("Returning bad class file, to cause test failure"); 92 return new byte[0]; 93 } 94 } 95 return null; 96 } 97 98 } 99 100 // for debugging 101 static void write_buffer(String fname, byte[]buffer) { 102 try { 103 File f = new File(fname); 104 if (!f.getParentFile().exists()) { 105 f.getParentFile().mkdirs(); 106 } 107 try (FileOutputStream outStream = new FileOutputStream(f)) { 108 outStream.write(buffer, 0, buffer.length); 109 } 110 } catch (IOException ex) { 111 System.err.println("EXCEPTION in write_buffer: " + ex); 112 } 113 } 114 115 public static void 116 premain (String agentArgs, Instrumentation instArg) 117 throws IOException, IllegalClassFormatException, 118 ClassNotFoundException, UnmodifiableClassException { 119 inst = instArg; 120 System.out.println("Premain"); 121 122 t1 = new Tr(1); 123 t2 = new Tr(2); 124 t0 = new Tr(0); 125 inst.addTransformer(t1, true); 126 inst.addTransformer(t2, false); 127 inst.addTransformer(t0, true); 128 instArg.setNativeMethodPrefix(t0, "wrapped_tr0_"); 129 instArg.setNativeMethodPrefix(t1, "wrapped_tr1_"); 130 instArg.setNativeMethodPrefix(t2, "wrapped_tr2_"); 131 132 // warm up: cause load of transformer classes before used during class load 133 instArg.retransformClasses(Runtime.class); 134 } 135} 136