2017-04-11 1 views
1

Java에서 호출되는 C 코드를 디버깅하기 위해 gdb를 사용하고 있습니다. gdb를 실행중인 Java 프로세스에 연결하면 작동합니다. 약간. 골칫거리는 GDB가 SIGSEGV를 주기적으로보고하고 있으며 Java를 중단시키지 않는다는 것입니다. JVM이 내려 가서 오류에 대한 정보로 hs_err_pid를 생성 할 것으로 기대합니다. 나는 그 결함이 gdb (실제로는 아무 생각도 없음)에 의해 실제로 발생하고 실행중인 코드에서 실제로 발생하지 않는지 궁금하거나 자바가 SIGSEGV (어떤 생각이 들지도)에서 복구 할 수있는 경우도 있습니다.Java에서 SIGSEGV가 JVM을 크래시 할 수 있습니까?

편집 : 여기에 전체 GDB 출력은 다음과 같습니다 https://pastebin.com/Mk44kWXQ

예 :

Thread 
52 "java" received signal SIGSEGV, Segmentation fault. 
0x00007f9f3a93d4b1 in ??() 
-exec-continue 
[New Thread 0x7f9ea4b46700 (LWP 10135)] 
[New Thread 0x7f9eb4079700 (LWP 10137)] 
[Thread 0x7f9eac95e700 (LWP 10130) exited] 

Thread 
52 "java" received signal SIGSEGV, Segmentation fault. 
0x00007f9f3a93d4b1 in ??() 
-exec-continue 
[Thread 0x7f9ea534c700 (LWP 9960) exited] 
+0

너무 모호합니다. gdb 세션의 전체 터미널 덤프를 포함한다면 더 많은 책임이있을 수 있습니다. – unwind

+0

Java VM이 별도의 샌드 박스에서 C 코드를 실행하면 샌드 박스의 seg 오류로 인해 Java VM이 중단되지 않습니다. –

+0

@PaulOgilvie - 그 일을 한 Java 구현에 대해 들어 본 적이 없습니다. 그것은 C와 자바 사이의 전환을 비싸게 만들 것이고, (상당한 정도까지) Java에서 C를 호출하는 목적을 무효로 만들 것입니다. –

답변

3

자바에서 SIGSEGV가 아니라 JVM 충돌 할 수 있습니까?

물론,이 때문에 자바 null를 역 참조 가능성이 가장 높은 Java 코드 (네이티브 코드가 아닌)를 실행하는 동안 SIGSEGV가 발생했을 경우. 그것은 갇혀서 NullPointerException으로 바뀌어 "던져 질"수 있습니다. 응용 프로그램은 이것으로부터 복구 할 수 있습니다. 즉 예외를 "포착"합니다.

SIGSEGV는 Java 스택 오버플로에 의해 트리거되어 Java 코드가 스택의 "빨간색 영역"메모리 세그먼트에서 주소를 읽거나 쓸 수 있다고 생각합니다.

아무튼 JVM의 SIGSEGV 신호 처리기가 SIGSEGV 이벤트를 Java 예외로 변환시킬 수있는 시나리오가 있습니다. JVM 하드 크래시가 발생하지 않는 경우에만 JVM 충돌이 발생합니다. 예 : 이벤트가 발생했을 때 SIGSEGV를 트리거 한 스레드가 원시 라이브러리에서 코드를 실행하고있는 경우.

+0

보통 Java NullPointerException이 발생하거나 내부 JVM이 될 수 있습니다. 나는 NPE가 segfault에 의해 시작되었다는 것을 몰랐습니다. JVM이 역 참조하기 전에 검사를 수행한다고 가정했습니다. 감사. – Novotny

+1

실제로는 구현에 따라 JVM에서 null의 역 참조를 감지합니다. 가능한 전략은 다양합니다. JIT 컴파일러가 다른 상황에서 다양한 전략을 선택할 것으로 기대합니다. 하나의 전략은 null을 테스트하는 것이고, 또 하나는 SIGSEGV를 잡는 것이다. –

관련 문제