java - 如何触发默认信号处理行为?

标签 java unix signals

在我的 Java 应用程序中,我想捕获 SIGINT,进行一些预处理,然后让默认行为(进程终止)运行。我想我可以做这样的事情:

Signal.handle(new Signal("INT"), new SignalHandler() {
  @Override
  public void handle(Signal signal) {
    // preprocessing
    // ...

    // now do default behavior
    SignalHandler.SIG_DFL.handle(signal);
  }
});

然而,当我向这个应用程序发送 SIGINT 时,我得到一个 SEGV:

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x0000000000000000, pid=10261, tid=21507
#
# JRE version: Java(TM) SE Runtime Environment (8.0_51-b16) (build 1.8.0_51-b16)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.51-b03 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# C  0x0000000000000000
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /private/tmp/hs_err_pid10261.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Abort trap: 6

看来 SignalHandler.SIG_DFL 并不意味着要直接调用(即使是从其他信号处理代码)。那么如何手动触发呢?

或者,我如何手动复制 SIG_DFL 的行为?它似乎等同于:

System.exit(signal.getNumber() + 128)

但我没有看到任何与此相关的文档。


表达我的问题的另一种方式:

实际上*这两个代码块之间有区别吗?

一个)

Signal.handle(new Signal("INT"), SignalHandler.SIG_DFL);

B)

Signal.handle(new Signal("INT"), new SignalHandler() {
  @Override
  public void handle(Signal signal) {
    System.exit(signal.getNumber() + 128)
  }});

*我知道未记录的行为可能随时发生变化,但 JVM 的退出行为不太可能在版本中期发生变化。在实践中,简单详细说明现在发生的事情的答案是可以接受的。

最佳答案

我认为这里的谜团的关键是 SIG_DFL 不是 SIGINT 的原始处理程序。

以下代码对我有用:

    Signal sigInt = new Signal("INT");

    // First register with SIG_DFL, just to get the old handler.
    final SignalHandler oldHandler = Signal.handle(sigInt, SignalHandler.SIG_DFL );

    // Now register the actual handler
    Signal.handle(sigInt, new SignalHandler(){

        @Override
        public void handle(Signal signal) {
            System.err.println("Sigint is being handled");
            oldHandler.handle(signal);
        }

    });

这不会导致分段冲突,而是按预期终止程序(在打印示例文本后)。

关于java - 如何触发默认信号处理行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32190311/

相关文章:

java - Spring-Boot 兼容内存数据库,支持字符串数组(String[])数据类型

shell - 在服务器上作为后台进程运行 java jar 文件

shell - 通过删除最后 n 个字符来重命名文件

c - Linux 上的简单 pthreads 和信号程序不会运行

c - 确定哪个信号中断了我的系统调用 (Linux)

java - 在 Java 上运行 JTape 库(java 库路径)

java - MATLAB java.util 是否有非 HashMap /集?

java - 使用扫描仪拆分字符串

c - 那里有软件缓存 API 吗?

c - 如果 sigwait() 阻塞,什么时候接受的信号实际上是 "selected"?