JadModel support line mappings. #1

This commit is contained in:
hengyunabc
2021-02-23 16:46:30 +08:00
parent c9e3099cbc
commit 2d7e19f133
4 changed files with 96 additions and 15 deletions
@@ -2,6 +2,7 @@ package com.taobao.arthas.core.command.klass100;
import com.alibaba.arthas.deps.org.slf4j.Logger;
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import com.taobao.arthas.common.Pair;
import com.taobao.arthas.core.command.Constants;
import com.taobao.arthas.core.command.model.ClassVO;
import com.taobao.arthas.core.command.model.ClassLoaderVO;
@@ -32,6 +33,7 @@ import java.lang.instrument.Instrumentation;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Set;
import java.util.Collection;
import java.util.regex.Pattern;
@@ -177,7 +179,8 @@ public class JadCommand extends AnnotatedCommand {
Map<Class<?>, File> classFiles = transformer.getDumpResult();
File classFile = classFiles.get(c);
String source = Decompiler.decompile(classFile.getAbsolutePath(), methodName, hideUnicode, lineNumber);
Pair<String,NavigableMap<Integer,Integer>> decompileResult = Decompiler.decompileWithMappings(classFile.getAbsolutePath(), methodName, hideUnicode, lineNumber);
String source = decompileResult.getFirst();
if (source != null) {
source = pattern.matcher(source).replaceAll("");
} else {
@@ -186,6 +189,7 @@ public class JadCommand extends AnnotatedCommand {
JadModel jadModel = new JadModel();
jadModel.setSource(source);
jadModel.setMappings(decompileResult.getSecond());
if (!this.sourceOnly) {
jadModel.setClassInfo(ClassUtils.createSimpleClassInfo(c));
jadModel.setLocation(ClassUtils.getCodeSource(c.getProtectionDomain().getCodeSource()));
@@ -1,15 +1,17 @@
package com.taobao.arthas.core.command.model;
import java.util.Collection;
import java.util.List;
import java.util.NavigableMap;
/**
* @author gongdewei 2020/4/22
* @author hengyunabc 2021-02-23
*/
public class JadModel extends ResultModel {
private ClassVO classInfo;
private String location;
private String source;
private NavigableMap<Integer,Integer> mappings;
private Collection<ClassLoaderVO> matchedClassLoaders;
private String classLoaderClass;
@@ -48,6 +50,14 @@ public class JadModel extends ResultModel {
this.source = source;
}
public NavigableMap<Integer, Integer> getMappings() {
return mappings;
}
public void setMappings(NavigableMap<Integer, Integer> mappings) {
this.mappings = mappings;
}
public Collection<ClassVO> getMatchedClasses() {
return matchedClasses;
}
@@ -8,11 +8,14 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;
import org.benf.cfr.reader.api.CfrDriver;
import org.benf.cfr.reader.api.OutputSinkFactory;
import org.benf.cfr.reader.api.SinkReturns.LineNumberMapping;
import com.taobao.arthas.common.Pair;
/**
*
* @author hengyunabc 2018-11-16
@@ -28,17 +31,11 @@ public class Decompiler {
return decompile(classFilePath, methodName, hideUnicode, true);
}
/**
* @param classFilePath
* @param methodName
* @param hideUnicode
* @return
*/
public static String decompile(String classFilePath, String methodName, boolean hideUnicode,
boolean printLineNumber) {
public static Pair<String, NavigableMap<Integer, Integer>> decompileWithMappings(String classFilePath,
String methodName, boolean hideUnicode, boolean printLineNumber) {
final StringBuilder sb = new StringBuilder(8192);
final Map<Integer, Integer> lineMapping = new HashMap<Integer, Integer>();
final NavigableMap<Integer, Integer> lineMapping = new TreeMap<Integer, Integer>();
OutputSinkFactory mySink = new OutputSinkFactory() {
@Override
@@ -59,7 +56,7 @@ public class Decompiler {
if (sinkType == SinkType.LINENUMBER) {
LineNumberMapping mapping = (LineNumberMapping) sinkable;
NavigableMap<Integer, Integer> classFileMappings = mapping.getClassFileMappings();
NavigableMap<Integer,Integer> mappings = mapping.getMappings();
NavigableMap<Integer, Integer> mappings = mapping.getMappings();
if (classFileMappings != null && mappings != null) {
for (Entry<Integer, Integer> entry : mappings.entrySet()) {
Integer srcLineNumber = classFileMappings.get(entry.getKey());
@@ -91,11 +88,17 @@ public class Decompiler {
toAnalyse.add(classFilePath);
driver.analyse(toAnalyse);
String result = sb.toString();
String resultCode = sb.toString();
if (printLineNumber && !lineMapping.isEmpty()) {
result = addLineNumber(result, lineMapping);
resultCode = addLineNumber(resultCode, lineMapping);
}
return result;
return Pair.make(resultCode, lineMapping);
}
public static String decompile(String classFilePath, String methodName, boolean hideUnicode,
boolean printLineNumber) {
return decompileWithMappings(classFilePath, methodName, hideUnicode, printLineNumber).getFirst();
}
private static String addLineNumber(String src, Map<Integer, Integer> lineMapping) {