From bbe10cb8d560c7365678d4549b88cf209699c5c3 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Sun, 26 Apr 2020 03:08:43 +0800 Subject: [PATCH] better support LineBinding --- .../arthas/bytekit/asm/binding/Binding.java | 22 +++++++++------ .../bytekit/asm/binding/LineBinding.java | 27 ++++++++++++++++--- .../bytekit/asm/interceptor/AtInvokeTest.java | 7 +++-- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/bytekit/src/main/java/com/taobao/arthas/bytekit/asm/binding/Binding.java b/bytekit/src/main/java/com/taobao/arthas/bytekit/asm/binding/Binding.java index cd38c7770..deb6aa7de 100644 --- a/bytekit/src/main/java/com/taobao/arthas/bytekit/asm/binding/Binding.java +++ b/bytekit/src/main/java/com/taobao/arthas/bytekit/asm/binding/Binding.java @@ -313,27 +313,33 @@ public abstract class Binding { } } - - + + @Documented @Retention(RetentionPolicy.RUNTIME) @java.lang.annotation.Target(ElementType.PARAMETER) @BindingParserHandler(parser = LineBindingParser.class) public static @interface Line { - boolean optional() default false; + /** + * 是否精确是在某个 LineNumberNode 上。如果为true的话,会向上找到最接近的 LineNumberNode + * + * @return + */ + boolean exact() default false; + } - + public static class LineBindingParser implements BindingParser { @Override public Binding parse(Annotation annotation) { - return new LineBinding(); + Line line = (Line) annotation; + return new LineBinding(line.exact()); } - } - - + + @Documented @Retention(RetentionPolicy.RUNTIME) @java.lang.annotation.Target(ElementType.PARAMETER) diff --git a/bytekit/src/main/java/com/taobao/arthas/bytekit/asm/binding/LineBinding.java b/bytekit/src/main/java/com/taobao/arthas/bytekit/asm/binding/LineBinding.java index cd57149c0..e30670856 100644 --- a/bytekit/src/main/java/com/taobao/arthas/bytekit/asm/binding/LineBinding.java +++ b/bytekit/src/main/java/com/taobao/arthas/bytekit/asm/binding/LineBinding.java @@ -8,17 +8,38 @@ import com.alibaba.arthas.deps.org.objectweb.asm.tree.LineNumberNode; import com.taobao.arthas.bytekit.asm.location.Location; import com.taobao.arthas.bytekit.utils.AsmOpUtils; +/** + * + * @author hengyunabc + * + */ public class LineBinding extends Binding { + private boolean exact; + + public LineBinding(boolean exact) { + this.exact = exact; + } + @Override public void pushOntoStack(InsnList instructions, BindingContext bindingContext) { Location location = bindingContext.getLocation(); AbstractInsnNode insnNode = location.getInsnNode(); - if (insnNode instanceof LineNumberNode) { - AsmOpUtils.push(instructions, ((LineNumberNode) insnNode).line); + if (exact) { + if (insnNode instanceof LineNumberNode) { + AsmOpUtils.push(instructions, ((LineNumberNode) insnNode).line); + } else { + throw new IllegalArgumentException("LineBinding location is not LineNumberNode, insnNode: " + insnNode); + } } else { - throw new IllegalArgumentException("LineBinding location is not LineNumberNode, insnNode: " + insnNode); + while (insnNode != null) { + if (insnNode instanceof LineNumberNode) { + AsmOpUtils.push(instructions, ((LineNumberNode) insnNode).line); + break; + } + insnNode = insnNode.getPrevious(); + } } } diff --git a/bytekit/src/test/java/com/taobao/arthas/bytekit/asm/interceptor/AtInvokeTest.java b/bytekit/src/test/java/com/taobao/arthas/bytekit/asm/interceptor/AtInvokeTest.java index 940679013..d33807517 100644 --- a/bytekit/src/test/java/com/taobao/arthas/bytekit/asm/interceptor/AtInvokeTest.java +++ b/bytekit/src/test/java/com/taobao/arthas/bytekit/asm/interceptor/AtInvokeTest.java @@ -28,6 +28,7 @@ public class AtInvokeTest { public int testCall(int ii) { toBeCall(ii, 123L, ""); System.err.println("abc"); + aaa("abc"); return 123; } @@ -60,10 +61,12 @@ public class AtInvokeTest { public static void onInvoke( @Binding.This Object object, @Binding.Class Object clazz - , + , + @Binding.Line int line, @Binding.InvokeArgs Object[] args ) { - System.err.println("onInvoke: this" + object); + System.err.println("onInvoke: line: " + line); + System.err.println("onInvoke: this: " + object); } @AtInvoke(name = "toBeCall", inline = false, whenComplete = true)