Java-Kern: HotSpot-Compiler stürzt unter SIGSEGV ab

HotSpot Compiler

Zunächst wird Java VM ausgeführt und ausgeführt, indem der als Interpreter auszuführende Code ausgeführt wird. Die Ausführung erfolgt jedoch durch Kompilieren häufig ausgeführter Teile (-XX: CompileThreshold = 10000 oder mehr auf Server VM) in die native Maschinensprache. Beschleunigt. Eine der Ursachen für den Absturz von Java VM ist, dass ein Fehler in diesem HotSpot-Compiler dazu führt, dass der SIGSEGV + Core-Dump abstürzt, wenn versucht wird, die Zielmethode zu kompilieren.

hs_error_log

Zusammen mit dem Core-Dump werden normalerweise hs-Fehlerprotokolldateien wie hs_error_log oder hs_err_pid1234.log ausgegeben. Diese Protokolldatei enthält wichtige Informationen, z. B. welche Methode der HotSpot-Compiler zu kompilieren versuchte und zu einem Abbruch führte.

Die Standardausgabe endet mit einem Fehler wie unten gezeigt.

# ulimit -c unlimited
# /usr/libexec/tomcat/server start

# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00007f5073f646c0, pid=15045, tid=139983466055424
#
# JRE version: OpenJDK Runtime Environment (7.0_141-b02) (build 1.7.0_141-mockbuild_2017_06_13_12_10-b00)
# Java VM: OpenJDK 64-Bit Server VM (24.141-b02 mixed mode linux-amd64 compressed oops)
# Derivative: IcedTea 2.6.10
# Distribution: Red Hat Enterprise Linux Server release 7.3 (Maipo), package rhel-2.6.10.5.el7-x86_64 u141-b02
# Problematic frame:
# V  [libjvm.so+0x8446c0]
#
# Core dump written. Default location: /usr/share/tomcat/core or core.15045
#
# An error report file with more information is saved as:
# /tmp/jvm-15045/hs_error.log
#
# If you would like to submit a bug report, please include
# instructions on how to reproduce the bug and visit:
#   http://icedtea.classpath.org/bugzilla
#
Stornieren(Core-Dump)

Sie können anhand des folgenden Teils der hs-Fehlerprotokolldatei sehen, welche Methode der HotSpot-Compiler zu kompilieren versucht hat und abgestürzt ist:

# vi /tmp/jvm-15045/hs_error.log
...Unterlassung... 
Current CompileTask:
C2: 205800  155             org.apache.tomcat.util.buf.ByteChunk::recycle (21 bytes)
...

Da wir die Ausgabe des Kerns zum Testen erzwingen, führt diese Methode normalerweise nicht zu einem Kernspeicherauszug. Aus dem obigen Ausgabeergebnis ist die Methode in der Spalte CompileTask: die Zielmethode.

Mit Problemen umgehen

Um solche Probleme mit dem HotSpot-Compiler zu vermeiden, können Sie dies vermeiden, indem Sie die zu kompilierende Methode aus dem HotSpot-Compiler ausschließen. Erstellen Sie beim Starten von Java eine .hotspot_compiler-Datei im aktuellen Arbeitsverzeichnis. Die Java-VM liest diese Datei beim Start. Danach wird die angegebene Methode nicht mehr mit HotSpot kompiliert.

# vi .hotspot_compiler
exclude org/apache/tomcat/util/buf/ByteChunk recycle

Die meisten Gründe, warum der HotSpot-Compiler auf SIGSEGV abgestürzt ist, sind Fehler in Java VM. Es ist jedoch sehr schwierig, dasselbe Abbruchereignis in einer anderen Umgebung zu reproduzieren. Selbst wenn Sie sich an den Java VM-Support wenden, kann die Ursache nicht sofort geklärt werden und es kann nicht erwartet werden, dass sie behoben wird, wenn es sich um ein neues Problem handelt, das noch nie zuvor aufgetreten ist. Stellen Sie zu diesem Zeitpunkt fest, ob es in der neuesten Java-VM erneut auftritt. Wenn es in der neuesten Version auftritt, senden Sie die Kerndatei, die verknüpfte Bibliothek, das hs-Fehlerprotokoll usw. an das Support-Fenster mit der Erwartung, dass es in Zukunft behoben wird. Ich denke, es wird zur Verfügung gestellt. In einer Produktionsumgebung sollten Sie zuerst .hotspot_compiler festlegen, um Probleme zu vermeiden.

Überprüfen Sie den Namen der Zielmethode in der Kerndatei

Möglicherweise geraten Sie in eine unglückliche Situation, in der Sie nur die Java-Kerndatei zur Hand haben, z. B. "Ich habe vergessen, die hs-Fehlerdatei abzurufen" oder "Ich habe sie bereits gelöscht". Auch in diesem Fall ist es möglich, den Zielklassennamen und den Methodennamen aus der Kerndatei zu überprüfen.

Unten bestätigt in RHEL 7.4 Java 1.7.0_141-Umgebung

$  gdb /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/jre-abrt/bin/java /usr/share/tomcat/core.15045
...Unterlassung...
(gdb) bt
#0  0x00007f50747b01f7 in raise () from /lib64/libc.so.6
#1  0x00007f50747b18e8 in abort () from /lib64/libc.so.6
#2  0x00007f5073f18de9 in os::abort (dump_core=<optimized out>) at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/os/linux/vm/os_linux.cpp:1635
#3  0x00007f50740a7bcf in VMError::report_and_die (this=this@entry=0x7f5070c49bd0)
    at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/share/vm/utilities/vmError.cpp:1074
