core(5)

NOM
core — Fichier image de la mémoire

DESCRIPTION
L'action par défaut de certains signaux consiste à faire se terminer un processus et à produire un fichier image de la mémoire (« core dump file »). C'est un fichier qui contient l'image mémoire du processus au moment où il s'est terminé. Cette image peut être utilisée dans un débogueur (par exemple, gdb(1)) pour étudier l'état du programme au moment où il s'est terminé. Une liste des signaux provoquant la création de cette image mémoire se trouve dans signal(7).

Un processus peut définir sa propre limite de ressource souple RLIMIT_CORE afin de définir une limite supérieure à la taille du fichier image de la mémoire qui sera créé s'il reçoit un signal « core dump » ; consultez getrlimit(2) pour davantage d'informations.

Il y a diverses circonstances dans lesquelles un fichier image de la mémoire (« core dump ») n'est pas produit :

-   Le processus ne possède pas les droits pour écrire le fichier image de la mémoire (par défaut, le fichier image de la mémoire s'appelle core ou core.pid, où pid est l'identifiant du processus qui a généré une image de la mémoire. Il est créé dans le répertoire de travail en cours. Voir ci-dessous pour davantage d'informations sur les règles de nommage). L'écriture du fichier image de la mémoire échouera si le répertoire dans lequel il devrait être écrit n'est pas accessible en écriture ou si un fichier avec le même nom existe et n'est pas accessible en écriture ou n'est pas un fichier ordinaire (par exemple, si c'est un répertoire ou un lien symbolique).

-   Un fichier (ordinaire et accessible en écriture) avec le même nom que celui qui serait utilisé pour l'image de la mémoire existe déjà, mais il y a plusieurs liens physiques vers ce fichier.

-   Le système de fichiers dans lequel serait écrit le fichier image de la mémoire est plein, il n'a plus d'inœud, il est monté en lecture seule ou l'utilisateur a atteint son quota pour le système de fichiers.

-   Le répertoire dans lequel le fichier image de la mémoire doit être créé n'existe pas.

-   Les limites de ressources RLIMIT_CORE (taille des fichiers « core ») ou RLIMIT_FSIZE (taille des fichiers) pour un processus sont définies à zéro ; consultez getrlimit(2) et la documentation de la commande ulimit de l'interpréteur de commande (limit dans csh(1)). RLIMIT_CORE sera cependant ignorée si le système est configuré pour tuber les vidages mémoire vers un programme.

-   Le binaire actuellement exécuté par le processus n'est pas accessible en lecture. Il s'agit d'une mesure de sécurité pour s'assurer qu'un exécutable dont le contenu n'est pas accessible en lecture ne produira pas de vidage mémoire — éventuellement lisible — contenant une image de l'exécutable.

-   Le processus exécute un programme set-user-ID (ou set-group-ID) dont le propriétaire (ou le groupe) est différent de l'identifiant d'utilisateur (ou de groupe) réel du processus, ou le processus exécute un programme qui possède des capacités de fichier (voir capabilities(7)). Consultez cependant la description de l'opération PR_SET_DUMPABLE de prctl(2), et la description du fichier /proc/sys/fs/suid_dumpable dans proc(5).

-   /proc/sys/kernel/core_pattern est vide et /proc/sys/kernel/core_uses_pid contient la valeur 0 (ces fichiers sont décrits plus loin). Notez que si /proc/sys/kernel/core_pattern est vide et si /proc/sys/kernel/core_uses_pid contient la valeur 1, les fichiers image de la mémoire posséderont des noms de la forme .pid, et que ces fichiers sont cachés, à moins d'utiliser l'option -a de ls(1).

-   (Depuis Linux 3.7) Le noyau a été compilé sans l'option CONFIG_COREDUMP.

De plus, le vidage mémoire peut exclure des portions de l'espace d'adressage du processus si l'attribut MADV_DONTDUMP de madvise(2) est utilisé.

Sur les systèmes qui utilisent systemd(1) comme cadriciel pour init, les vidages mémoire peuvent être écrits à un emplacement déterminé par systemd(1). Voir plus loin pour plus de détails.

  Nommage des fichiers image de la mémoire
