fix jad commnad VerifyError when the class is created by lambda expression. #675

This commit is contained in:
hengyunabc
2019-04-30 16:08:37 +08:00
parent e6d21ea8a4
commit 195ea0667b
2 changed files with 31 additions and 1 deletions
@@ -26,8 +26,12 @@ import com.taobao.text.ui.LabelElement;
import com.taobao.text.ui.TableElement;
import com.taobao.text.util.RenderUtil;
import static java.lang.System.arraycopy;
import java.io.File;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.util.*;
import java.util.regex.Pattern;
@@ -118,6 +122,27 @@ public class JadCommand extends AnnotatedCommand {
}
}
public static void retransformClasses(Instrumentation inst, ClassFileTransformer transformer, Set<Class<?>> classes) {
try {
inst.addTransformer(transformer, true);
for(Class<?> clazz : classes) {
try{
inst.retransformClasses(clazz);
}catch(Throwable e) {
String errorMsg = "retransformClasses class error, name: " + clazz.getName();
if(ClassUtils.isLambdaClass(clazz) && e instanceof VerifyError) {
errorMsg += ", Please ignore lambda class VerifyError: https://github.com/alibaba/arthas/issues/675";
}
logger.error("jad", errorMsg, e);
}
}
} finally {
inst.removeTransformer(transformer);
}
}
private void processExactMatch(CommandProcess process, RowAffect affect, Instrumentation inst, Set<Class<?>> matchedClasses, Set<Class<?>> withInnerClasses) {
Class<?> c = matchedClasses.iterator().next();
Set<Class<?>> allClasses = new HashSet<Class<?>>(withInnerClasses);
@@ -125,7 +150,8 @@ public class JadCommand extends AnnotatedCommand {
try {
ClassDumpTransformer transformer = new ClassDumpTransformer(allClasses);
Enhancer.enhance(inst, transformer, allClasses);
retransformClasses(inst, transformer, allClasses);
Map<Class<?>, File> classFiles = transformer.getDumpResult();
File classFile = classFiles.get(c);
@@ -23,6 +23,10 @@ public class ClassUtils {
return cs.getLocation().getFile();
}
public static boolean isLambdaClass(Class<?> clazz) {
return clazz.getName().contains("$$Lambda$");
}
public static Element renderClassInfo(Class<?> clazz) {
return renderClassInfo(clazz, false, null);
}