private static void dump(Iterable<AbstractInsnNode> il) { Textifier textifier = new Textifier(); MethodVisitor visitor = new TraceMethodVisitor(textifier); for (Iterator<AbstractInsnNode> it = il.iterator(); it.hasNext(); ) { AbstractInsnNode in = it.next(); in.accept(visitor); } StringWriter writer = new StringWriter(); try (PrintWriter pw = new PrintWriter(writer)) { textifier.print(pw); } System.out.println(writer.toString()); }
@Override public void visitEnd() { try { accept(inner); super.visitEnd(); } catch(Exception e){ Textifier t = new Textifier(); accept(new TraceMethodVisitor(t)); StringBuilderWriter sw = new StringBuilderWriter(); PrintWriter pw = new PrintWriter(sw); t.print(pw); pw.flush(); String bytecode = sw.getBuilder().toString(); logger.error(String.format("Failure while rendering method %s, %s, %s. ByteCode:\n %s", name, desc, signature, bytecode), e); throw new RuntimeException(String.format("Failure while rendering method %s, %s, %s. ByteCode:\n %s", name, desc, signature, bytecode), e); } }
/** * 格式化输出字节码 * @param bytecode */ public static void viewByteCode(byte[] bytecode) { ClassReader cr = new ClassReader(bytecode); ClassNode cn = new ClassNode(); cr.accept(cn, 0); final List<MethodNode> mns = cn.methods; Printer printer = new Textifier(); TraceMethodVisitor mp = new TraceMethodVisitor(printer); for (MethodNode mn : mns) { InsnList inList = mn.instructions; System.out.println(mn.name); for (int i = 0; i < inList.size(); i++) { inList.get(i).accept(mp); StringWriter sw = new StringWriter(); printer.print(new PrintWriter(sw)); printer.getText().clear(); System.out.print(sw.toString()); } } }
@Override public void visitEnd() { super.visitEnd(); if (!found && errorNoMatch) { StringWriter output = new StringWriter(); PrintWriter writer = new PrintWriter(output); writer.append("Cannot find nodes"); if (methods.size() > 0) { writer.append(" for methods ").append(methods.toString()); } writer.println(); Printer printer = new Textifier(); TraceMethodVisitor visitor = new TraceMethodVisitor(printer); for (AbstractInsnNode node : nodes) { node.accept(visitor); } printer.print(writer); throw new IllegalStateException(output.toString()); } }
public static void viewByteCode(byte[] bytecode) { ClassReader cr = new ClassReader(bytecode); ClassNode cn = new ClassNode(); cr.accept(cn, 0); final List<MethodNode> mns = cn.methods; Printer printer = new Textifier(); TraceMethodVisitor mp = new TraceMethodVisitor(printer); for (MethodNode mn : mns) { InsnList inList = mn.instructions; System.out.println(mn.name); for (int i = 0; i < inList.size(); i++) { inList.get(i).accept(mp); StringWriter sw = new StringWriter(); printer.print(new PrintWriter(sw)); printer.getText().clear(); System.out.print(sw.toString()); } } }
/** Returns a human readable string for the code that this {@link BytecodeProducer} generates. */ public final String trace() { // TODO(lukes): textifier has support for custom label names by overriding appendLabel. // Consider trying to make use of (using the Label.info field? adding a custom NamedLabel // sub type?) Textifier textifier = new Textifier(Opcodes.ASM6) { { // reset tab sizes. Since we don't care about formatting class names or method // signatures (only code). We only need to set the tab2,tab3 and ltab settings (tab is // for class members). this.tab = null; // trigger an error if used. this.tab2 = " "; // tab setting for instructions this.tab3 = ""; // tab setting for switch cases this.ltab = ""; // tab setting for labels } }; gen(new CodeBuilder(new TraceMethodVisitor(textifier), 0, "trace", "()V")); StringWriter writer = new StringWriter(); textifier.print(new PrintWriter(writer)); return writer.toString(); // Note textifier always adds a trailing newline }
public static String getMethodInstructionList(final MethodNode methodNode) { Preconditions.checkNotNull(methodNode, "methodNode"); final Printer printer = new NonMaxTextifier(); final TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer); methodNode.accept(traceMethodVisitor); final StringWriter stringWriter = new StringWriter(); final PrintWriter printWriter = new PrintWriter(stringWriter); printer.print(printWriter); printWriter.flush(); final String[] lines = PATTERN.split(stringWriter.toString()); int lineNr = 0; for (int i = 0; i < lines.length; i++) { if (!lines[i].startsWith(" @")) { lines[i] = String.format("%2d %s", lineNr++, lines[i]); } } return "Method '" + methodNode.name + "':\n" + NEWLINE.join(lines) + '\n'; }
@Override protected void setUp() throws Exception { super.setUp(); jsr = new JSRInlinerAdapter(Opcodes.ASM5, null, 0, "m", "()V", null, null) { @Override public void visitEnd() { System.err.println("started w/ method:" + name); Textifier t = new Textifier(); TraceMethodVisitor mv = new TraceMethodVisitor(t); for (int i = 0; i < instructions.size(); ++i) { instructions.get(i).accept(mv); System.err.print(Integer.toString(i + 100000).substring(1)); System.err.print(" : " + t.text.get(i)); } super.visitEnd(); System.err.println("finished w/ method:" + name); } }; exp = new MethodNode(0, "m", "()V", null, null); }
public static void printMethod(PrintStream out, MethodNode method) { final Textifier textifier = new Textifier(); final TraceMethodVisitor mv = new TraceMethodVisitor(textifier); out.println(method.name + method.desc); for (int j = 0; j < method.instructions.size(); ++j) { method.instructions.get(j).accept(mv); final StringBuffer s = new StringBuffer(); while (s.length() < method.maxStack + method.maxLocals + 1) { s.append(' '); } out.print(Integer.toString(j + 100000).substring(1)); out.print(" " + s + " : " + textifier.text.get(j)); } for (int j = 0; j < method.tryCatchBlocks.size(); ++j) { ((TryCatchBlockNode) method.tryCatchBlocks.get(j)).accept(mv); out.print(" " + textifier.text.get(method.instructions.size()+j)); } out.println(" MAXSTACK " + method.maxStack); out.println(" MAXLOCALS " + method.maxLocals); out.println(); }
@Override protected void setUp() throws Exception { super.setUp(); jsr = new JSRInlinerAdapter(null, 0, "m", "()V", null, null) { @Override public void visitEnd() { System.err.println("started w/ method:" + name); Textifier t = new Textifier(); TraceMethodVisitor mv = new TraceMethodVisitor(t); for (int i = 0; i < instructions.size(); ++i) { instructions.get(i).accept(mv); System.err.print(Integer.toString(i + 100000).substring(1)); System.err.print(" : " + t.text.get(i)); } super.visitEnd(); System.err.println("finished w/ method:" + name); } }; exp = new MethodNode(0, "m", "()V", null, null); }
private static void dump(MethodNode method) { Textifier textifier = new Textifier(); method.accept(new TraceMethodVisitor(textifier)); StringWriter writer = new StringWriter(); try (PrintWriter pw = new PrintWriter(writer)) { textifier.print(pw); } System.out.println(writer.toString()); }
@Override public String toString() { triggerDelayedParsingIfNeccessary(); TraceMethodVisitor visitor = new TraceMethodVisitor(new Textifier()); node.accept(visitor); StringWriter writer = new StringWriter(); visitor.p.print(new PrintWriter(writer)); return writer.toString(); }
public void traceMethod(String className, final String method) { new ClassReader(inMemoryClassFileManager.classBytes(className)).accept( new ClassVisitor(Opcodes.ASM5) { PrintWriter pw = new PrintWriter(System.out); Textifier p = new Textifier(); @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if(name.equals(method)) { p.visitMethod(access, name, desc, signature, exceptions); return new TraceMethodVisitor(p); } return null; } @Override public void visitEnd() { p.visitClassEnd(); if (pw != null) { p.print(pw); pw.flush(); } } }, ClassReader.SKIP_FRAMES ); }
public String toString() { Textifier t = new Textifier(); accept(new TraceMethodVisitor(t)); StringWriter sw = new StringWriter(); t.print(new PrintWriter(sw)); return sw.toString(); }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (method.matches(name, desc)) { Printer localPrinter = asmifier.visitMethod(access, name, desc, signature, exceptions); return new TraceMethodVisitor(null, localPrinter); } return null; }
public static String toString(MethodNode mn) { TraceMethodVisitor tcv = new TraceMethodVisitor(null, new Textifier()); mn.accept(tcv); StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); pw.println(mn.name + " " + mn.desc); tcv.p.print(pw); pw.flush(); return sw.toString(); }
public static List<String> toString(InsnList instructions) { Printer p = new Textifier(); TraceMethodVisitor mp = new TraceMethodVisitor(p); instructions.accept(mp); return p.getText().stream() .map(Object::toString) .map(String::trim) .collect(toList()); }
public static String toString(AbstractInsnNode instruction) { Printer p = new Textifier(); TraceMethodVisitor mp = new TraceMethodVisitor(p); instruction.accept(mp); String text = p.getText().stream() .map(Object::toString) .collect(joining("\n")); return text; }
public static void assertTraceDumpEquality( final MethodNode method, final String traceDump) throws Exception { Preconditions.checkNotNull(method, "method"); final Printer printer = new NonMaxTextifier(); final TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer); // MethodAdapter checkMethodAdapter = new MethodAdapter(traceMethodVisitor); final MethodVisitor checkMethodAdapter = new CheckMethodAdapter(traceMethodVisitor); method.accept(checkMethodAdapter); final StringWriter stringWriter = new StringWriter(); final PrintWriter printWriter = new PrintWriter(stringWriter); printer.print(printWriter); printWriter.flush(); assertEquals(stringWriter.toString(), traceDump); }
private String toString(MethodTree mt) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); TraceMethodVisitor mv = new TraceMethodVisitor(new Textifier()); mt.rawNode().accept(mv); try (PrintWriter pw = new PrintWriter(bos)) { mv.p.print(pw); } return "Byte code is \n" + new String(bos.toByteArray()); }
/** * Prints an individual method behavior. [debugging] * * @param node the node to print * * @since 1.00 */ public static void print(MethodNode node) { Textifier tf = new Textifier(); node.accept(new TraceMethodVisitor(tf)); PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out)); tf.print(pw); pw.flush(); }
/** * Prints an instruction list. * * @param insn instructions * * @since 1.00 */ public static void print(InsnList insn) { Textifier tf = new Textifier(); MethodVisitor vis = new TraceMethodVisitor(tf); for (int i = 0; i < insn.size(); i++) { insn.get(i).accept(vis); } PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out)); tf.print(pw); pw.flush(); }
private String getText(final MethodNode mn) { Textifier tv = new Textifier(); TraceMethodVisitor tmv = new TraceMethodVisitor(tv); mn.accept(tmv); StringBuilder sb = new StringBuilder(); for (int i = 0; i < tv.text.size(); i++) { sb.append(tv.text.get(i)); } return sb.toString(); }
private static void printMethod(final Analyzer a, final PrintStream out, final MethodNode method) { final Frame[] frames = a.getFrames(); final Textifier textifier = new Textifier(); final TraceMethodVisitor mv = new TraceMethodVisitor(textifier); out.println(method.name + method.desc); for (int j = 0; j < method.instructions.size(); ++j) { method.instructions.get(j).accept(mv); final StringBuffer s = new StringBuffer(); final Frame f = frames[j]; if (f == null) { s.append('?'); } else { for (int k = 0; k < f.getLocals(); ++k) { s.append(getShortName(f.getLocal(k).toString())).append(' '); } s.append(" : "); for (int k = 0; k < f.getStackSize(); ++k) { s.append(getShortName(f.getStack(k).toString())).append(' '); } } while (s.length() < method.maxStack + method.maxLocals + 1) { s.append(' '); } out.print(Integer.toString(j + 100000).substring(1)); out.print(" " + s + " : " + textifier.text.get(j)); } for (int j = 0; j < method.tryCatchBlocks.size(); ++j) { ((TryCatchBlockNode) method.tryCatchBlocks.get(j)).accept(mv); out.print(" " + textifier.text.get(method.instructions.size()+j)); } out.println(" MAXSTACK " + method.maxStack); out.println(" MAXLOCALS " + method.maxLocals); out.println(); }
private String getText(final MethodNode mn) { Textifier tv = new Textifier(); TraceMethodVisitor tmv = new TraceMethodVisitor(tv); mn.accept(tmv); StringBuffer sb = new StringBuffer(); for (int i = 0; i < tv.text.size(); i++) { sb.append(tv.text.get(i)); } return sb.toString(); }
public void trace() { PrintWriter printWriter = new PrintWriter(System.out); printWriter.format("%nClass=%s, Method=%s [%s]%n", method.classCode.className, method.methodName, method.methodDescriptor); ((TraceMethodVisitor) mv).p.print(printWriter); printWriter.format("%n"); printWriter.flush(); }
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (methodName.equals(name) && methodType.toMethodDescriptorString().equals(desc)) { Printer p = printer.visitMethod(access, name, desc, signature, exceptions); return new TraceMethodVisitor(null, p); } return null; }
/** * Prints the method. * * @param node * the node * @param stream * the stream */ public static void printMethod(final MethodNode node, final ClassNode classNode, final PrintStream stream, final boolean build) { final Printer p; if (build) { p = new ClassNodeBuilderTextifier(node, classNode); } else { p = new ExtendedTextifier(node, classNode); } final TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(p); node.accept(traceMethodVisitor); stream.println(StringUtils.join(p.getText(), "")); }
@SuppressWarnings("unchecked") public <T extends TypeEntry> void emitOuterType(T ast) { ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); this.cw = writer; if (VERIFY_EMITTED_BYTECODE) { this.cw = new CheckClassAdapter(this.cw); } AstEmitter<AbstractEmitterContext, T> emitter = (AstEmitter<AbstractEmitterContext, T>) this.set.getAstEmitter(ast.getClass()); if (emitter == null) { throw new IllegalArgumentException("No emitter for ast entry " + ast.getClass().getName()); } emitter.emit(this, ast); this.cw.visitEnd(); byte[] clazz = writer.toByteArray(); if (DUMP_INSTRUCTIONS_AFTER_WRITE) { ClassReader cr = new ClassReader(clazz); ClassNode cn = new ClassNode(); cr.accept(cn, 0); List<MethodNode> methods = cn.methods; for (MethodNode mn : methods) { System.out.println("Method: " + mn.name + mn.desc); Printer printer = new Textifier(); TraceMethodVisitor mp = new TraceMethodVisitor(printer); for (Iterator<AbstractInsnNode> it = mn.instructions.iterator(); it.hasNext();) { AbstractInsnNode insn = it.next(); insn.accept(mp); } StringWriter sw = new StringWriter(); printer.print(new PrintWriter(sw)); String s = sw.toString(); if (s.endsWith("\n")) { s = s.substring(0, s.length() - 1); } System.out.println(s); mn.instructions.accept(mp); } } try { this.out.write(clazz); } catch (IOException e) { Throwables.propagate(e); } }
public static String toString(MethodNode mn) { Textifier t = new Textifier(); TraceMethodVisitor tmv = new TraceMethodVisitor(t); mn.accept(tmv); return t.toString(); }
public MethodRecorder() { printer = new Textifier(); visitor = new TraceMethodVisitor(printer); }
private boolean readClass(String clazz) throws IOException { ClassReader cr = new ClassReader(new FileInputStream(clazz)); ClassNode ca = new ClassNode() { public void visitEnd() { //accept(cv); } }; cr.accept(new CheckClassAdapter(ca), ClassWriter.COMPUTE_MAXS); boolean failed = false; List methods = ca.methods; for (int i = 0; i < methods.size(); ++i) { MethodNode method = (MethodNode) methods.get(i); if (method.instructions.size() > 0) { Analyzer a = new Analyzer(new SimpleVerifier()); try { a.analyze(ca.name, method); continue; } catch (Exception e) { e.printStackTrace(); } if (!failed) { failed = true; log("verifying of class " + clazz + " failed"); } if (verbose) log(method.name + method.desc); TraceMethodVisitor mv = new TraceMethodVisitor(null); /*= new TraceMethodVisitor(null) { public void visitMaxs(int maxStack, int maxLocals) { StringBuffer buffer = new StringBuffer(); for (int i = 0; i < text.size(); ++i) { String s = frames[i] == null ? "null" : frames[i].toString(); while (s.length() < maxStack + maxLocals + 1) { s += " "; } buffer.append(Integer.toString(i + 100000).substring(1)); buffer.append(" "); buffer.append(s); buffer.append(" : "); buffer.append(text.get(i)); } if (verbose) log(buffer.toString()); } };*/ for (int j = 0; j < method.instructions.size(); ++j) { Object insn = method.instructions.get(j); if (insn instanceof AbstractInsnNode) { ((AbstractInsnNode) insn).accept(mv); } else { mv.visitLabel((Label) insn); } } mv.visitMaxs(method.maxStack, method.maxLocals); } } return !failed; }
protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { controller.resetLineNumber(); Parameter[] parameters = node.getParameters(); String methodType = BytecodeHelper.getMethodDescriptor(node.getReturnType(), parameters); String signature = BytecodeHelper.getGenericsMethodSignature(node); int modifiers = node.getModifiers(); if (isVargs(node.getParameters())) modifiers |= Opcodes.ACC_VARARGS; MethodVisitor mv = cv.visitMethod(modifiers, node.getName(), methodType, signature, buildExceptions(node.getExceptions())); controller.setMethodVisitor(mv); visitAnnotations(node, mv); for (int i = 0; i < parameters.length; i++) { visitParameterAnnotations(parameters[i], i, mv); } // Add parameter names to the MethodVisitor (jdk8+ only) if (getCompileUnit().getConfig().getParameters()) { for (int i = 0; i < parameters.length; i++) { // TODO handle ACC_SYNTHETIC for enum method parameters? mv.visitParameter(parameters[i].getName(), 0); } } if (controller.getClassNode().isAnnotationDefinition() && !node.isStaticConstructor()) { visitAnnotationDefault(node, mv); } else if (!node.isAbstract()) { Statement code = node.getCode(); mv.visitCode(); // fast path for getter/setters etc. if (code instanceof BytecodeSequence && ((BytecodeSequence)code).getInstructions().size() == 1 && ((BytecodeSequence)code).getInstructions().get(0) instanceof BytecodeInstruction) { ((BytecodeInstruction)((BytecodeSequence)code).getInstructions().get(0)).visit(mv); } else { visitStdMethod(node, isConstructor, parameters, code); } // we use this NOP to have a valid jump target for the various labels //mv.visitInsn(NOP); try { mv.visitMaxs(0, 0); } catch (Exception e) { Writer writer = null; if (mv instanceof TraceMethodVisitor) { TraceMethodVisitor tracer = (TraceMethodVisitor) mv; writer = new StringBuilderWriter(); PrintWriter p = new PrintWriter(writer); tracer.p.print(p); p.flush(); } StringBuilder outBuffer = new StringBuilder(); outBuffer.append("ASM reporting processing error for "); outBuffer.append(controller.getClassNode().toString() + "#" + node.getName()); outBuffer.append(" with signature " + node.getTypeDescriptor()); outBuffer.append(" in " + sourceFile + ":" + node.getLineNumber()); if (writer != null) { outBuffer.append("\nLast known generated bytecode in last generated method or constructor:\n"); outBuffer.append(writer); } throw new GroovyRuntimeException(outBuffer.toString(), e); } } mv.visitEnd(); }
private static Map<String, List<Integer>> getClassInstructions(InputStream classAsInputStream) { HashMap<String, List<Integer>> methodInstructionsMap = new HashMap<>(); try { ClassReader reader = new ClassReader(classAsInputStream); ClassNode classNode = new ClassNode(); reader.accept(classNode, 0); @SuppressWarnings("unchecked") final List<MethodNode> methods = classNode.methods; Printer printer = new Textifier(); TraceMethodVisitor mp = new TraceMethodVisitor(printer); for (MethodNode m : methods) { List<Integer> instructions = new ArrayList<>(); InsnList inList = m.instructions; String mathodID = m.name + ": " + m.desc; System.out.println(mathodID); int[] methodInstructions = new int[inList.size()]; for (int i = 0; i < inList.size(); i++) { int op = inList.get(i).getOpcode(); methodInstructions[i] = op; AbstractInsnNode insn = inList.get(i); insn.accept(mp); // Uncomment the following comment block to print the bytecode // instructions // StringWriter sw = new StringWriter(); // printer.print(new PrintWriter(sw)); // printer.getText().clear(); // System.out.println(sw.toString()); // logger.warn("{} -> {}", sw.toString(), op); if (op != -1) instructions.add(op); } methodInstructionsMap.put(mathodID, instructions); } } catch (IOException e) { // Will fail if ClassReader fails e.printStackTrace(); } return methodInstructionsMap; }
private void verifyClassIntegrity(ClassNode classNode) { // Do not COMPUTE_FRAMES. If you COMPUTE_FRAMES and you pop too many items off the stack or do other weird things that mess up the // stack map frames, it'll crash on classNode.accept(cw). ClassWriter cw = new SimpleClassWriter(ClassWriter.COMPUTE_MAXS/* | ClassWriter.COMPUTE_FRAMES*/, classRepo); classNode.accept(cw); byte[] classData = cw.toByteArray(); ClassReader cr = new ClassReader(classData); classNode = new SimpleClassNode(); cr.accept(classNode, 0); for (MethodNode methodNode : classNode.methods) { Analyzer<BasicValue> analyzer = new Analyzer<>(new SimpleVerifier(classRepo)); try { analyzer.analyze(classNode.name, methodNode); } catch (AnalyzerException e) { // IF WE DID OUR INSTRUMENTATION RIGHT, WE SHOULD NEVER GET AN EXCEPTION HERE!!!! StringWriter writer = new StringWriter(); PrintWriter printWriter = new PrintWriter(writer); printWriter.append(methodNode.name + " encountered " + e); Printer printer = new Textifier(); TraceMethodVisitor traceMethodVisitor = new TraceMethodVisitor(printer); AbstractInsnNode insn = methodNode.instructions.getFirst(); while (insn != null) { if (insn == e.node) { printer.getText().add("----------------- BAD INSTRUCTION HERE -----------------\n"); } insn.accept(traceMethodVisitor); insn = insn.getNext(); } printer.print(printWriter); printWriter.flush(); // we need this or we'll get incomplete results throw new IllegalStateException(writer.toString(), e); } } }
@Override public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { // Unused? /* final MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); */ return new MethodNode(Opcodes.ASM5, access, name, desc, signature, exceptions) { @Override public void visitEnd() { super.visitEnd(); try { final BasicInterpreter basicInterpreter = new BasicInterpreter(); final Analyzer<BasicValue> analyzer = new Analyzer<>(basicInterpreter); final AbstractInsnNode[] nodes = instructions.toArray(); final Frame<BasicValue>[] frames = analyzer.analyze(className, this); int areturn = -1; for (int i = nodes.length -1; i >= 0; i--) { if (nodes[i].getOpcode() == Opcodes.ARETURN) { areturn = i; System.out.println(className + "." + name + desc); System.out.println("Found areturn at: " + i); } else if (areturn != -1 && nodes[i].getOpcode() != -1 && frames[i].getStackSize() == 0) { System.out.println("Found start of block at: " + i); final InsnList list = new InsnList(); for (int j = i; j <= areturn; j++) list.add(nodes[j]); final Textifier textifier = new Textifier(); final PrintWriter pw = new PrintWriter(System.out); list.accept(new TraceMethodVisitor(textifier)); textifier.print(pw); pw.flush(); System.out.println("\n\n"); areturn = -1; } } } catch (AnalyzerException e) { e.printStackTrace(); } if (mv != null) accept(mv); } }; }
public static void main(final String[] args) throws Exception { ClassReader cr = new ClassReader("Analysis"); ClassNode cn = new ClassNode(); cr.accept(cn, ClassReader.SKIP_DEBUG); List<MethodNode> methods = cn.methods; for (int i = 0; i < methods.size(); ++i) { MethodNode method = methods.get(i); if (method.instructions.size() > 0) { if (!analyze(cn, method)) { Analyzer<?> a = new Analyzer<BasicValue>( new BasicVerifier()); try { a.analyze(cn.name, method); } catch (Exception ignored) { } final Frame<?>[] frames = a.getFrames(); Textifier t = new Textifier() { @Override public void visitMaxs(final int maxStack, final int maxLocals) { for (int i = 0; i < text.size(); ++i) { StringBuilder s = new StringBuilder( frames[i] == null ? "null" : frames[i].toString()); while (s.length() < Math.max(20, maxStack + maxLocals + 1)) { s.append(' '); } System.err.print(Integer.toString(i + 1000) .substring(1) + " " + s + " : " + text.get(i)); } System.err.println(); } }; MethodVisitor mv = new TraceMethodVisitor(t); for (int j = 0; j < method.instructions.size(); ++j) { Object insn = method.instructions.get(j); ((AbstractInsnNode) insn).accept(mv); } mv.visitMaxs(0, 0); } } } }