forked from pinpoint-apm/pinpoint
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pinpoint-apm#1811 add bytecodedump option
- Loading branch information
Showing
11 changed files
with
408 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
84 changes: 84 additions & 0 deletions
84
...ler/src/main/java/com/navercorp/pinpoint/profiler/instrument/ASMBytecodeDisassembler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package com.navercorp.pinpoint.profiler.instrument; | ||
|
||
import org.objectweb.asm.ClassReader; | ||
import org.objectweb.asm.ClassWriter; | ||
import org.objectweb.asm.util.ASMifier; | ||
import org.objectweb.asm.util.CheckClassAdapter; | ||
import org.objectweb.asm.util.Printer; | ||
import org.objectweb.asm.util.Textifier; | ||
import org.objectweb.asm.util.TraceClassVisitor; | ||
|
||
import java.io.PrintWriter; | ||
import java.io.StringWriter; | ||
|
||
/** | ||
* @author Woonduk Kang(emeroad) | ||
*/ | ||
public class ASMBytecodeDisassembler { | ||
|
||
private final int cwFlag; | ||
private final int crFlag; | ||
|
||
public ASMBytecodeDisassembler() { | ||
this(ClassReader.EXPAND_FRAMES, ClassWriter.COMPUTE_FRAMES); | ||
} | ||
|
||
public ASMBytecodeDisassembler(int crFlag, int cwFlag) { | ||
this.cwFlag = cwFlag; | ||
this.crFlag = crFlag; | ||
} | ||
|
||
public String dumpBytecode(final byte[] bytecode) { | ||
if (bytecode == null) { | ||
throw new NullPointerException("bytecode must not be null"); | ||
} | ||
|
||
return writeBytecode(bytecode, new Textifier()); | ||
} | ||
|
||
|
||
public String dumpASM(byte[] bytecode) { | ||
if (bytecode == null) { | ||
throw new NullPointerException("bytecode must not be null"); | ||
} | ||
|
||
return writeBytecode(bytecode, new ASMifier()); | ||
} | ||
|
||
private String writeBytecode(byte[] bytecode, Printer printer) { | ||
|
||
final StringWriter out = new StringWriter(); | ||
final PrintWriter writer = new PrintWriter(out); | ||
|
||
accept(bytecode, printer, writer); | ||
|
||
return out.toString(); | ||
} | ||
|
||
private void accept(byte[] bytecode, Printer printer, PrintWriter writer) { | ||
|
||
final ClassReader cr = new ClassReader(bytecode); | ||
final ClassWriter cw = new ClassWriter(this.cwFlag); | ||
final TraceClassVisitor tcv = new TraceClassVisitor(cw, printer, writer); | ||
cr.accept(tcv, this.crFlag); | ||
} | ||
|
||
public String dumpVerify(byte[] bytecode, ClassLoader classLoader) { | ||
if (bytecode == null) { | ||
throw new NullPointerException("bytecode must not be null"); | ||
} | ||
if (classLoader == null) { | ||
throw new NullPointerException("classLoader must not be null"); | ||
} | ||
|
||
final StringWriter out = new StringWriter(); | ||
final PrintWriter writer = new PrintWriter(out); | ||
|
||
final ClassReader cr = new ClassReader(bytecode); | ||
CheckClassAdapter.verify(cr, classLoader, true, writer); | ||
|
||
return out.toString(); | ||
} | ||
|
||
|
||
} |
123 changes: 123 additions & 0 deletions
123
...iler/src/main/java/com/navercorp/pinpoint/profiler/instrument/ASMBytecodeDumpService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package com.navercorp.pinpoint.profiler.instrument; | ||
|
||
import com.navercorp.pinpoint.bootstrap.config.ProfilerConfig; | ||
import com.navercorp.pinpoint.bootstrap.util.StringUtils; | ||
import com.navercorp.pinpoint.profiler.util.JavaAssistUtils; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
/** | ||
* @author Woonduk Kang(emeroad) | ||
*/ | ||
public class ASMBytecodeDumpService implements BytecodeDumpService { | ||
|
||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | ||
|
||
public static final String ENABLE_BYTECODE_DUMP = "bytecode.dump.enable"; | ||
public static final boolean ENABLE_BYTECODE_DUMP_DEFAULT_VALUE = false; | ||
|
||
public static final String BYTECODE_DUMP_BYTECODE = "bytecode.dump.bytecode"; | ||
public static final boolean BYTECODE_DUMP_BYTECODE_DEFAULT_VALUE = true; | ||
|
||
public static final String BYTECODE_DUMP_VERIFY = "bytecode.dump.verify"; | ||
public static final boolean BYTECODE_DUMP_VERIFY_DEFAULT_VALUE = false; | ||
|
||
public static final String BYTECODE_DUMP_ASM = "bytecode.dump.asm"; | ||
public static final boolean BYTECODE_DUMP_ASM_DEFAULT_VALUE = true; | ||
|
||
public static final String DUMP_CLASS_LIST = "bytecode.dump.classlist"; | ||
|
||
private final boolean dumpBytecode; | ||
private final boolean dumpVerify; | ||
private final boolean dumpASM; | ||
private final Set<String> dumpJvmClassNameSet; | ||
|
||
private ASMBytecodeDisassembler disassembler = new ASMBytecodeDisassembler(); | ||
|
||
public ASMBytecodeDumpService(ProfilerConfig profilerConfig) { | ||
if (profilerConfig == null) { | ||
throw new NullPointerException("profilerConfig must not be null"); | ||
} | ||
|
||
this.dumpBytecode = profilerConfig.readBoolean(BYTECODE_DUMP_BYTECODE, BYTECODE_DUMP_BYTECODE_DEFAULT_VALUE); | ||
this.dumpVerify = profilerConfig.readBoolean(BYTECODE_DUMP_VERIFY, BYTECODE_DUMP_VERIFY_DEFAULT_VALUE); | ||
this.dumpASM = profilerConfig.readBoolean(BYTECODE_DUMP_ASM, BYTECODE_DUMP_ASM_DEFAULT_VALUE); | ||
|
||
this.dumpJvmClassNameSet = getClassName(profilerConfig); | ||
} | ||
|
||
private Set<String> getClassName(ProfilerConfig profilerConfig) { | ||
final String classNameList = profilerConfig.readString(DUMP_CLASS_LIST, ""); | ||
if (classNameList.isEmpty()) { | ||
return Collections.emptySet(); | ||
} else { | ||
final List<String> classList = StringUtils.splitAndTrim(classNameList, ","); | ||
final List<String> jvmClassList = javaNameToJvmName(classList); | ||
return new HashSet<String>(jvmClassList); | ||
} | ||
} | ||
|
||
public ASMBytecodeDumpService(boolean dumpBytecode, boolean dumpVerify, boolean dumpASM, List<String> classNameList) { | ||
if (classNameList == null) { | ||
throw new NullPointerException("classNameList must not be null"); | ||
} | ||
|
||
this.dumpBytecode = dumpBytecode; | ||
this.dumpVerify = dumpVerify; | ||
this.dumpASM = dumpASM; | ||
|
||
List<String> jvmClassNameList = javaNameToJvmName(classNameList); | ||
this.dumpJvmClassNameSet = new HashSet<String>(jvmClassNameList); | ||
} | ||
|
||
private List<String> javaNameToJvmName(List<String> classNameList) { | ||
List<String> jvmNameList = new ArrayList<String>(classNameList.size()); | ||
|
||
for (String className : classNameList) { | ||
jvmNameList.add(JavaAssistUtils.javaNameToJvmName(className)); | ||
} | ||
return jvmNameList; | ||
} | ||
|
||
@Override | ||
public void dumpBytecode(String dumpMessage, final String jvmClassName, final byte[] bytes, ClassLoader classLoader) { | ||
if (jvmClassName == null) { | ||
throw new NullPointerException("jvmClassName must not be null"); | ||
} | ||
|
||
if (!filterClassName(jvmClassName)) { | ||
return; | ||
} | ||
|
||
|
||
if (dumpBytecode) { | ||
final String dumpBytecode = this.disassembler.dumpBytecode(bytes); | ||
logger.info("{} class:{} bytecode:{}", dumpMessage, jvmClassName, dumpBytecode); | ||
} | ||
|
||
if (dumpVerify) { | ||
if (classLoader == null) { | ||
logger.debug("classLoader is null, jvmClassName:{}", jvmClassName); | ||
classLoader = ClassLoader.getSystemClassLoader(); | ||
} | ||
final String dumpVerify = this.disassembler.dumpVerify(bytes, classLoader); | ||
logger.info("{} class:{} verify:{}", dumpMessage, jvmClassName, dumpVerify); | ||
} | ||
|
||
if (dumpASM) { | ||
final String dumpASM = this.disassembler.dumpASM(bytes); | ||
logger.info("{} class:{} asm:{}", dumpMessage, jvmClassName, dumpASM); | ||
} | ||
} | ||
|
||
private boolean filterClassName(String className) { | ||
return this.dumpJvmClassNameSet.contains(className); | ||
} | ||
} | ||
|
9 changes: 9 additions & 0 deletions
9
profiler/src/main/java/com/navercorp/pinpoint/profiler/instrument/BytecodeDumpService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package com.navercorp.pinpoint.profiler.instrument; | ||
|
||
/** | ||
* @author Woonduk Kang(emeroad) | ||
*/ | ||
public interface BytecodeDumpService { | ||
|
||
void dumpBytecode(String dumpMessage, String jvmClassName, byte[] bytes, ClassLoader classLoader); | ||
} |
Oops, something went wrong.