We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
@AtLine
@Binding.LocalVars
在尝试为 arthas 添加 @AtLine 的支持,用于打印出方法运行时,局部变量的信息。 当前有了一个 MVP 的版本(commit: lotabout/arthas@5536242#diff-060c8feafaa130cf1bf5dad5a84703d46db28aa09e78fe2088b8d49288005949R48)
在自测时,发现 @AtLine 返回的 LocalVars 和 LocalVarName 都是空。
LocalVars
LocalVarName
测试类如下:
public class Hello { public static void main(String[] args) throws InterruptedException { Sample sample = new Sample(); for (int i = 0; i < 10000; i++) { System.out.println(sample.hello()); Thread.sleep(1000); } } private static class Sample { private int i = 0; public String hello() { int x = i * 2; String y = String.format("hello %d", x); return y; } } }
启动测试类:
javac Hello.java java Hello
随后有添加 AtLine 版本的 arthas 进行 attach
AtLine
java -jar arthas-boot.jar # 其中 `-l` 新 patch 后新加的参数 $ watch Hello$Sample hello '{varNames, vars}' -l
在 arthas 的 Enhancer 中已经加了 log 逻辑,打印出 transform 后的代码,如下:
Enhancer
/* * Decompiled with CFR. * * Could not load the following classes: * java.arthas.SpyAPI */ import java.arthas.SpyAPI; private static class Hello.Sample { private int i = 0; public String hello() { Object[] objectArray = new Object[]{}; String string = "hello|()Ljava/lang/String;"; Class<Hello.Sample> clazz = Hello.Sample.class; Hello.Sample sample = this; SpyAPI.atEnter(clazz, (String)string, (Object)sample, (Object[])objectArray); try { String string2; String[] stringArray = new String[]{}; Object[] objectArray2 = new Object[]{}; int n = 16; Object[] objectArray3 = new Object[]{}; String string3 = "hello|()Ljava/lang/String;"; Class<Hello.Sample> clazz2 = Hello.Sample.class; Hello.Sample sample2 = this; SpyAPI.atLine(clazz2, (String)string3, (Object)sample2, (Object[])objectArray3, (int)n, (String[])stringArray, (Object[])objectArray2); int n2 = this.i * 2; String[] stringArray2 = new String[]{}; Object[] objectArray4 = new Object[]{}; int n3 = 17; Object[] objectArray5 = new Object[]{}; String string4 = "hello|()Ljava/lang/String;"; Class<Hello.Sample> clazz3 = Hello.Sample.class; Hello.Sample sample3 = this; SpyAPI.atLine(clazz3, (String)string4, (Object)sample3, (Object[])objectArray5, (int)n3, (String[])stringArray2, (Object[])objectArray4); String string5 = String.format("hello %d", n2); String[] stringArray3 = new String[]{}; Object[] objectArray6 = new Object[]{}; int n4 = 18; Object[] objectArray7 = new Object[]{}; String string6 = "hello|()Ljava/lang/String;"; Class<Hello.Sample> clazz4 = Hello.Sample.class; Hello.Sample sample4 = this; SpyAPI.atLine(clazz4, (String)string6, (Object)sample4, (Object[])objectArray7, (int)n4, (String[])stringArray3, (Object[])objectArray6); String string7 = string2 = string5; Object[] objectArray8 = new Object[]{}; String string8 = "hello|()Ljava/lang/String;"; Class<Hello.Sample> clazz5 = Hello.Sample.class; Hello.Sample sample5 = this; SpyAPI.atExit(clazz5, (String)string8, (Object)sample5, (Object[])objectArray8, (Object)string7); return string2; } catch (Throwable throwable) { Throwable throwable2 = throwable; Object[] objectArray9 = new Object[]{}; String string9 = "hello|()Ljava/lang/String;"; Class<Hello.Sample> clazz6 = Hello.Sample.class; Hello.Sample sample6 = this; SpyAPI.atExceptionExit(clazz6, (String)string9, (Object)sample6, (Object[])objectArray9, (Throwable)throwable2); throw throwable; } } private Hello.Sample() { } }
发现其中 atLine 的最后两个参数 varName 和 vars 都是空数组。
atLine
varName
vars
分别使用 JDK 1.8 和 JDK 11 进行测试,都有这个问题。
另外,单独运行 bytekit 的 unit test,是能正确 transform 的,下面是 UT 的一些中间输出
vars: [com.alibaba.bytekit.asm.interceptor.AtLineTest$Sample@5b3c56e0, 101, 100, 100100] varNames: [this, i, s, abc] method: methodtestLine|(I)I atLine: thiscom.alibaba.bytekit.asm.interceptor.AtLineTest$Sample@5b3c56e0 line: 29 args: [10202] argNames: [i] vars: [com.alibaba.bytekit.asm.interceptor.AtLineTest$Sample@5b3c56e0, 10202, 100, 100100] varNames: [this, i, s, abc] method: methodtestLine|(I)I atLine: thiscom.alibaba.bytekit.asm.interceptor.AtLineTest$Sample@5b3c56e0 line: 30 args: [10211] argNames: [i] vars: [com.alibaba.bytekit.asm.interceptor.AtLineTest$Sample@5b3c56e0, 10211, 100] varNames: [this, i, s] method: methodtestLine|(I)I atLine: thiscom.alibaba.bytekit.asm.interceptor.AtLineTest$Sample@5b3c56e0 line: 41 args: [10211] argNames: [i] vars: [com.alibaba.bytekit.asm.interceptor.AtLineTest$Sample@5b3c56e0, 10211, 100] varNames: [this, i, s]
The text was updated successfully, but these errors were encountered:
定位到是 AsmUtils.loadClass 与 AsmUtils.toClassNode 的差异,loadClass 生成的 ClassNode 缺少 localVariables 信息。 并发现 javac 后的 bytecode 就缺少了 localVariableTable。
AsmUtils.loadClass
AsmUtils.toClassNode
loadClass
Sorry, something went wrong.
No branches or pull requests
背景
在尝试为 arthas 添加
@AtLine
的支持,用于打印出方法运行时,局部变量的信息。当前有了一个 MVP 的版本(commit: lotabout/arthas@5536242#diff-060c8feafaa130cf1bf5dad5a84703d46db28aa09e78fe2088b8d49288005949R48)
在自测时,发现
@AtLine
返回的LocalVars
和LocalVarName
都是空。问题复现
测试类如下:
启动测试类:
随后有添加
AtLine
版本的 arthas 进行 attach在 arthas 的
Enhancer
中已经加了 log 逻辑,打印出 transform 后的代码,如下:发现其中
atLine
的最后两个参数varName
和vars
都是空数组。环境信息
分别使用 JDK 1.8 和 JDK 11 进行测试,都有这个问题。
另外,单独运行 bytekit 的 unit test,是能正确 transform 的,下面是 UT 的一些中间输出
The text was updated successfully, but these errors were encountered: