Chaque fois que mon application plante, un fichier de vidage principal n'est pas généré. Je me souviens qu'il y a quelques jours, sur un autre serveur, il était généré. Je lance l'application en utilisant screen in bash comme ceci:
#!/bin/bash
ulimit -c unlimited
while true; do ./server; done
Comme vous pouvez le constater, j'utilise ulimit -c unlimited
, ce qui est important si je veux générer un vidage mémoire, mais il ne le génère toujours pas, lorsque j'ai une erreur de segmentation . Comment puis-je le faire fonctionner?
Assurez-vous que votre répertoire actuel (au moment du crash - server
peut changer de répertoire) est accessible en écriture. Si le serveur appelle setuid
, le répertoire doit être accessible en écriture pour cet utilisateur.
Vérifiez également /proc/sys/kernel/core_pattern
. Cela peut rediriger les core dumps vers un autre répertoire, et le répertoire that doit être accessible en écriture. Plus d'infos ici .
Ce lien contient une bonne liste de contrôle pour laquelle les vidages mémoire ne sont pas générés:
exit()
au lieu d'utiliser le gestionnaire de vidage de mémoire.Vérifier:
$ sysctl kernel.core_pattern
pour voir comment vos dumps sont créés (% e sera le nom du processus et% t sera l’heure du système).
Si vous avez Ubuntu, vos dumps sont créés par apport
dans /var/crash
, mais dans un format différent (éditez le fichier pour le voir).
Vous pouvez le tester par:
sleep 10 &
killall -SIGSEGV sleep
Si la sauvegarde du noyau réussit, vous verrez «(noyau déchargé)» après l'indication de faute de segmentation.
Lire la suite:
Comment générer un fichier core dump dans Ubuntu
Ubuntu
S'il vous plaît lire plus à:
Rappelez-vous que si vous démarrez le serveur à partir d'un service , il démarrera une autre session bash, de sorte que ulimit ne sera pas efficace là. Essayez de mettre ceci dans votre script lui-même :
ulimit -c unlimited
Pour mémoire, sous Debian 9 Stretch (systemd
), je devais installer le paquet systemd-coredump
. Ensuite, les core dumps ont été générés dans le dossier /var/lib/systemd/coredump
.
De plus, ces coredumps sont compressés au format lz4
. Pour décompresser, vous pouvez utiliser le package liblz4-tool
comme ceci: lz4 -d FILE
.
Pour pouvoir déboguer le coredump décompressé en utilisant gdb
, je devais aussi renommer le nom de fichier tout à fait long en quelque chose de plus court ...
Les réponses données ici couvrent assez bien la plupart des scénarios pour lesquels le vidage principal n'est pas créé. Cependant, dans mon cas, aucun de ces cas ne s'est appliqué. Je publie cette réponse comme un ajout aux autres réponses.
Si votre fichier principal n’est pas créé pour une raison quelconque, je vous recommande d’examiner le fichier/var/log/messages. Il pourrait y avoir un indice pour expliquer pourquoi le fichier de base n’est pas créé. Dans mon cas, il y avait une ligne indiquant la cause première:
Executable '/path/to/executable' doesn't belong to any package
Pour résoudre ce problème, modifiez le fichier /etc/abrt/abrt-action-save-package-data.conf et remplacez ProcessUnpackaged de «non» par «oui».
ProcessUnpackaged = yes
Ce paramètre spécifie s'il faut créer un noyau pour les fichiers binaires non installés avec le gestionnaire de packages.
Vérifiez également que vous avez suffisamment d’espace disque sur /var/core
ou à chaque fois que vos fichiers de sauvegarde principaux sont écrits. Si la partition est almos saturée ou utilisée à 100% sur le disque, c'est le problème qui se pose. Mon noyau dépose en moyenne quelques concerts, vous devez donc vous assurer d’avoir au moins 5 à 10 concerts disponibles sur la partition.
Si vous appelez daemon () puis démonisez un processus, le répertoire de travail en cours passera par défaut à /
. Donc, si votre programme est un démon, vous devriez rechercher un noyau dans le répertoire /
et non dans le répertoire du binaire.
Si vous utilisez une distribution Linux (CentOS, Debian, par exemple), le moyen le plus accessible de connaître les fichiers principaux et les conditions associées est la page de manuel. Il suffit d’exécuter la commande suivante depuis un terminal:
man 5 core
Bien que cela ne pose pas de problème à la personne qui a posé la question, car ils ont exécuté le programme destiné à générer le fichier core dans un script avec la commande ulimit, mais j'aimerais préciser que la commande ulimit est spécifique. dans le shell dans lequel vous l’exécutez (comme des variables d’environnement). J'ai passé beaucoup trop de temps à exécuter ulimit, sysctl et d'autres éléments dans un shell, ainsi que la commande que je souhaitais vider du noyau dans l'autre shell et à me demander pourquoi le fichier de base n'avait pas été produit.
Je vais l'ajouter à mon panier. Le système sysctl fonctionne pour tous les processus une fois qu'il est émis, mais ulimit ne fonctionne que pour le shell dans lequel il est émis (peut-être aussi les descendants), mais pas pour les autres shell en cours d'exécution.
Juste au cas où quelqu'un d'autre trébuche. J'exécutais le code de quelqu'un d'autre - assurez-vous qu'ils ne gèrent pas le signal, afin qu'ils puissent sortir correctement. J'ai commenté la manipulation, et j'ai récupéré le core dump.
Remarque: Si vous avez vous-même écrit un gestionnaire de crash, il est possible que le noyau ne soit pas généré. Alors, cherchez un code avec quelque chose en ligne:
signal(SIGSEGV, <handler> );
ainsi, le SIGSEGV sera géré par un gestionnaire et vous n'obtiendrez pas le vidage mémoire.
En centos, si vous n'êtes pas un compte root pour générer le fichier core: Vous devez être configuré pour que le compte dispose d'un privilège root ou d'un compte root de connexion:
vim /etc/security/limits.conf
comptesoft core illimité
comptenoyau dur illimité
alors si vous vous connectez à Shell avec securecrt ou autre:
déconnexion puis relogin