Par défaut, un fichier image de la mémoire s'appelle core, mais le fichier /proc/sys/kernel/core_pattern (depuis Linux 2.6 et 2.4.21) peut être configuré de manière à définir un motif qui sera utilisé pour le nommage des fichiers image de la mémoire. Le motif peut contenir des spécificateurs % qui sont remplacés par les valeurs suivantes lorsqu'une image de la mémoire est créée :

    %%  Caractère % unique
    %c  Limite de ressource souple de la taille du fichier image de la mémoire créé lors du plantage d'un processus (depuis Linux 2.6.24).
    %d  Mode vidage (« dump mode ») — identique à la valeur renvoyée par PR_GET_DUMPABLE de prctl(2) (depuis Linux 3.7).
    %e  La valeur de comm du processus ou du thread, qui correspond en général au nom de l'exécutable (sans le chemin et tronqué à un maximum de 15 caractères), mais qui peut avoir été modifiée en quelque chose de différent ; voir les explications à propos de /proc/pid/comm et /proc/pid/task/tid/comm dans proc(5).
    %E  Chemin d'accès de l'exécutable, où les barres obliques « / » sont remplacées par des points d'exclamation « ! » (depuis Linux 3.0).
    %F  PIDFD of dumped process (since Linux 6.16).
    %g  GID numérique réel du processus dont l'image mémoire a été vidée.
    %h  Nom d'hôte (identique à nodename renvoyé par uname(2)).
    %i  TID du thread qui a déclenché le vidage mémoire, tel qu'il est vu dans l'espace de noms du PID dans lequel le thread se trouve (depuis Linux 3.18).
    %I  TID du thread qui a déclenché le vidage mémoire, tel qu'il est vu dans l'espace de noms du PID initial (depuis Linux 3.18).
    %p  PID du processus dont l'image mémoire a été vidée, tel qu'il est vu dans l'espace de noms du PID dans lequel le processus se trouve.
    %P  PID du processus dont l'image mémoire a été vidée, tel qu'il est vu dans l'espace des noms du PID initial (depuis Linux 3.12).
    %s  Numéro du signal ayant provoqué le vidage mémoire
    %t  Heure du vidage mémoire exprimée en secondes depuis l'Époque, 1er janvier 1970 à 00:00:00 +0000 (UTC).
    %u  UID numérique réel du processus « vidé ».

Un % isolé à la fin du motif est éliminé du nom de fichier de l'image mémoire, et il en sera de même pour un % suivi d'un caractère autre que ceux de la liste ci-dessus. Tous les autres caractères du motif conservent leur valeur littérale dans le nom de fichier de l'image mémoire. Un motif peut contenir des caractères « / », ils sont interprétés comme des délimiteurs pour les noms de répertoire. La taille maximale du nom de fichier de l'image mémoire résultant est de 128 octets (64 octets avant Linux 2.6.19). La valeur par défaut de ce nom de fichier est « core ». Afin d'assurer une rétrocompatibilité, si /proc/sys/kernel/core_pattern ne contient pas « %p » et si /proc/sys/kernel/core_uses_pid (voir ci-dessous) est différent de zéro, « .PID » est ajouté au nom de fichier de l'image mémoire.

Les chemins sont interprétés en tenant compte des paramètres actifs pour le processus qui a planté. Ces paramètres comprennent l'espace de noms montage du processus qui a planté (voir mount_namespaces(7)), son répertoire de travail actuel (déterminé à l'aide de getcwd(2)) et son répertoire racine (voir chroot(2)).

Depuis Linux 2.4, Linux procure aussi une méthode plus primitive pour contrôler le nom du fichier image de la mémoire. Si le fichier /proc/sys/kernel/core_uses_pid contient la valeur 0, le fichier image de la mémoire est tout simplement appelé core. Si ce fichier contient une valeur différente de zéro, le fichier image de la mémoire intégrera dans son nom le numéro d'identification du processus sous la forme core.PID.

