La génération des fichier core contiennent l’état de la mémoire d’un process, et a lieu généralement suite au crash de ce process. Sous Linux, le core dump est provoqué suite à la réception par le process de signaux spécifiques documentés dans le man 7 signal:
Signal Value Action Comment
----------------------------------------------------------------------
SIGQUIT 3 Core Quit from keyboard
SIGILL 4 Core Illegal Instruction
SIGABRT 6 Core Abort signal from abort(3)
SIGFPE 8 Core Floating point exception
SIGSEGV 11 Core Invalid memory reference
SIGBUS 10,7,10 Core Bus error (bad memory access)
SIGSYS 12,31,12 Core Bad argument to routine (SVr4)
SIGTRAP 5 Core Trace/breakpoint trap
SIGXCPU 24,24,30 Core CPU time limit exceeded (4.2BSD)
SIGXFSZ 25,25,31 Core File size limit exceeded (4.2BSD)
Avant toute chose, il faut vérifier que le système est capable de générer ces fichiers. En effet, sous Ubuntu par exemple, la user limit (ulimit) pour la taille des fichiers core est nulle. Il faut donc permettre au système d’écrire des fichiers de taille illimité:
On peut trivialement vérifier que les fichiers core sont générés. On lance un shell, et on envoie un signal SIGSEGV qui va faire crasher ce nouveau process ($$) pour générer le core:
$ kill -SEGV $$
Segmentation fault (core dumped)
$ ls -l core
-rw------- 1 mycroft mycroft 3784704 2011-04-02 13:02 core
Cependant, parfois, on veut pouvoir controler un peu plus ce fichier, en particulier son nom et sa destination. Les noyaux Linux 2.6 permettent cela grace à la variable système kernel.core_pattern (ou /proc/sys/kernel/core_pattern) qui sert de template pour le nom de fichier et qui a comme valeur par défaut « core ». Ce template accepte un chemin absolu et les modificateurs de format suivant:
- %p – pid
- %u – uid
- %g – gid
- %s – numéro de signal
- %t – temps UNIX / timestamp
- %h – hostname
- %e – nom de fichier executable
- %% – « % »
On décide donc de placer nos fichiers core dans /tmp/core, et qu’ils aient le format « timestamp.nom-executable.pid.uid:gid ». Pour cela, on modifie /proc/sys/kernel/core_pattern avec le format de notre choix:
# echo "/tmp/core/%t.%e.%p.%u:%g" > /proc/sys/kernel/core_pattern
Et on teste:
$ bash
$ kill -SEGV $$
Segmentation fault (core dumped)
$ ls -l /tmp/core
total 3584
-rw------- 1 mycroft mycroft 3784704 2011-04-02 13:16 1301778979.bash.19366.1000:1000
Il ne reste plus qu’à le configurer de manière à toujours reproduire ce comportement, en particulier après un reboot dy système. Pour cela, il n’y a qu’à ajouter la ligne suivante dans le fichier /etc/sysctl.conf:
De plus, pour conserver la valeur de ulimit, il faudra modifier /etc/security/limits.conf et affecter la valeur « unlimited » à l’item « core »:
#<domain> <type> <item> <value> * soft core unlimited
A noter que cette modification prendra effet au prochain log-in et non à l’ouverture d’une nouvelle console dans X.