Si vous utilisez une application Java en combinaison avec OSS créé dans un autre langage, un fichier hs_err_pid peut être créé et provoquer une opération involontaire telle qu'une interruption anormale. La plupart des bogues sont très simples, mais je vais en prendre note car ils pourraient être causés par un conflit entre les gestionnaires de signaux JavaVM et OSS.
Lorsque JavaVM signale SIGSEGV, SIGBUS, SIGFPE, SIGPIPE et SIGILL, il semble juger l'instruction en cours d'exécution et la mapper à NullPointerException. Cependant, si vous écrasez ces gestionnaires de signaux avec OSS ou votre propre bibliothèque, le signal généré à l'origine par Java sera interprété par OSS sans autorisation, ce qui entraînera une opération involontaire.
Mis à part ma propre bibliothèque, il est difficile de modifier des éléments essentiels tels que le contrôle du signal OSS. En tant que fonction Java, un mécanisme (chaîne de signaux) qui ne réécrit pas le gestionnaire de signaux est fourni.
Enregistrement de la bibliothèque de chaînes de signaux
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
Lancez simplement l'application Java après cette configuration.
Les gestionnaires de signaux sont enregistrés avec les appels système tels que signal et sigaction. La définition de la variable d'environnement LD_PRELOAD sur libjsig.so garantit que ces appels système sont enregistrés via la fonction du même nom implémentée dans libjsig.so et ne remplacent pas le gestionnaire de signaux enregistré par JavaVM. En conséquence, lorsqu'un signal est généré, le gestionnaire de signal JavaVM fonctionne de préférence, et si le signal n'est pas généré en Java, le traitement est enchaîné au gestionnaire de signal enregistré dans OSS ou similaire.
Une séquence pour enregistrer un gestionnaire de signaux en langage R depuis 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(Section d'enregistrement du gestionnaire de signaux)
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);
}
Cela écrase le gestionnaire de signaux requis pour contrôler JavaVM, ce qui empêche JavaVM de fonctionner correctement.
Faites attention si des gestionnaires de signaux autres que libjvm.so sont enregistrés dans la section "Gestionnaires de signaux" de 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, Guide de dépannage de l'édition Standard> 7 Gestion des signaux et des exceptions
Un simple exemple de JNI (un programme qui affiche Hello World)
Recommended Posts