arthas
arthas copied to clipboard
#cost>xxx错误命中,以及trace输出信息不完整
- [x] 我已经在 issues 里搜索,没有重复的issue。
环境信息
arthas-boot.jar或者as.sh的版本: 3.7.2- Arthas 版本: 4.0.1、4.0.2、4.0.3、4.0.4
- 操作系统版本: windows 11
- 目标进程的JVM版本: 17.0.11
- 执行
arthas-boot的版本: 3.7.2
重现问题的步骤
- 运行以下测试代码
public class SimpleArthasMatchTest {
public static void main(String[] args) throws InterruptedException {
while(true){
test1();
}
}
public static void test1() throws InterruptedException {
Thread.sleep(100);
test2();
}
public static void test2(){
if(ThreadLocalRandom.current().nextInt() == 0){
System.out.println("Unreachable in practice");
}
}
}
- 启动arthas
- 执行命令:trace SimpleArthasMatchTest test1 '#cost>10000'
- 按q终止命令
- 再次执行命令:trace SimpleArthasMatchTest test1 '#cost>10000'
- 如果没有匹配结果,重复第4、5步骤
期望的结果
- 第5步没有结果输出,耗时不可能超过10秒,不应该命中
实际运行的结果
- 第5步有结果输出,且不完整,第一条连子调用(test2方法)的信息都没有,第二、三条有子调用的信息,但没有trace方法本身的信息
[arthas@10632]$ trace SimpleArthasMatchTest test1 '#cost>10000'
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 42 ms, listenerId: 3
`---ts=2024-11-25 11:38:54.294;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
[arthas@10632]$ trace SimpleArthasMatchTest test1 '#cost>10000'
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 16 ms, listenerId: 4
`---ts=2024-11-25 11:39:00.220;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
`---[0.0414ms] SimpleArthasMatchTest:test2() #18
[arthas@10632]$ trace SimpleArthasMatchTest test1 '#cost>10000'
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 18 ms, listenerId: 5
`---ts=2024-11-25 11:39:04.875;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=jdk.internal.loader.ClassLoaders$AppClassLoader@63947c6b
`---[0.0366ms] SimpleArthasMatchTest:test2() #18
###问题原因 在执行方法增强逻辑时(SpyImpl类中的atEnter、atExit等方法),并不能保证atExit前一定执行过atEnter,导致依赖于进出栈来完成的操作无法正确执行,例如计算耗时,导致耗时计算错误,以及调用信息缺失等
#2565 跟这个是同一类问题,都是cost计算错误导致的,不同的表现形式
借楼,希望trace的cost命令,能支持过滤掉一次完整调用中,某些子调用小于#cost值的输出。