2016-07-08 15 views
6

Der Kontext: Ich arbeite an einem Java-basierten Netzwerk-Server, der versehentlich Rohre leckt. Alle paar Tage erreicht es sein Limit von 40.000 Dateideskriptoren und stirbt. Mit lsof auf dem Server vor dem Tod zeigt es mit Rohren erstickt ist. Die Rohre verbinden sich mit sich selbst und nicht mit einem anderen Prozess.Aufzeichnung der Java-Stack-Trace bei einem bestimmten Systemaufruf?

Kein Teil der Codebasis erstellt oder verwendet Rohre - das können wir sehen.

Einige ältere Version der JVM haben erstellt & durchgesickert ein Rohr beim Erstellen eines Sockels, jedoch zeigt dies auf Java 1.7.0_75, die ich glaube, dass nicht diesen Bug leiden.

Meine Frage ist: die moderne Toolchain Linux verwenden (wie perf) ist es möglich, den Prozess Snapshot, wenn es die pipe(2) Systemaufruf ruft - die meiner Meinung nach ist die einzige Möglichkeit, Rohre erzeugt werden. Ist es außerdem möglich, einen Java-Stack-Trace von diesem zu erhalten?

Angesichts dieser Informationen sollte es möglich sein, die Frage zu beantworten "Wer schafft Rohre, und warum?"

+0

Ich schlage vor, Sie sind undicht 'Selectors'. – EJP

+0

Verwenden Sie LD_PRELOAD, um "pipe" durch eine eigene Funktion zu ersetzen. – Nykakin

+0

@EJP - eine faszinierende Idee. Wie könnten Sie daraus eine konkrete Diagnose machen? –

Antwort

3

Auf Java 1.7.0_75 (oder vor Java 8 Update 60) können Sie nur begrenzte Informationen von perf auf dem Aufruf-Stack eines Ereignisses erhalten, da der Stapel abgeschnitten wird (siehe unten).

Sie können systemweite Tracepoint-Ereignisse bei Sys-Aufrufen an pipe abrufen und mit dem folgenden perf-Befehl oder ähnlichem schließen.

perf record -e 'syscalls:sys_enter_pipe*' -e 'syscalls:sys_enter_close' -ag -- sleep 10 

Um den vollständigen Stapel zu erhalten:

  1. -Test auf einem Testsystem vor in der laufenden Produktion.
  2. Installieren Java 8 Update 60 oder höher
  3. Run Java mit -XX: + PreserveFramePointer verkürzten Stapel
  4. Optional zu vermeiden installieren und ausführen perf-map-Agenten von Github (da es nicht Produktion bereit-Code ist) zu Java JIT-Symbole für die Verwendung des perf lösen
  5. Führen Sie das oben „perf record“ oder ähnlich, wenn das Problem auftritt, wird
  6. Run „perf Skript“, um die Tracepoint Ereignisse Ausgang und die damit verbundenen Stapel Spuren

ein verkürztes Stapel werden eine, die Thread-Start-Funktion am unteren Rand für nicht Beispiel haben:

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]) 

Ein voller Stapel wie aussehen kann:

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) 

Run mit perf-map-Agent perf, damit die lösen JITted [unbekannt] Funktionen zu Java-Methoden.

Es gibt verschiedene andere Führer auf, wie dies mit Brendan Gregg Arbeit zu tun http://techblog.netflix.com/2015/07/java-in-flames.html

Verwandte Themen