2017-04-11 86 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。 –