2016-07-08 7 views
6

컨텍스트 : 나는 실수로 파이프가 새는 Java 기반 네트워크 서버에서 작업 중입니다. 며칠에 한 번씩 40,000 개의 파일 설명자를 제한하여 죽습니다. 사망하기 전에 서버에서 lsof을 사용하면 파이프로 막혔습니다. 파이프는 다른 프로세스가 아닌 자체에 연결됩니다.특정 시스템 호출이있을 때 java 스택 추적 기록?

코드베이스의 어떤 부분도 파이프를 생성하거나 사용하지 않습니다.

일부 이전 버전의 JVM에서는 소켓을 만들 때 & 파이프가 누출되었지만이 버그는 Java 1.7.0_75에서 나타납니다.

내 질문은입니다 : 현대 리눅스 툴 체인을, (예 퍼포 레이션)를 사용하기는 pipe(2) 시스템 콜 호출 할 때 가능 과정을 스냅 샷입니다 - 내가 파이프를 생성하는 유일한 방법입니다 생각합니다. 게다가, 그때부터 자바 스택 추적을 검색 할 수 있습니까?

이 정보가 주어지면 "누가 파이프를 만들고 있습니까?"라는 질문에 대답 할 수 있어야합니다.

+0

난 당신이'Selectors'를 유출하는 제안을 포함하여이 작업을 수행하는 방법에 대한 다양한 가이드가

있습니다. – EJP

+0

LD_PRELOAD를 사용하여'pipe'를 자신의 함수로 대체하는 것을 고려하십시오. – Nykakin

+0

@EJP - 매혹적인 아이디어. 어떻게하면 구체적인 진단을 내릴 수 있습니까? –

답변

3

Java 1.7.0_75 (또는 pre-java 8 update 60)에서는 스택이 잘 리게 (아래 참조)되기 때문에 이벤트의 호출 스택에서 perf로부터 제한된 정보 만 얻을 수 있습니다.

시스템 콜 트레이스 이벤트를 파이프로 보내고 다음 perf 명령 또는 이와 유사한 방법으로 닫을 수 있습니다. 생산 실행하기 전에 테스트 시스템에

  1. 테스트 :
    perf record -e 'syscalls:sys_enter_pipe*' -e 'syscalls:sys_enter_close' -ag -- sleep 10 
    

    전체 스택을 얻으려면.
  2. 자바 8 업데이트 60 이상을 설치
  3. -XX와
  4. 실행 자바 : + PreserveFramePointer 잘립니다 스택
  5. 선택적으로 방지하기 위해 (그대로 생산 준비 코드가 아닙니다) 설치에 Github에서에서 반환 한 -지도 - 에이전트를 실행 문제가 출력에 트레이스 이벤트와 관련된 스택을
  6. 실행 "을 반환 한 스크립트를"발생하는 경우 또는 이와 유사한 "레코드 반환 한"퍼포 레이션의 사용
  7. 실행 위의 자바 JIT 기호를 해결

절두 스택 추적 ~ 할 것이다 반환 한이를 해결할 수 있도록 반환 한 -지도 - 에이전트

java 21553 [009] 10601254.522385: syscalls:sys_enter_pipe: fildes: 0x7f545322f340 
     7f54527180b7 __pipe (/usr/lib64/libc-2.17.so) 
     7f543d007760 [unknown] (/tmp/perf-21552.map) 
     7f543d0007a7 [unknown] (/tmp/perf-21552.map) 
     7f5451ce1be6 JavaCalls::call_helper (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5451fe7b27 Reflection::invoke (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5451feb237 Reflection::invoke_method (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5451d705fb JVM_InvokeMethod (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f543da669ed [unknown] (/tmp/perf-21552.map) 
     7f543d0007a7 [unknown] (/tmp/perf-21552.map) 
     7f5451ce1be6 JavaCalls::call_helper (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5451d23182 jni_invoke_static (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5451d3fb8a jni_CallStaticVoidMethod (/usr/java/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so) 
     7f5452bfcbcc JavaMain (/usr/java/jdk1.8.0_60/jre/lib/amd64/jli/libjli.so) 
     7f5452e12df5 start_thread (/usr/lib64/libpthread-2.17.so) 

실행 :

java 19575 [018] 10600910.346655: syscalls:sys_enter_pipe: fildes: 0x7f353b9f7f80 
     7f3809cff0b7 __pipe (/usr/lib64/libc-2.17.so) 
     7f37f59aecb9 [unknown] (/tmp/perf-19375.map) 
     7f37f5e83150 [unknown] (/tmp/perf-19375.map) 
    edb4639ef8034082 [unknown] ([unknown]) 

전체 스택이 더 좋아 보일 수 있습니다 : 예를 들어 바닥에 나사 스타트 기능이없는 하나가 될 Java 메소드에 JITted [unknown] 함수. 브렌든 그레그의 작품 http://techblog.netflix.com/2015/07/java-in-flames.html