자바 에이전트 개발을 위해 Java Instrumentation과 ASM ByteCode Library를 사용하고 있습니다. 메소드에 의해 던진 런타임 예외를 얻는 방법?ASM ByteCode - 예외의 stackTrace
코드 첨부. 여기에서 메서드가 정상적으로 종료되는지 여부를 확인하거나 을 예외로 설정합니다. 그러나 예외를 검색 할 수 없습니다. 예외를 검색하는 방법?
package com.abc.agent.servlet;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import com.abc.agent.matcher.HttpServletMethodMatcher;
public class AbcServletMethodVisitorAdapter extends MethodVisitor {
private String methodName;
private String className;
private String description;
private boolean doMethodMatch;
private int opcode = -1;
public AbcServletMethodVisitorAdapter(MethodVisitor mv , String methodName , String description , String className) {
super(Opcodes.ASM4, mv);
this.methodName = methodName;
this.className = className;
this.description = description;
this.doMethodMatch = false;
}
public void visitCode() {
super.visitCode();
if(methodName.equals("<clinit>") || methodName.equals("<init>"))
return;
HttpServletMethodMatcher httpServletMethodMatcher = new HttpServletMethodMatcher(className , methodName , description);
this.doMethodMatch = httpServletMethodMatcher.isHttpServletMatch();
if(this.doMethodMatch){
mv.visitVarInsn(Opcodes.ALOAD, 0);
mv.visitVarInsn(Opcodes.ALOAD, 1);
mv.visitLdcInsn(this.className);
mv.visitLdcInsn(this.methodName);
mv.visitLdcInsn(this.description);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/abc/agent/trace/RootTracer", "httpServletDoMethodBegin", "(Ljava/lang/Object;Ljavax/servlet/http/HttpServletRequest;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
mv.visitCode();
}
else // Other Methods defined in the HttpServlet...
{
mv.visitLdcInsn(this.className);
mv.visitLdcInsn(this.methodName);
mv.visitLdcInsn(this.description);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/abc/agent/trace/RootTracer", "httpServletOtherMethodBegin", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
mv.visitCode();
}
}
public void visitMaxs(int maxStack, int maxLocals) {
super.visitMaxs(maxStack + 4, maxLocals);
}
public void visitInsn(int opcode) {
if(methodName.equals("<clinit>") || methodName.equals("<init>")){
// Do nothing....
}
else{
if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) || opcode == Opcodes.ATHROW) {
this.opcode = opcode;
mv.visitLdcInsn(this.className);
mv.visitLdcInsn(this.methodName);
mv.visitLdcInsn(this.description);
mv.visitLdcInsn(this.opcode);
if(this.doMethodMatch) {
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/abc/agent/trace/RootTracer", "httpServletDoMethodEnd", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
}
else{
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/abc/agent/trace/RootTracer", "httpServletOtherMethodEnd", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V");
}
}
}
mv.visitInsn(opcode);
}
}
방법과 거기에 뭔가를 추가 할 수 있습니다. 하지만 현재 메서드 또는이 메서드에서 호출 된 메서드에 의해 throw 된 모든 예외 스택 추적을 인쇄 할. 어떻게이 메서드에 의해 던져지고있는 예외 개체를 잡을 것인가? –
그래서,/I는 시작의 핸들을 가지고 말을 어떤 말을 수 있습니다 – AKS
예제 코드에서 'ASTORE, 1'이있는 행은 예외를 지역 변수 1에 저장합니다. 그런 다음 원하는만큼 여러 번 거기에서 검색 할 수 있습니다. 예제에서는'ALOAD, 1'을 로딩하고'printStackTrace'를 호출합니다. –