2017-04-11 13 views
1

我正在使用gdb來調試C代碼,這是從Java調用的。我將gdb附加到正在運行的Java進程並且它可以工作。有些。古怪的事情是GDB定期報告SIGSEGV,它不會使Java崩潰。我希望JVM能夠關閉並生成hs_err_pid,並提供有關錯誤的信息。我想知道如果這些錯誤實際上是由gdb引起的(不知道如何),並且不會真正發生在運行代碼中,或者在某些情況下Java可以從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之間的切換非常昂貴,並且(在很大程度上)會失去從Java調用C的目的。 –

回答

3

可以在Java中的SIGSEGV不會崩潰的JVM?

當然,如果在執行Java代碼(不是本機代碼),這是最有可能是由於提領一個Java null發生SIGSEGV。這可以被困住並變成NullPointerException和「拋出」。應用程序可以從中恢復;即通過「捕捉」例外。

我認爲SIGSEGV也可能被Java堆棧溢出觸發,導致Java代碼讀取或寫入堆棧的「紅色區域」內存段中的地址。

無論如何,肯定會出現JVM的SIGSEGV信號處理程序可能會將SIGSEGV事件轉化爲Java異常的情況。如果無法實現,您將只會遇到JVM嚴重崩潰;例如如果觸發SIGSEGV的線程在事件發生時正在本機庫中執行代碼。

+0

好的,所以它可能是一個普通的Java NullPointerException發生,或者一些內部的JVM東西。我不知道NPE是由segfault啓動的,我假定JVM在解引用之前執行檢查。謝謝。 – Novotny

+1

它實際上取決於JVM如何檢測到空值解引用。有不同的可能策略,我希望JIT編譯器能夠在不同的上下文中選擇不同的策略。一個策略是測試null,另一個策略是捕獲SIGSEGV。 –