【问题标题】:Can a SIGSEGV in Java not crash the JVM?Java 中的 SIGSEGV 可以不使 JVM 崩溃吗?
【发布时间】:2017-09-06 19:22:39
【问题描述】:

我正在使用 gdb 调试从 Java 调用的 C 代码。我将 gdb 附加到正在运行的 Java 进程,它可以工作。有些。古玩的事情是 GDB 定期报告 SIGSEGV 并且它不会使 Java 崩溃。我希望 JVM 会关闭并生成带有错误信息的 hs_err_pid。我想知道这些错误是否实际上是由 gdb 引起的(不知道如何)并且不会真正发生在正在运行的代码中,或者在某些情况下 Java 是否可以从 SIGSEGV 中恢复(不知道如何)。

编辑:这是完整的 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]

【问题讨论】:

  • 我认为这太模糊了。如果您要包含 gdb 会话的完整终端转储,那可能会更容易回答。
  • 如果 Java 虚拟机在单独的沙箱中运行 C 代码,那么沙箱中的任何 seg 错误都不会导致 Java 虚拟机崩溃。
  • @PaulOgilvie - 我从未听说过这样做的 Java 实现。这将使 C 和 Java 之间的切换变得昂贵,并且(在很大程度上)破坏了从 Java 调用 C 的目的。

标签: java c debugging gdb segmentation-fault


【解决方案1】:

Java 中的 SIGSEGV 能否不使 JVM 崩溃?

当然,如果在执行 Java 代码(不是本机代码)时出现 SIGSEGV,很可能是由于取消了对 Java null 的引用。这可以被捕获并变成NullPointerException 并“抛出”。应用程序可以从中恢复;即通过“捕获”异常。

我认为 SIGSEGV 也可能由 Java 堆栈溢出触发,导致 Java 代码在堆栈的“红色区域”内存段中读取或写入地址。

无论如何,在某些情况下,JVM 的 SIGSEGV 信号处理程序可能会将 SIGSEGV 事件转换为 Java 异常。如果这不能发生,您只会遇到 JVM 硬崩溃;例如如果事件发生时触发 SIGSEGV 的线程正在执行本机库中的代码。

【讨论】:

  • 好的,所以它可能是一个正常的 Java NullPointerException 发生,或者是一些内部 JVM 的东西。我不知道 NPE 是由段错误启动的,我认为 JVM 在取消引用之前会执行检查。谢谢。
  • 它实际上取决于JVM如何检测空值的取消引用。有不同的可能策略,我希望 JIT 编译器在不同的上下文中选择不同的策略。一种策略是测试 null,另一种策略是捕获 SIGSEGV。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
  • 2016-07-06
相关资源
最近更新 更多