2016-10-31 2 views
1

JVMI 함수 RetransformClasses 및 이벤트 후크 ClassLoadFileHook을 사용하여 클래스를 계측하려는 다소 복잡한 아키텍처가 있습니다. JNI를 사용하여 변환을 수행하기 위해 Java 공간으로 이동합니다. ClassLoadFileHook에서 계측하고자하는 클래스에 대해 해고되는지 확인한 후 ASM 5.0.4을 사용하여 계측을 수행하는 Java 클래스에 대한 JNI 호출을 작성합니다. 즉, Java 공간에서 계측 된 클래스를 나타내는 바이트 배열을 가져온 다음 내 기본 코드로 다시 호출하여 업데이트를 적용합니다.ASM 바이트 코드 대체 함수가 완료되지 않았습니다.

내가 경험하고 문제는 내가 인스턴스화 후 나는 클래스를 재 변환 내 자바 코드에서, 코드/중에 걸려 있다는 것입니다 ClassReader :

/** 
* Transform some class and then call back down to native code to apply 
* the transformation. 
* 
* @param existingClass The existing class to change. 
*/ 
public synchronized void transformSomeClass(byte[] existingClass) { 
    System.out.println("Transformation function started. Existing class len: " + existingClass.length); 
    try { 
     ClassReader cr = new ClassReader(existingClass); 
     // No statements below here are being executed. 
     // I'm also not sure if `new ClassReader` is being successfully 
     // executed. 
     System.out.println("After ClassReader instantiation"); 
     ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 
     System.out.println("After ClassWriter instantiation"); 
     ClassVisitor cv = 
       new MyCustomClassAdapter(cw, this.lineNumberToPlaceUpdate_); 
     System.out.println("After ClassVisitor instantiation"); 
     cr.accept(cv, 0); 
     System.out.println("After cv accept."); 

     System.out.println("Applying class transformation natively."); 
     // Call back down to native code to apply the update in ClassLoadFileHook. 
     applyClassTransformNative(cw.toByteArray()); 
     System.out.println("Transformation function ended."); 
    } catch (Exception e) { 
     // This is never being fired. 
     System.err.println("Class transformation could not be completed. Error message: " + e.getMessage()); 
     e.printStackTrace(); 
    } finally { 
     // This print statement is never executed. 
     System.err.println("Going back to native code from finally"); 
    } 
} 

나는 코드의 코멘트에 언급 된 바와 같이 ClassReader intantiation 문이 실행 된 후에는 아무 것도 표시되지 않습니다. finally 블록조차 실행되지 않습니다. 여기서 무슨 일이 벌어 질지 확신 할 수 없습니다. 왜 일반적인 바이트 배열을 사용하는 ClassReader을 인스턴스화하면 코드가 이와 같이 정지하게됩니까? 나는 실제로 수업에서 어떤 작업도 수행하지 않았다.

+0

왜'new ClassReader'가 돌아 오지 않는지/내가 왜 디버거를 사용하지 않는지 모르겠다는 궁금증을 가진 사람을위한 부수적 인 언급으로, 내가 만들고있는 JNI 호출은 내가 ' 쓰기 때문에, 내가 아는 한 자바 프로세스가 하나의 에이전트 만 실행할 수 있기 때문에 디버거를 사용할 수있는 여유가 없다. 내가 틀렸다면 왜 누군가에게 왜 설명하고, 어떻게 디버거를 사용할 수 있는지 말해 주시면 감사하겠습니다. – DIMMSum

+3

ASM 클래스를로드하는 클래스 로더를 암시 적으로 잠그는 클래스 로딩을 트리거한다고 가정합니다. 따라서 코드가 진행되지 않습니다. 그렇지 않으면 결과물을 얻을 수 있습니다. –

+0

"Java 프로세스는 단일 에이전트 만 실행할 수 있습니다"? 나는 그런 제한에 대해 들어 본 적이 없다. 방금 테스트 했으므로 여러 에이전트를 실행하는 데 아무런 문제가 없었습니다 ... – Holger

답변

3

Java 코드로 호출하면 클래스 로딩이 발생하면 클래스를로드하는 클래스 로더에서 암시 적으로 동기화됩니다. Java 레이어에서 다시 트리거하려고 시도 할 때 네이티브 레이어에서 이러한 클래스 로딩을 트리거 한 다음 차단되는 것으로 가정합니다. 따라서 Java에서 클래스를 변환하려고하면 첫 번째 ASM 클래스를 넘어서는 작업을 수행하지 않는 것입니다.

관련 문제