2017-03-20 9 views
0

저는 첫 번째 자바 에이전트를 작성하고 있습니다. 나는 git repo에서 골랐던 프로젝트를 도구로 사용하려고 노력하고있다.자바 에이전트 - 선택된 파일들을 인스트루먼트하십시오 (모든 내장 자바 클래스와 메소드 제외)

나는 모두 premain 방법으로 내 에이전트 클래스를 작성하고 일부 로깅을 구현 한 그러나

, 나는 심지어 붙박이 자바 기능/클래스가 호출하는 것을 볼합니다 (ASM 바이트 코드 조작 프레임 워크를 사용하여 실행 라인의 수를 기록) 잘못된 것을 계측하고 있습니다. 프로젝트의 파일 만 계측되기를 원합니다. 이를 위해, 나는 다음과 같이 필터를 추가 -

public static void premain(String agentArgs, Instrumentation inst) { 

    System.out.println("Premain called"); 

    inst.addTransformer(new ClassFileTransformer() { 
     public byte[] transform(ClassLoader classLoader, 
           String className, 
           Class<?> classBeingRedefined, 
           ProtectionDomain protectionDomain, 
           byte[] bytes)throws IllegalClassFormatException { 


     // ASM Code 
     if(className.startsWith("org/mytestpackage/")){ 
      ClassReader reader = new ClassReader(bytes); 
      ClassWriter writer = new ClassWriter(reader, 0); 
      ClassTransformVisitor visitor = new ClassTransformVisitor(writer); 
      reader.accept(visitor, 0); 
      return writer.toByteArray(); 
     } 

     return null; 

     } 
    }); 

    } 

내가이 필터를 추가 한 후, 모두 premain가 호출되고 있지만이 필터를 추가하기 전에 나는 조건 경우 (일부 예외

initializationError(org.mytestpackage.TestAllPackages) Time elapsed: 0.002 sec <<< ERROR! 
java.lang.VerifyError: (class: org/mytestpackage/TestAllPackages, method: main signature: ([Ljava/lang/String;)V) Stack size too large 
     at java.lang.Class.getDeclaredMethods0(Native Method) 
     at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) 
     at java.lang.Class.privateGetMethodRecursive(Class.java:3048) 
     at java.lang.Class.getMethod0(Class.java:3018) 
     at java.lang.Class.getMethod(Class.java:1784) 

무엇입니까 className을 기반으로), 나는 inbuilt java 클래스 및 메소드에 대한 내 논리 작업을 볼 수있었습니다. 실패한 경우 필터를 추가 한 후 실패합니다.

감사합니다. TIA.

답변

1

ClassTransformVisitor은 변형 된 사례의 코드를 어기는 것 같습니다. 특정 경우에는 클래스의 메서드 스택 크기를 조정하지 않는 것 같습니다 org.mytestpackage.TestAllPackages.

검증 자 오류 Stack size too large은 메소드의 피연산자 스택에이 스택의 슬롯으로 지정한 값보다 많은 값을 전달 함을 나타냅니다. new ClassWriter(reader, ClassWriter.COMPUTE_MAXS)을 지정하여 ASM에 문제를 해결하도록 요청할 수 있습니다.

+0

예. 그들은 내가 학급 작성자를 만들어 문제를 일으키는 것처럼 보였습니다. 고맙습니다. – maddie

+0

최대 크기를 직접 계산하지 않는다면 스택 맵 프레임을 만들지 않았을 것입니다. 따라서 Class 버전이 50 이상인 경우 ClassWriter.COMPUTE_FRAMES를 사용하여 둘 다 계산해야합니다. – Holger