From 512472ed17f84f636ebc3dfa1e4c1e0c5d8d6644 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 24 Sep 2020 20:35:03 +0800 Subject: [PATCH] Fix the problem that when the --enable-preview feature is enabled, set the wrong java version in watch/trace. #1526 #1223 --- .../taobao/arthas/bytekit/utils/AsmUtils.java | 20 ++++++++++++ .../arthas/bytekit/utils/AsmUtilsTest.java | 32 +++++++++++++++++++ .../taobao/arthas/core/advisor/Enhancer.java | 6 ++-- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/bytekit/src/main/java/com/taobao/arthas/bytekit/utils/AsmUtils.java b/bytekit/src/main/java/com/taobao/arthas/bytekit/utils/AsmUtils.java index f094d6644..9846d293d 100644 --- a/bytekit/src/main/java/com/taobao/arthas/bytekit/utils/AsmUtils.java +++ b/bytekit/src/main/java/com/taobao/arthas/bytekit/utils/AsmUtils.java @@ -561,6 +561,26 @@ public class AsmUtils { return new String(charArray); } + /** + * Java ClassFile versions (the minor version is stored in the 16 most + * significant bits, and the major version in the 16 least significant bits). + * @see com.alibaba.arthas.deps.org.objectweb.asm.Opcodes#V_PREVIEW + * @param version + * @return + */ + public static int getMajorVersion(int version) { + return 0x0000FFFF & version; + } + /** + * 替换掉完整 version里的 major version + * + * @param version + * @param majorVersion + * @return + */ + public static int setMajorVersion(int version, int majorVersion) { + return (version & 0xFFFF0000) | majorVersion; + } } diff --git a/bytekit/src/test/java/com/taobao/arthas/bytekit/utils/AsmUtilsTest.java b/bytekit/src/test/java/com/taobao/arthas/bytekit/utils/AsmUtilsTest.java index eef1d9ab4..21c122b16 100644 --- a/bytekit/src/test/java/com/taobao/arthas/bytekit/utils/AsmUtilsTest.java +++ b/bytekit/src/test/java/com/taobao/arthas/bytekit/utils/AsmUtilsTest.java @@ -141,4 +141,36 @@ public class AsmUtilsTest { Assertions.assertThat(object.getClass().getName()).isEqualTo("com.test.Test.XXX"); } + @Test + public void testGetMajorVersion() throws Exception { + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V1_1)).isEqualTo(45); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V1_2)).isEqualTo(46); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V1_3)).isEqualTo(47); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V1_4)).isEqualTo(48); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V1_5)).isEqualTo(49); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V1_6)).isEqualTo(50); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V1_7)).isEqualTo(51); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V1_8)).isEqualTo(52); + + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V9)).isEqualTo(53); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V10)).isEqualTo(54); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V11)).isEqualTo(55); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V12)).isEqualTo(56); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V13)).isEqualTo(57); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V14)).isEqualTo(58); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V15)).isEqualTo(59); + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V16)).isEqualTo(60); + + Assertions.assertThat(AsmUtils.getMajorVersion(Opcodes.V16 | Opcodes.V_PREVIEW)).isEqualTo(60); + } + + @Test + public void testSetMajorVersion() throws Exception { + int version = Opcodes.V16 | Opcodes.V_PREVIEW; + int newVersion = AsmUtils.setMajorVersion(version, 58); + + AsmUtils.getMajorVersion(newVersion); + + Assertions.assertThat(AsmUtils.getMajorVersion(newVersion)).isEqualTo(58); + } } diff --git a/core/src/main/java/com/taobao/arthas/core/advisor/Enhancer.java b/core/src/main/java/com/taobao/arthas/core/advisor/Enhancer.java index 2bbce18e2..0ff205bad 100644 --- a/core/src/main/java/com/taobao/arthas/core/advisor/Enhancer.java +++ b/core/src/main/java/com/taobao/arthas/core/advisor/Enhancer.java @@ -228,9 +228,9 @@ public class Enhancer implements ClassFileTransformer { affect.addMethodAndCount(inClassLoader, className, methodNode.name, methodNode.desc); } - // https://github.com/alibaba/arthas/issues/1223 - if (classNode.version < Opcodes.V1_5) { - classNode.version = Opcodes.V1_5; + // https://github.com/alibaba/arthas/issues/1223 , V1_5 的major version是49 + if (AsmUtils.getMajorVersion(classNode.version) < 49) { + classNode.version = AsmUtils.setMajorVersion(classNode.version, 49); } byte[] enhanceClassByteArray = AsmUtils.toBytes(classNode, inClassLoader, classReader);