À partir de Linux 3.6, si /proc/sys/fs/suid_dumpable a pour valeur 2 (« suidsafe »), le motif doit être soit un chemin absolu (commençant par le caractère « / », soit un tube, comme indiqué plus bas.

  Tuber les vidages mémoire vers un programme
Since Linux 2.6.19, Linux supports an alternate syntax for the /proc/sys/kernel/core_pattern file. If the first character of this file is a pipe symbol (|), then the remainder of the line is interpreted as the command-line for a user-space program (or script) that is to be executed.

Depuis Linux 5.3.0, le modèle de tube est divisé en tenant compte des espaces en une liste d'arguments avant l'interprétation des paramètres du modèle. Avec les noyaux plus anciens, les paramètres du modèle sont interprétés en premier et la chaîne résultante est divisée en tenant compte des espaces en une liste d'arguments. Cela signifie qu'avec les noyaux plus anciens, les noms d'exécutable ajoutés par les paramètres de modèle %e et %E pouvaient être divisés en plusieurs arguments. Le gestionnaire de vidage mémoire doit donc définir le dernier argument avec les noms d'exécutable et s'assurer de « recoller » toutes les parties du nom de l'exécutable en tenant compte des espaces. Les noms d'exécutable qui contiennent plusieurs espaces ne sont pas correctement représentés dans les noyaux plus anciens, et dans ce cas, le gestionnaire de vidage mémoire devra utiliser des mécanismes permettant de déterminer le nom de l'exécutable.

Au lieu d'être écrit dans un fichier, le vidage mémoire est envoyé sur l'entrée standard du programme. Notez les points suivants :

-   Le programme doit être indiqué avec un chemin d'accès absolu (ou un chemin relatif par rapport au répertoire racine, /) et doit immédiatement suivre le caractère « | ».

-   Les arguments de la ligne de commande peuvent inclure tout spécificateur % indiqué plus haut. Par exemple, pour transmettre le PID du processus vidé, indiquez %p dans un argument.

-   Le processus créé pour exécuter le programme s'exécute avec les utilisateur et groupe root.

-   L'exécution en tant que root ne permet pas de contournement de sécurité exceptionnel. À ce titre, les LSM (comme SELinux) sont toujours actifs et peuvent empêcher le gestionnaire d'accéder aux détails du processus ayant planté à l'aide de /proc/pid.

-   Le nom de chemin du programme est interprété en respectant l'espace de noms montage initial, car il est toujours exécuté dans ce contexte. Il n'est pas affecté par les paramètres du processus ayant planté (par exemple le répertoire racine, l'espace de noms montage et le répertoire de travail actuel).

-   Le processus s'exécute dans les espaces de noms initiaux (PID, montage, utilisateur, etc.) et non dans les espaces de noms du processus ayant planté. On peut utiliser des spécificateurs comme %P pour trouver le répertoire /proc/pid correct et sonder/entrer les espaces de noms du processus ayant planté si nécessaire.

-   Le processus démarre avec son répertoire de travail courant comme répertoire racine. Il est cependant possible de passer au répertoire de travail du processus de vidage en utilisant la valeur fournie par le spécificateur %P pour passer à l'emplacement du processus de vidage à l'aide de /proc/pid/cwd.

-   Depuis Linux 2.6.24, il est possible de fournir au programme des arguments séparés par des espaces dans la ligne de commande (jusqu'à une longueur de ligne de 128 octets).

-   La limite RLIMIT_CORE ne s'applique pas aux vidages mémoire tubés vers un programme à l'aide de ce mécanisme.

  /proc/sys/kernel/core_pipe_limit
Lorsqu'on collecte des vidages mémoire à l'aide d'un tube vers un programme de l'espace utilisateur, il peut s'avérer utile pour le programme collecteur d'extraire les données à propos du processus ayant planté depuis le répertoire /proc/pid de ce dernier. Pour ce faire en toute sécurité, le noyau doit attendre que le programme collecteur de vidage mémoire se termine, de façon à ne pas supprimer prématurément les fichiers contenus dans le répertoire /proc/pid du processus ayant planté, ce qui a pour inconvénient de donner la possibilité à un programme de collecte défectueux de bloquer le vidage d’un processus planté en ne se terminant jamais.

Depuis Linux 2.6.32, on peut utiliser /proc/sys/kernel/core_pipe_limit pour limiter cette possibilité. La valeur contenue dans ce fichier définit le nombre de processus plantés simultanés qui peuvent être tubés en parallèle vers des programmes de l'espace utilisateur. Si cette valeur est dépassée, les processus plantés concernés seront consignés dans le journal du noyau et leurs vidages mémoires omis.

Une valeur de 0 dans ce fichier a une signification particulière. Elle indique qu'il n'y a pas de limite au nombre de processus qui peuvent être interceptés en parallèle, mais qu'aucune attente ne sera observée (autrement dit, le programme collecteur n'a aucune garantie d'accéder à /proc/<crashing-PID>). Par défaut, ce fichier contient la valeur 0.

  Contrôler quelles projections seront écrites dans le vidage mémoire
Depuis Linux 2.6.23, le fichier /proc/pid/coredump_filter spécifique à Linux permet de contrôler quels segments de mémoire seront écrits dans le fichier image de la mémoire si un vidage mémoire est effectué pour le processus avec le PID correspondant.

The value in the file is a bit mask of memory mapping types (see mmap(2)). If a bit is set in the mask, then memory mappings of the corresponding type are dumped; otherwise, they are not dumped. The bits in this file have the following meanings:

    bit 0
        Vider les projections privées anonymes.
    bit 1
        Vider les projections partagées anonymes.
    bit 2
        Vider les projections privées sauvegardées sur fichier.
    bit 3
        Vider les projections partagées sauvegardées sur fichier.
    bit 4 (depuis Linux 2.6.24)
        Vider les en-têtes ELF.
    bit 5 (depuis Linux 2.6.28)
        Vider les pages privées volumineuses.
    bit 6 (depuis Linux 2.6.28)
        Vider les pages partagées volumineuses.
    bit 7 (depuis Linux 4.4)
        Vider les pages DAX privées.
    bit 8 (depuis Linux 4.4)
        Vider les pages DAX partagées.

Par défaut, les bits suivants sont positionnés : 0, 1, 4 (si l'option de configuration du noyau CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS est activée) et 5. L'option d'amorçage coredump_filter permet de modifier ce réglage par défaut.

La valeur dans ce fichier est enregistrée en hexadécimal (la valeur par défaut est donc 33).

Les pages d'entrées-sorties projetées en mémoire telles que les tampons de trame ne sont jamais vidées, et les pages DSO virtuelles (vdso(7)) le sont toujours, quelle que soit la valeur de coredump_filter.

Un processus enfant créé avec fork(2) hérite de la valeur de coredump_filter de son parent ; la valeur de coredump_filter est préservée au travers d'un execve(2).

Il peut être utile de définir coredump_filter dans l'interpréteur de commande parent avant d'exécuter le programme ; par exemple :

    $ echo 0x7 > /proc/self/coredump_filter
    $ ./un_programme

Ce fichier n'existe que si le noyau a été compilé avec l'option de configuration CONFIG_ELF_CORE.

  Vidages mémoire et systemd
Sur les systèmes qui utilisent systemd(1) comme cadriciel pour init, les vidages mémoire peuvent être écrits à un emplacement déterminé par systemd(1). À cet effet, systemd(1) utilise la fonctionnalité core_pattern qui permet de tuber les vidages mémoire vers un programme. Cela peut être vérifié en regardant si les vidages mémoires sont tubés vers le programme systemd-coredump(8) :

    $ cat /proc/sys/kernel/core_pattern;
    |/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %e

Dans ce cas, les vidages mémoire seront enregistrés à l'emplacement configuré pour systemd-coredump(8), en général sous la forme de fichiers compressés lz4(1) dans le répertoire /var/lib/systemd/coredump/. Pour lister les vidages mémoires qui ont été enregistrés par systemd-coredump(8), on peut utiliser coredumpctl(1) :

    $ coredumpctl list | tail -5;
    Wed 2017-10-11 22:25:30 CEST  2748 1000 1000 3 present  /usr/bin/sleep
    Thu 2017-10-12 06:29:10 CEST  2716 1000 1000 3 present  /usr/bin/sleep
    Thu 2017-10-12 06:30:50 CEST  2767 1000 1000 3 present  /usr/bin/sleep
    Thu 2017-10-12 06:37:40 CEST  2918 1000 1000 3 present  /usr/bin/cat
    Thu 2017-10-12 08:13:07 CEST  2955 1000 1000 3 present  /usr/bin/cat

Les informations contenues dans tout vidage mémoire comprennent la date et l'heure du vidage, les PID, UID et GID du processus de vidage, le numéro du signal qui a déclenché le vidage et le chemin de l'exécutable qui était exécuté par le processus vidé. Plusieurs options de coredumpctl(1) permettent de déplacer le fichier image de la mémoire donné depuis l'emplacement de systemd(1) vers le fichier spécifié. Par exemple, pour extraire le vidage mémoire du PID 2955 montré plus haut dans un fichier nommé core dans le répertoire actuel, on peut utiliser :

    $ coredumpctl dump 2955 -o core;

Pour des détails plus exhaustifs, voir la page de manuel de coredumpctl(1).

Pour désactiver de manière permanente le mécanisme de systemd(1) qui archive les vidages mémoire et rétablir un fonctionnement plus proche du comportement traditionnel de Linux, on peut définir un contournement du mécanisme de systemd(1) en utilisant quelque chose du genre :

    # echo "kernel.core_pattern=core.%p" > \;
                   /etc/sysctl.d/50-coredump.conf
    # /lib/systemd/systemd-sysctl;

On peut aussi modifier le core_pattern temporairement (jusqu'au prochain redémarrage) en utilisant par exemple la commande suivante (qui inclut dans le nom des fichiers image de la mémoire le nom de l'exécutable et le numéro du signal qui a déclenché le vidage mémoire) :

    # sysctl -w kernel.core_pattern="%e-%s.core";

NOTES
La commande gdb(1) gcore permet d'obtenir une image mémoire d'un processus en cours d'exécution.

Jusqu'à Linux 2.6.27 inclus, si un processus multithreadé (ou plus précisément, un processus qui partage son espace mémoire avec un autre processus parce que créé avec l'indicateur CLONE_VM de clone(2)) crée une image mémoire, l'identifiant du processus (PID) est toujours ajouté au nom du fichier image de la mémoire, à moins que l'identifiant du processus ne fasse déjà partie du nom de fichier de par la présence d'une spécification %p dans /proc/sys/kernel/core_pattern (cela s'avère principalement utile lors de l'utilisation de l'implémentation obsolète LinuxThreads pour laquelle chaque thread d'un processus a son propre PID).

EXEMPLES
Le programme ci-dessous montre l'utilisation de la syntaxe de tubage dans le fichier /proc/sys/kernel/core_pattern. La session de l'interpréteur de commande suivante montre l'utilisation de ce programme (compilé pour créer un exécutable nommé core_pattern_pipe_test) :

    $ cc -o core_pattern_pipe_test core_pattern_pipe_test.c
    $ su
    Password:
    # echo "|$PWD/core_pattern_pipe_test %p UID=%u GID=%g sig=%s" > \
    /proc/sys/kernel/core_pattern
    # exit
    $ sleep 100
    ^\                     # taper control-backslash
    Quit (core dumped)
    $ cat core.info
    argc=5
    argc[0]=</home/mtk/core_pattern_pipe_test>
    argc[1]=<20575>
    argc[2]=<UID=1000>
    argc[3]=<GID=100>
    argc[4]=<sig=3>
    Total bytes in core dump: 282624

  Source du programme
    /* core_pattern_pipe_test.c */

    #define _GNU_SOURCE
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <limits.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>

    #define BUF_SIZE 1024

    int
    main(int argc, char *argv[])
    {
        ssize_t nread, tot;
        char buf[BUF_SIZE];
        FILE *fp;
        char cwd[PATH_MAX];

        /* Change our current working directory to that of the
           crashing process.  */

        snprintf(cwd, PATH_MAX, "/proc/%s/cwd", argv[1]);
        chdir(cwd);

        /* Write output to file "core.info" in that directory.  */

        fp = fopen("core.info", "w+");
        if (fp == NULL)
            exit(EXIT_FAILURE);

        /* Display command-line arguments given to core_pattern
           pipe program.  */

        fprintf(fp, "argc=%d\n", argc);
        for (size_t j = 0; j < argc; j++)
            fprintf(fp, "argc[%zu]=<%s>\n", j, argv[j]);

        /* Count bytes in standard input (the core dump).  */

        tot = 0;
        while ((nread = read(STDIN_FILENO, buf, BUF_SIZE)) > 0)
            tot += nread;
        fprintf(fp, "Total bytes in core dump: %zd\n", tot);

        fclose(fp);
        exit(EXIT_SUCCESS);
    }

VOIR AUSSI
bash(1), coredumpctl(1), gdb(1), getrlimit(2), mmap(2), prctl(2), sigaction(2), elf(5), proc(5), pthreads(7), signal(7), systemd-coredump(8)

TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org>, Cédric Boutillier <cedric.boutillier@gmail.com>, Frédéric Hantrais <fhantrais@gmail.com> et Lucien Gentis <lucien.gentis@waika9.com>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.