Linux: comment vérifier quel gestionnaire gère les signaux

Le / proc / PID / status indique quel signal est détecté par le processus. Cependant, je me demande comment vérifier quel gestionnaire gère le ou les signaux. Par exemple:

void handler1(int sigNum) { if(sigNum == SIGINT) printf("handler1 is handling SIGINT\n"); } void handler2(int sigNum) { if(sigNum == SIGINT) printf("handler2 is handling SIGINT\n"); } void main() { signal(SIGINT, handler1); signal(SIGINT, handler2); while(1); } 

La fonction principale a enregistré deux gestionnaires de signaux pour gérer le SIGINT. Comment savoir si handler1 ou handler2 a été enregistré pour gérer SIGINT et gère SIGINT? Je veux faire la même chose comme psig sous Solaris. Quelle est la signification de chaque colonne lors de l’exécution d’une commande psig?

J’ai expérimenté un programme de surveillance qui exécute un processus cible avec interposition de signal() , sigaction() et fork() , en utilisant une bibliothèque d’assistance dynamic. Le programme de surveillance écoute les connexions de domaine Unix entrantes.

La bibliothèque dynamic est très simple. Au démarrage (en utilisant l’atsortingbut constructor GCC pris en charge dans les binarys Linux ELF), il se connecte au programme de surveillance. (Après un fork() réussi, le nouveau processus fermera sa copie du descripteur et ouvrira une nouvelle connexion.) A chaque sigaction() signal() ou sigaction() , il signale le nom du signal au programme de surveillance en utilisant

 struct change { uint64_t addr; char name[15]; unsigned char info; /* SA_RESETHAND; SIG_DFL/SIG_IGN */ }; 

La bibliothèque associe les numéros de signaux aux noms (comme SIGINT à "INT" ou SIGRTMIN+3 à "RTMIN+3" ) ou à des chaînes de nombres décimaux simples pour les numéros de signal non reconnus. Cela permet à un programme de surveillance 64 bits unique de surveiller un mélange de processus 64 bits et 32 ​​bits.

Le champ info est utilisé pour signaler les gestionnaires de signaux SA_RESETHAND ( SA_ONESHOT ), qui sont réinitialisés à la disposition par défaut lorsque le signal est remis au gestionnaire. Il est également utilisé pour indiquer les SIG_DFL et SIG_IGN , ainsi que d’autres événements spéciaux.

Lorsqu’une nouvelle connexion est établie, le programme de surveillance utilise readelf -W --syms --dyn-syms ou objdump -tT ou objdump -d sur /proc/PID/exe , en mémorisant l’adresse (ou la plage d’adresses) pour chaque fonction connue. dans le binary. Il enregistre chaque struct change pour chaque connexion, ainsi qu’un horodatage.

(Lorsqu’une connexion est établie, la bibliothèque interposée doit “faire une pause” jusqu’à ce que le programme de surveillance ait examiné le fichier binary. Sinon, des fichiers binarys à exécution courte peuvent être sortis avant l’exécution du programme de surveillance. .)

Sur mon système, bash installe un gestionnaire SIGCHLD pour l’adresse 447ad0, sans symbole associé. Si les symboles connus sont sortingés par ordre croissant et que les gestionnaires sont spécifiés par rapport au symbole le plus proche, ce gestionnaire peut être signalé par reap_dead_jobs+40 <447ad0> sous la forme reap_dead_jobs+40 <447ad0> . (Notez que reap_dead_jobs réside à [447a90, 447ac1), donc trouver le symbole qui couvre l’adresse ne suffira pas.)

Considérez ceci comme une description de l’approche qui devrait fonctionner, basée sur mes expériences. Mon propre code nécessite une réécriture complète pour être utile; c’est pourquoi je ne l’ai pas inclus ici. Je m’attendais à ce que le projet soit d’environ 600 à 900 lignes de code.