2011-03-14 6 views
5

저는 JNI를 통해 레거시 애플리케이션의 다양한 고유 메소드를 호출하는 Java 애플리케이션을 보유하고 있습니다. 그러나 임의의 JNI 호출 외부의 임의의 위치에서 스택 덤프로 인해 JVM이 충돌합니다. 때로는 GC 동안, 때로는 클래스로드 및 기타 장소에서 충돌이 발생합니다. 하나 이상의 원시 메소드가 JVM 힙 또는 다른 데이터 구조를 손상시키는 것으로 의심됩니다. 이 호출이 무엇인지 알아야하므로 기본 구현을 수정할 수 있습니다.JNI 힙 손상 문제를 디버그하는 방법은 무엇입니까?

레거시 응용 프로그램은 원본이나 기호 정보가없는 타사 DLL입니다. Java에서 호출 가능하게 만들기 위해 JNI 호출 규칙을 사용하는 래퍼 DLL을 만들었습니다.

완벽한 솔루션은 JVM이 각 JNI 호출 후 힙 및 기타 데이터 구조의 무결성을 자동으로 검사하도록하는 확장 된 JVM 옵션입니다.

도움이 될만한 것을 알고 있습니까?

P. JVM과 레거시 애플리케이션 사이에 소켓이나 파이프 레이어를 빌드하라는 요구를하지 않기 때문에 요구하지 않습니다. 이것은 아키텍처 설계가 아니라 버그 탐지에 관한 것입니다.

+0

'-Xcheck : jni'에 대해 알고 있다고 가정합니다. – Erik

+0

네,하지만 물어봐 줘서 고마워. – fernacolo

+0

이것이 도움이된다면 나는 다음과 같은 문제를 안고있다 :/나는 JNI를 통해 많은 양의 데이터를 가져 왔고 때로는 손상된 주소와 패킷 데이터를 얻는다. 그것은 전체 시뮬레이션을 망치고, 그것은 정말로 성가신 일입니다. –

답변

5

답변이 없어서 혼자 준비된 솔루션을 찾을 수 없기 때문에 문제를 확인하기 위해 순수 C++로 샌드 박스 프로세스를 작성했습니다. 내 Java 응용 프로그램은 ProcessBuilder를 사용하여 샌드 박스 프로세스를 인스턴스화 한 다음 stdin 및 stdout을 사용하여 통신합니다. JVM 대신에 실제로 레거시 DLL을로드하고 호출하는 것은 샌드 박스입니다. 그런 다음 메모리 손상 문제가있는 Microsoft의 Application Verifier를 사용하여 샌드 박스 프로세스를 모니터링했습니다. 예상보다 작은 버퍼를 호출하는 호출이있었습니다. 이 문제가 확인 된 후 Java 앱에서 버퍼로 사용 된 byte []의 길이를 늘렸으므로 이제 JVM은 샌드 박스를 사용하지 않고 DLL을 직접 호출 할 수 있습니다.

전반적으로 JVM에는 각 JNI 호출 후에 힙을 확인하는 옵션이 없기 때문에 거의 10 일이 손실되었습니다. 그러나 적어도 누군가가 충돌을 발견하면 샌드 박스를 사용하여 충돌을 신속하게 디버깅 할 수 있습니다.

관련 문제