2017-04-11 2 views
1

Ich benutze GDB, um C-Code zu debuggen, der von Java aufgerufen wird. Ich füge die gdb an laufenden Java-Prozess an und es funktioniert. Etwas. Die Kuriosität ist, dass GDB regelmäßig SIGSEGV meldet und Java nicht zum Absturz bringt. Ich würde erwarten, dass die JVM heruntergeht und hs_err_pid mit Informationen über den Fehler generiert. Ich frage mich, ob diese Fehler tatsächlich von gdb (keine Ahnung wie) verursacht werden und nicht wirklich im laufenden Code auftreten, oder ob Java unter bestimmten Umständen von SIGSEGV wiederherstellen kann (keine Ahnung wie).Kann ein SIGSEGV in Java die JVM nicht zum Absturz bringen?

EDIT: Hier ist voll gdb Ausgang: https://pastebin.com/Mk44kWXQ

Beispiel:

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

Ich denke, das ist zu vage. Wenn Sie den vollständigen Terminal-Dump der gdb-Sitzung einschließen würden, könnte dies die Rechenschaftspflicht erhöhen. – unwind

+0

Wenn die Java-VM den C-Code in einer separaten Sandbox ausführt, kann ein Seg-Fehler in der Sandbox die Java VM nicht zum Absturz bringen. –

+0

@PaulOgilvie - Ich habe noch nie von einer Java-Implementierung gehört, die das getan hat. Es würde den Wechsel zwischen C und Java teuer machen und (zu einem wesentlichen Grad) den Zweck des Aufrufs von C aus Java zunichtemachen. –

Antwort

3

Kann ein SIGSEGV in Java nicht die JVM abstürzen?

Sicher, wenn ein SIGSEGV auftritt, während der Ausführung von Java-Code (nicht nativen Code) es höchstwahrscheinlich eine Java zu dereferencing null zurückzuführen ist. Das kann gefangen und in eine NullPointerException umgewandelt und "geworfen" werden. Eine Anwendung kann davon wiederherstellen; d.h. durch "Fangen" der Ausnahme.

Ich denke, dass ein SIGSEGV auch durch einen Java-Stack-Überlauf ausgelöst werden könnte, der Java-Code zum Lesen oder Schreiben einer Adresse in einem "roten Bereich" Speichersegment eines Stapels verursacht.

Irgendwie gibt es definitiv Szenarien, in denen der SIGSEGV-Signalhandler der JVM das SIGSEGV-Ereignis in eine Java-Ausnahme umwandeln kann. Sie werden nur einen schweren JVM-Absturz bekommen, wenn das nicht passieren kann; z.B. wenn der Thread, der SIGSEGV ausgelöst hat, Code in einer systemeigenen Bibliothek ausgeführt hat, als das Ereignis passiert ist.

+0

OK, es könnte also eine normale Java NullPointerException oder ein internes JVM-Problem auftreten. Ich wusste nicht, dass NPEs von segfault gestartet wurden, ich nahm an, dass JVM vor der Dereferenzierung eine Überprüfung durchführt. Vielen Dank. – Novotny

+1

Es ist tatsächlich implementierungsabhängig, wie die JVM Dereferenzierung von Nullen erkennt. Es gibt verschiedene mögliche Strategien, und ich würde erwarten, dass ein JIT-Compiler verschiedene Strategien in verschiedenen Kontexten wählt. Eine Strategie besteht darin, auf Null zu prüfen, eine andere besteht darin, SIGSEGV abzufangen. –

Verwandte Themen