Sous Linux, Core signifie mémoire. Lorsqu'une exception est détectée pendant l'exécution du programme et que le programme se termine anormalement, le système stocke l'état actuel de la mémoire du programme dans un fichier core, appelé core dumped, qui est également un vidage d'informations lorsque le système d'exploitation détecte une exception ; le processus actuel, il utilisera un signal. Notifier le processus cible des informations d'erreur correspondantes. Les signaux courants incluent SIGSEGV, SIGBUS, etc. Par défaut, le processus dispose d'un mécanisme de traitement correspondant lorsqu'il reçoit le signal correspondant.
L'environnement d'exploitation de ce tutoriel : système linux7.3, ordinateur Dell G3.
Lors du développement sous Linux, nous entendons souvent les programmeurs dire que le cœur de mon programme a chuté. De tels problèmes surviennent généralement en raison de bugs de bas niveau tels qu'un accès mémoire hors limites, l'utilisation de pointeurs nuls, un débordement de pile, etc. . Si le programme se ferme ou se termine anormalement pendant l'exécution, les fichiers core seront générés lorsque ces conditions seront remplies.
Pourquoi Coredump se produit-il
Core signifie mémoire. Ce mot vient du matériau utilisé il y a longtemps pour fabriquer de la mémoire et a été utilisé jusqu'à présent lorsqu'une anomalie est détectée lors du fonctionnement du programme et du programme. Le programme se termine anormalement, le système stocke l'état actuel de la mémoire du programme dans un fichier core, appelé core dumped, également connu sous le nom de Information dump Lorsque le système d'exploitation détecte une exception dans le processus en cours, il en informe le processus cible. les informations d'erreur correspondantes via un signal. Les signaux courants incluent SIGSEGV, SIGBUS, etc. Par défaut, le processus dispose d'un mécanisme de traitement correspondant lorsqu'il reçoit le signal correspondant.
Prenons Linux comme exemple. L'action correspond à la méthode de traitement du signal. Les cases rouges sont marquées comme des signaux communs
Avant cela, il est préférable de comprendre la disposition de la mémoire du processus. Les systèmes Unix et Linux seront légèrement différents, l'espace du noyau sera plus petit que celui de Linux, en particulier le noyau et les processus utilisateur adoptent un mode d'espace d'adressage séparé. Voici Linux à titre d'exemple :
Le stockage. emplacement du fichier coredump
Nous savons que dans le système Linux, si le processus plante, le noyau du système capturera les informations de crash du processus, puis écrira les informations coredump du processus dans un fichier. Le nom de fichier par défaut est. cœur. L'emplacement de stockage est dans le même répertoire que le programme exécutable correspondant. Le nom du fichier est core Vous pouvez voir l'emplacement du fichier core via la commande suivante :
Core_pattern format :
%p. PID de transfert du processus vidé
%u (Nombre) UID réel du processus vidé
%G (Nombre) GID réel du processus vidé
%s Nombre de signaux qui ont provoqué le dump
%t Heure du dump, exprimée sous la forme depuis 1970 1 Nombre de secondes depuis le 1er mois 00:00:00 +0000 (UTC)
%H Nom d'hôte (identique au nom de nœud renvoyé par uname(2))
%e Nom de l'exécutable (pas de préfixe de chemin)
%E Oui Le nom de chemin du fichier exécutable, avec des barres obliques ('/') remplacées par des points d'exclamation ('!').
%C Limite souple de ressources de taille de fichier Core pour le processus de crash (depuis Linux 2.6.24)
Le programme suivant peut être utilisé pour démontrer l'utilisation de la syntaxe des tubes dans le fichier /proc/sys/kernel/core_pattern.
#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[]) { int tot, j; ssize_t nread; char buf[BUF_SIZE]; FILE *fp; char cwd[PATH_MAX]; /* 属性的当前工作目录崩溃的过程*/ snprintf(cwd, PATH_MAX, "/proc/%s/cwd", argv[1]); chdir(cwd); /* 将输出写到该目录下的文件"core.info" */ fp = fopen("core.info", "w+"); if (fp == NULL) { exit(EXIT_FAILURE); } fprintf(fp, "argc=%d\n", argc); for (j = 0; j < argc; j++) { fprintf(fp, "argc[%d]=<%s>\n", j, argv[j]); } /* 计算标准输入(核心转储)中的字节数*/ tot = 0; while ((nread = read(STDIN_FILENO, buf, BUF_SIZE)) > 0) { tot += nread; } fprintf(fp, "Total bytes in core dump: %d\n", tot); return 0; }
注意一下: 这里是指在进程当前工作目录的下创建。通常与程序在相同的路径下。但如果程序中调用了chdir函数,则有可能改变了当前工作目录。这时core文件创建在chdir指定的路径下。有好多程序崩溃了,我们却找不到core文件放在什么位置。和chdir函数就有关系。当然程序崩溃了不一定都产生 core文件。
下面通过的命令可以更改coredump文件的存储位置,如下:
echo “|$PWD/core_pattern_pipe_test %p UID=%u GID=%g sig=%s” > /proc/sys/kernel/core_pattern
cat /proc/sys/kernel/core_pattern
查看路径已经变为如下:
下面带大家配置永久的core。只要出现内存访问越界、使用空指针、堆栈溢出等情况,都可以在这个目录下查看。
配置 core
1、首先在根目录下建立一个储存coredump文件的文件夹,命令如下:
mkdir /corefile
2、设置产生coredump文件的大小,命令如下:
ulimit -c unlimited
3、 执行以下两条命令:
echo “1” > /proc/sys/kernel/core_uses_pid //将1写入到该文件里 echo “/corefile/core-%e-%p-%t” > /proc/sys/kernel/core_pattern
将coredump产生的格式制定好写入core_pattern文件,这样当coredump产生时会直接以这种格式存入到根目录下的文件夹corefile中。
4、修改配置文件/etc/profile
vim /etc/profile
添加 ulimit -S -c unlimited > /dev/null 2>&1
执行命令生效该文件
5、 在配置文件/etc/rc.local中最后面添加信息(机器重启时会自动加载该命令):添加命令:
rm -rf /corefile/*
机器重启时清空该文件夹,由于产生的coredump文件很大,若不清空的话时间长了会将硬盘占满;
再执行以下两条命令:
echo “1” > /proc/sys/kernel/core_uses_pid echo “/corefile/core-%e-%p-%t” > /proc/sys/kernel/core_pattern
测试
下面写个例子测试一下是否配置好了corefile文件
#include
编译运行,注意这里需要-g选项编译。
进入前面创建的corefile文件夹:
出现core文件表示完成coredump配置。可以用通过readelf命令进行判断是否是core文件:
Exécutez gdb pour lire le fichier core. La commande est "le programme gdb correspond au fichier coredump". À ce moment, vous entrerez l'invite gdb "(gdb)".
Comme vous pouvez le voir sur la capture d'écran de l'encadré rouge, le programme est terminé à cause du signal 11.
Vous pouvez voir la pile d'appels de la fonction via la commande bt (backtrace) (ou où) ci-dessous :
C'est-à-dire que lorsque le programme s'exécute à la ligne 6 de test.cpp, une erreur de segmentation se produit. La raison est qu'il pointe vers un pointeur nul.
Résumé
Il existe de nombreuses raisons pour le coredump du programme. Voici un résumé, principalement l'accès à la mémoire hors limites, l'utilisation de fonctions non sécurisées pour les threads, l'utilisation de pointeurs nuls, le débordement de pile, etc.
Je tiens à dire ici que lors du débogage de coredump avec gdb, la plupart du temps, vous ne pouvez découvrir la raison intuitive du core qu'à partir du fichier core. Cependant, la raison la plus fondamentale doit généralement être combinée avec le code pour. analyser le contexte d'exécution du processus à ce moment-là afin d'en déduire. Le problème réside dans le code du programme.
Recommandations associées : "Tutoriel vidéo Linux"
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!