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.
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.
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.
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.
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.
Be careful if signal handlers other than libjvm.so are registered in the "Signal Handlers" section of hs_err_pid
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
Java Platform, Standard Edition Troubleshooting Guide> 7 Handling Signals and Exceptions
A simple sample of JNI (a program that displays Hello World)
Recommended Posts