#4  0x00007f5073f21ff7 in JVM_handle_linux_signal (sig=11, info=0x7f5070c49e30, ucVoid=0x7f5070c49d00, abort_if_unrecognized=<optimized out>)
    at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp:531
#5  <signal handler called>
#6  0x00007f5073f646c0 in Phase::Phase (this=0x0, pnum=Phase::Compiler)
    at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/share/vm/opto/phase.cpp:83
#7  0x00007f5073b78711 in Compile::Compile (this=0x0, ci_env=0x7f5070c4ba40, compiler=0x7f506c072730, target=0x7f503c0ba4f0, osr_bci=-1, subsume_loads=<optimized out>, 
    do_escape_analysis=true, eliminate_boxing=true) at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/share/vm/opto/compile.cpp:683
#8  0x00007f5073ae3d30 in C2Compiler::compile_method (this=0x7f506c072730, env=0x7f5070c4ba40, target=0x7f503c0ba4f0, entry_bci=-1)
    at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/share/vm/opto/c2compiler.cpp:137
#9  0x00007f5073b7f788 in CompileBroker::invoke_compiler_on_method (task=task@entry=0x7f506c1595c0)
    at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/share/vm/compiler/compileBroker.cpp:1761
#10 0x00007f5073b80b00 in CompileBroker::compiler_thread_loop ()
    at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/share/vm/compiler/compileBroker.cpp:1597
#11 0x00007f5074059cfa in JavaThread::thread_main_inner (this=this@entry=0x7f506c0a8800)
    at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/share/vm/runtime/thread.cpp:1687
#12 0x00007f507405a07f in JavaThread::run (this=0x7f506c0a8800)
    at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/share/vm/runtime/thread.cpp:1667
#13 0x00007f5073f17de2 in java_start (thread=0x7f506c0a8800) at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/os/linux/vm/os_linux.cpp:910
#14 0x00007f5074f57e25 in start_thread () from /lib64/libpthread.so.0
#15 0x00007f507487334d in clone () from /lib64/libc.so.6
(gdb)

Es sollte eine C2Compiler :: compile_method-Funktion wie Frame # 8 im obigen Kompilierungsthread geben. Die zu kompilierende Methode wird in diesem dritten Argument als target = 0x7f503c0ba4f0 angegeben. Überprüfen Sie von diesem Ziel aus den Klassennamen und den Methodennamen.

python


(gdb) frame 8
#8  0x00007f5073ae3d30 in C2Compiler::compile_method (this=0x7f506c072730, env=0x7f5070c4ba40, target=0x7f503c0ba4f0, entry_bci=-1)
    at /usr/src/debug/java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64/openjdk/hotspot/src/share/vm/opto/c2compiler.cpp:137
137         Compile C(env, this, target, entry_bci, subsume_loads, do_escape_analysis, eliminate_boxing);
(gdb)
(gdb) p ({ciMethod}0x7f503c0ba4f0)->_name
$1 = (ciSymbol *) 0x7f503c0ba590
(gdb) p ({ciSymbol}0x7f503c0ba590)->_symbol
$2 = (Symbol *) 0x7f506c4fdb10
(gdb) p &({Symbol}0x7f506c4fdb10)->_body
$3 = (signed char (*)[1]) 0x7f506c4fdb1a
(gdb) x/s 0x7f506c4fdb1a
0x7f506c4fdb1a: "recycle"
(gdb) 

Methodenname"recycle"war.

(gdb) p ({ciMethod}0x7f503c0ba4f0)->_holder
$21 = (ciInstanceKlass *) 0x7f503c0ba5a0
(gdb) p ({ciInstanceKlass}0x7f503c0ba5a0)->_name
$22 = (ciSymbol *) 0x7f503c0ba630
(gdb) p ({ciSymbol}0x7f503c0ba630)->_symbol
$23 = (Symbol *) 0x7f506c529af0
(gdb) p &({Symbol}0x7f506c529af0)->_body
$24 = (signed char (*)[1]) 0x7f506c529afa
(gdb) x/s 0x7f506c529afa
0x7f506c529afa: "org/apache/tomcat/util/buf/ByteChunk"
(gdb) 

Name der Klasse"org/apache/tomcat/util/buf/ByteChunk"war.

Es war eine tastende Bestätigung, aber es war mühsam, also schrieb ich ein einfaches Python-Skript. https://github.com/takimai39/gdb-java

(gdb) source target.py
(gdb) target 0x7f503c0ba4f0
exclude org/apache/tomcat/util/buf/ByteChunk recycle
(gdb) 

Ich hoffe, Sie finden es nützlich.

Recommended Posts

Java-Kern: HotSpot-Compiler stürzt unter SIGSEGV ab
Java-Kern: HotSpot-Compiler und C-Heap
[Java] Einen Fehler im JDK-Compiler beheben
Installieren Sie Java auf dem Mac
Führen Sie PostgreSQL unter Java aus
Java Core: gehackte Core-Datei
Brainfuck-> Java Byte Code Compiler