Remarques sur le contrôle du signal en Java

Remarques sur le contrôle du signal en Java

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.

Relation entre Java et les signaux

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.

solution de contournement

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.

Commentaire

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.

Étude de cas

Lors de l'utilisation du langage R à partir de Java avec rJava

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.

Pas de chaîne de signal

  1. JavaVM enregistre un gestionnaire de signaux
  2. Charger le langage R depuis rJava
  3. Gestionnaire de signaux de registres de langage R

Il y a une chaîne de signal

  1. Enregistrez la bibliothèque de chaînes de signaux avec LD_PRELOAD
  2. JavaVM enregistre un gestionnaire de signaux
  1. Charger le langage R depuis rJava
  2. Gestionnaire de signaux de registres de langage R

Fichier journal hs_err_pid

Faites attention si des gestionnaires de signaux autres que libjvm.so sont enregistrés dans la section "Gestionnaires de signaux" de hs_err_pid .log créé lorsqu'une application Java plante. (Dans l'exemple ci-dessous, libNative.so est un gestionnaire de signaux défini par l'utilisateur)

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

référence

Recommended Posts

Remarques sur le contrôle du signal en Java
Télécharger et télécharger des notes en java sur S3
Gestion des versions Java sur macOS
Remarques sur l'utilisation des expressions régulières en Java
note java
Remarques sur le traitement des threads Android (java)
Remarques sur le chemin et le package Java
Remarques sur les opérateurs utilisant Java ~ Type chaîne ~
Gestion des versions de java avec jenv d'OSX
Remarques sur les balises d'extension JSP dans SpringFrameWork
Syntaxe de contrôle Java
Syntaxe de contrôle Java
Partition en Java
Génériques Java (Notes)
Changements dans Java 11
[Java] Note sur le tableau
Janken à Java
[Java] Notes d'étude
Notes de sérialisation Java
Taux circonférentiel à Java
FizzBuzz en Java
Mémo organisé dans la tête (syntaxe Java --Control)
Désérialiser le CSV en Java en fonction du nom de l'en-tête
Notes sur la façon de rédiger des commentaires en anglais
Remarques sur la mise en œuvre de l'API Google Books dans les versions java okhttp et gson et les versions okhttp et jackson
Lire JSON en Java
Implémentation de l'interpréteur par Java
Faites un blackjack avec Java
Application Janken en Java
Remarques sur les tampons de protocole
Programmation par contraintes en Java
Mettez java8 dans centos7
[Java] Remarque sur les collecteurs de flux
Sortie au format Java [Note]
Joindre des tableaux en Java
"Hello World" en Java
Interface appelable en Java
Installez Java sur Mac
Commentaires dans la source Java
[Android] Notes sur xml
Fonctions Azure en Java
Exécutez PostgreSQL sur Java
Formater XML en Java
Remarques sur l'héritage multiple
Notes de révision de Java NIO 2
Simple htmlspecialchars en Java
Notes sur les expressions régulières
Implémentation Boyer-Moore en Java
Hello World en Java
Utiliser OpenCV avec Java
Mémorandum WebApi avec Java
Détermination de type en Java
Exécuter des commandes en Java (ping)
Divers threads en java
Implémentation du tri de tas (en java)
API Zabbix en Java
Art ASCII à Java
Comparer des listes en Java