/** Checks all of the methods in gen for consistency */ public static void checkMgens(final ClassGen gen) { if (skip_checks) return; Method[] methods = gen.getMethods(); for (int i = 0; i < methods.length; i++) { Method method = methods[i]; // System.out.println ("Checking method " + method + " in class " // + gen.getClassName()); checkMgen(new MethodGen(method, gen.getClassName(), gen.getConstantPool())); } if (false) { Throwable t = new Throwable(); t.fillInStackTrace(); StackTraceElement[] ste = t.getStackTrace(); StackTraceElement caller = ste[1]; System.out.printf( "%s.%s (%s line %d)", caller.getClassName(), caller.getMethodName(), caller.getFileName(), caller.getLineNumber()); for (int ii = 2; ii < ste.length; ii++) System.out.printf(" [%s line %d]", ste[ii].getFileName(), ste[ii].getLineNumber()); System.out.printf("\n"); dump_methods(gen); } }
/** Checks the specific method for consistency. */ public static void checkMgen(MethodGen mgen) { if (skip_checks) return; try { mgen.toString(); mgen.getLineNumberTable(mgen.getConstantPool()); InstructionList ilist = mgen.getInstructionList(); if (ilist == null || ilist.getStart() == null) return; CodeExceptionGen[] exceptionHandlers = mgen.getExceptionHandlers(); for (CodeExceptionGen gen : exceptionHandlers) { assert ilist.contains(gen.getStartPC()) : "exception handler " + gen + " has been forgotten in " + mgen.getClassName() + "." + mgen.getName(); } MethodGen nmg = new MethodGen(mgen.getMethod(), mgen.getClassName(), mgen.getConstantPool()); nmg.getLineNumberTable(mgen.getConstantPool()); } catch (Throwable t) { System.out.printf("failure in method %s.%s\n", mgen.getClassName(), mgen.getName()); t.printStackTrace(); throw new Error(t); } }
public static void premain(String args, Instrumentation inst) throws Exception { try { String[] agentArgs; if (args == null) agentArgs = new String[] {""}; else agentArgs = args.split(","); if (!agentArgs[0].equals("instrumenting")) jarFileName = agentArgs[0]; BaseClassTransformer rct = null; rct = new BaseClassTransformer(); if (agentArgs[0].equals("instrumenting")) { initVMClasses = new HashSet<String>(); for (Class<?> c : inst.getAllLoadedClasses()) { ((Set<String>) initVMClasses).add(c.getName()); } } if (!agentArgs[0].equals("instrumenting")) { inst.addTransformer(rct); Tracer.setLocals(new CounterThreadLocal()); Tracer.overrideAll(true); for (Class<?> c : inst.getAllLoadedClasses()) { try { if (c.isInterface()) continue; if (c.isArray()) continue; byte[] bytes = rct.getBytes(c.getName()); if (bytes == null) { continue; } inst.redefineClasses(new ClassDefinition[] {new ClassDefinition(c, bytes)}); } catch (Throwable e) { synchronized (System.err) { System.err.println("" + c + " failed..."); e.printStackTrace(); } } } Runtime.getRuntime() .addShutdownHook( new Thread() { public void run() { Tracer.mark(); try { PrintStream ps = new PrintStream("bailout.txt"); ps.println("Bailouts: " + Tracer.getBailoutCount()); ps.close(); } catch (Exception e) { } Tracer.unmark(); } }); if ("true".equals(System.getProperty("bci.observerOn"))) Tracer.overrideAll(false); } } catch (Exception e) { e.printStackTrace(); } }
/** * Verifies one or more class files. Verification results are presented graphically: Red means * 'rejected', green means 'passed' while yellow means 'could not be verified yet'. * * @param args java.lang.String[] fully qualified names of classes to verify. */ public static void main(java.lang.String[] args) { classes_to_verify = args.length; for (int i = 0; i < args.length; i++) { try { VerifyDialog aVerifyDialog; aVerifyDialog = new VerifyDialog(args[i]); aVerifyDialog.setModal(true); aVerifyDialog.addWindowListener( new java.awt.event.WindowAdapter() { public void windowClosing(java.awt.event.WindowEvent e) { classes_to_verify--; if (classes_to_verify == 0) System.exit(0); }; }); aVerifyDialog.setVisible(true); } catch (Throwable exception) { System.err.println("Exception occurred in main() of javax.swing.JDialog"); exception.printStackTrace(System.out); } } }
/** * Given another class, return a transformed version of the class which replaces specified calls * with alternative static implementations */ public byte[] transform( ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { // debug = className.equals ("chicory/Test"); String fullClassName = className.replace("/", "."); debug_transform.log("In Transform: class = %s%n", className); // Don't instrument boot classes. We only want to instrument // user classes classpath. // Most boot classes have the null loader, // but some generated classes (such as those in sun.reflect) will // have a non-null loader. Some of these have a null parent loader, // but some do not. The check for the sun.reflect package is a hack // to catch all of these. A more consistent mechanism to determine // boot classes would be preferrable. if (loader == null) { debug_transform.log("ignoring system class %s, class loader == null", fullClassName); return (null); } else if (loader.getParent() == null) { debug_transform.log("ignoring system class %s, parent loader == null\n", fullClassName); return (null); } else if (fullClassName.startsWith("sun.reflect")) { debug_transform.log("ignoring system class %s, in sun.reflect package", fullClassName); return (null); } else if (fullClassName.startsWith("com.sun")) { System.out.printf("Class from com.sun package %s with nonnull loaders\n", fullClassName); } // Don't intrument our code if (className.startsWith("randoop.")) { debug_transform.log("Not considering randoop class %s%n", fullClassName); return (null); } // Look for match with specified regular expressions for class method_map = null; debug_class = false; for (MethodMapInfo mmi : map_list) { if (mmi.class_regex.matcher(className).matches()) { if (false && className.startsWith("RandoopTest")) debug_class = true; if (debug_class) System.out.printf("Classname %s matches re %s%n", className, mmi.class_regex); method_map = mmi.map; break; } } if (method_map == null) return null; debug_transform.log( "transforming class %s, loader %s - %s%n", className, loader, loader.getParent()); // Parse the bytes of the classfile, die on any errors JavaClass c = null; ClassParser parser = new ClassParser(new ByteArrayInputStream(classfileBuffer), className); try { c = parser.parse(); } catch (Exception e) { throw new RuntimeException("Unexpected error", e); } try { // Get the class information ClassGen cg = new ClassGen(c); ifact = new InstructionFactory(cg); map_calls(cg, className, loader); JavaClass njc = cg.getJavaClass(); if (debug) njc.dump("/tmp/ret/" + njc.getClassName() + ".class"); if (true) { return (cg.getJavaClass().getBytes()); } else { debug_transform.log("not including class %s (filtered out)", className); return null; } } catch (Throwable e) { out.format("Unexpected error %s in transform", e); e.printStackTrace(); return (null); } }