Notes on signal control in Java

Notes on signal control in Java

If you use a Java application in combination with OSS created in another language, an hs_err_pid file may be created and abnormal termination may occur, resulting in unintended behavior. Most of the bugs are very simple, but I'll keep a note of them as they could be caused by a conflict between the JavaVM and OSS signal handlers.

Relationship between Java and signals

JavaVM seems to judge the instruction being executed and map it to NullPointerException etc. when the signal of SIGSEGV, SIGBUS, SIGFPE, SIGPIPE, SIGILL occurs. However, if you overwrite these signal handlers with OSS or your own library, the signal originally generated in Java will be interpreted by OSS without permission, which will lead to unintended operation.

Workaround

Aside from my own library, it is difficult to modify core parts such as OSS signal control. As a Java function, a mechanism (signal chain) that does not rewrite the signal handler is provided.

Signal chain library registration


export LD_PRELOAD=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.201.b09-2.el7_6.x86_64/jre/lib/amd64/libjsig.so

Simply launch your Java application after this setup.

Commentary

Signal handlers are registered with system calls such as signal and sigaction. Setting the LD_PRELOAD environment variable to libjsig.so ensures that these system calls are registered via the function of the same name implemented in libjsig.so and do not override the signal handler registered by the Java VM. As a result, when a signal is generated, the Java VM signal handler operates preferentially, and if it is not a signal generated in Java, the processing is chained to the signal handler registered in OSS or the like.

Case study

When using R language from Java using rJava

A sequence for registering R language signal handlers from rJava.

Rengine()                                    # rJava: jri/Rengine.java
-> Java_org_rosuda_JRI_Rengine_rniSetupR()   # rJava: jri/src/Rengine.c
   -> initR()                                # rJava: jri/src/Rinit.c
      -> setup_Rmainloop()                   # R: src/main/main.c
         -> init_signal_handlers()           # R: src/main/main.c(Signal handler registration section)

c:src/main/main.c(R-3.6.0)


static void init_signal_handlers(void)
{
    /* <FIXME> may need to reinstall this if we do recover. */
    struct sigaction sa;
    signal_stack = malloc(SIGSTKSZ + R_USAGE);
    if (signal_stack != NULL) {
        sigstk.ss_sp = signal_stack;
        sigstk.ss_size = SIGSTKSZ + R_USAGE;
        sigstk.ss_flags = 0;
        if(sigaltstack(&sigstk, NULL) < 0)
            warning("failed to set alternate signal stack");
    } else
        warning("failed to allocate alternate signal stack");
    sa.sa_sigaction = sigactionSegv;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
    sigaction(SIGSEGV, &sa, NULL);
    sigaction(SIGILL, &sa, NULL);
#ifdef SIGBUS
    sigaction(SIGBUS, &sa, NULL);
#endif

    signal(SIGINT,  handleInterrupt);
    signal(SIGUSR1, onsigusr1);
    signal(SIGUSR2, onsigusr2);
    signal(SIGPIPE, handlePipe);
}

As a result, the signal handler required for controlling the Java VM is overwritten, and the Java VM cannot operate properly.

No signal chain

  1. JavaVM registers a signal handler
  2. Load R language from rJava
  3. R language registers signal handler --Overwrite JavaVM signal handler! !!

There is a signal chain

  1. Register the signal chain library with LD_PRELOAD
  2. JavaVM registers a signal handler --Register via signal chain library
  3. Load R language from rJava
  4. R language registers signal handler --Chained and registered behind the Java VM handler by signal chain. --Signals to be processed by the JavaVM are processed by the JavaVM handler, and other signals are processed by the chained handler.

hs_err_pid log file

Be careful if signal handlers other than libjvm.so are registered in the "Signal Handlers" section of hs_err_pid .log created when a Java application crashes. (In the example below, libNative.so is a user-defined signal handler)

Signal Handlers:
SIGSEGV: [libjvm.so+0xade3c0], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGBUS: [libjvm.so+0xade3c0], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGFPE: [libNative.so+0x7d5], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO
SIGPIPE: [libNative.so+0x7d5], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO
SIGXFSZ: [libjvm.so+0x8ce930], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGILL: [libNative.so+0x7d5], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO
SIGUSR1: SIG_DFL, sa_mask[0]=00000000000000000000000000000000, sa_flags=none
SIGUSR2: [libjvm.so+0x8ce7e0], sa_mask[0]=00000000000000000000000000000000, sa_flags=SA_RESTART|SA_SIGINFO
SIGHUP: [libjvm.so+0x8ce9f0], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGINT: [libjvm.so+0x8ce9f0], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGTERM: [libjvm.so+0x8ce9f0], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO
SIGQUIT: [libjvm.so+0x8ce9f0], sa_mask[0]=11111111011111111101111111111110, sa_flags=SA_RESTART|SA_SIGINFO

reference

Recommended Posts

Notes on signal control in Java
Upload and download notes in java on S3
Java version control on macOS
Notes on how to use regular expressions in Java
java notes
Notes on Android (java) thread processing
Notes on Java path and Package
Notes on operators using Java ~ String type ~
Output Notes document as XML document in Java
Java version control with jenv on OSX
Notes on JSP extension tags in SpringFrameWork
Java control syntax
Java control syntax
Partization in Java
Java Generics (Notes)
Changes in Java 11
[Java] Array notes
Rock-paper-scissors in Java
[Java] Study notes
Java serialization notes
Pi in Java
FizzBuzz in Java
Organized memo in the head (Java --Control syntax)
Deserialize CSV in Java based on header name
Notes on how to write comments in English
Notes on implementing google books api in java okhttp and gson versions and okhttp and jackson versions
[java] sort in list
Read JSON in Java
Interpreter implementation in Java
Make Blackjack in Java
Let's touch on Java
Rock-paper-scissors app in Java
Notes on Protocol Buffers
Constraint programming in Java
Put java8 in centos7
[Java] Stream Collectors notes
Java formatted output [Notes]
Combine arrays in Java
"Hello World" in Java
Callable Interface in Java
Install Java on Mac
Comments in Java source
[Android] Notes on xml
Azure functions in java
Run PostgreSQL on Java
Format XML in Java
Notes on multiple inheritance
Java NIO 2 review notes
Simple htmlspecialchars in Java
Notes on regular expressions
Boyer-Moore implementation in Java
Hello World in Java
Use OpenCV in Java
webApi memorandum in java
Type determination in Java
Ping commands in Java
Various threads in java
Heapsort implementation (in java)
Zabbix API in Java
ASCII art in Java
Compare Lists in Java