При разработке под linux, если программа вдруг вылетает, лога нет. На этом этапе вы можете просмотреть основной файл. Проанализируйте причину из файла ядра, посмотрите, где программа зависает через gdb, проанализируйте переменные до и после и выясните причину проблемы.
Core Dump
Когда программа работает ненормально или дает сбой, операционная система записывает текущее состояние памяти программы и сохраняет его в файле.Это поведение называется Core Dump (некоторые китайцы переводятся как «дамп ядра»). Мы можем думать, что дамп ядра — это «снимок памяти», но на самом деле, помимо информации о памяти, одновременно сбрасываются и некоторые ключевые состояния работы программы, такие как информация о регистрах (включая указатель программы, указатель стека и т. ), информация об управлении памятью, другое состояние процессора и операционной системы и информация. Дамп ядра очень полезен для программистов при диагностике и отладке программ, потому что некоторые программные ошибки трудно воспроизвести, например исключения указателя, а файлы дампа ядра могут воспроизвести ситуацию, когда программа неверна.
Связанные настройки
Если настройки, связанные с дампом ядра, отсутствуют, по умолчанию они отключены. в состоянии пройтиulimit -c
Проверьте, включен ли он. Если выход0
, он не включен и его нужно выполнитьulimit -c unlimited
Включить функцию дампа ядра.
ulimit
ulimit
Команда используется для ограничения доступа системных пользователей к ресурсам оболочки. Ограничивает ресурсы, занимаемые процессом запуска оболочки, поддерживает следующие типы ограничений: размер создаваемого файла ядра, размер блока данных процесса, размер файла, создаваемого процессом оболочки, размер блокировки памяти , размер набора резидентной памяти, количество дескрипторов открытых файлов, максимальный размер выделенного стека, процессорное время, максимальное количество потоков на пользователя, максимальное количество виртуальной памяти, которую может использовать процесс оболочки. В то же время он поддерживает жесткие и мягкие ограничения ресурсов.
Параметры, связанные с ulimit, следующие:
-a:显示目前资源限制的设定;
-c <core文件上限>:设定core文件的最大值,单位为区块;
-d <数据节区大小>:程序数据节区的最大值,单位为KB;
-f <文件大小>:shell所能建立的最大文件,单位为区块;
-H:设定资源的硬性限制,也就是管理员所设下的限制;
-m <内存大小>:指定可使用内存的上限,单位为KB;
-n <文件数目>:指定同一时间最多可开启的文件数;
-p <缓冲区大小>:指定管道缓冲区的大小,单位512字节;
-s <堆叠大小>:指定堆叠的上限,单位为KB;
-S:设定资源的弹性限制;
-t <CPU时间>:指定CPU使用时间的上限,单位为秒;
-u <程序数目>:用户最多可开启的程序数目;
-v <虚拟内存大小>:指定可使用的虚拟内存上限,单位为KB。
Имя и путь сборки основного файла:
Если никакие настройки не сделаны, файлы ядра, сгенерированные по умолчанию, не имеют никаких других имен расширений, и все они называются core. Новое поколение файла дампа перезапишет исходный файл дампа. Имя и путь создания файла ядра можно настроить следующим образом:
-
/proc/sys /kernel/core_uses_pid
Вы можете контролировать, добавлять ли pid в качестве расширения к имени файла ядра. Если содержимое файла равно 1, это означает добавление pid в качестве расширения, а формат сгенерированного файла ядра — core.xxxx, если он равен 0, это означает, что сгенерированный файл ядра называется core. -
proc/sys/kernel/core_pattern
Может управлять местом сохранения основного файла и форматом имени файла.
Вот список параметров:
%p - insert pid into filename 添加pid
%u - insert current uid into filename 添加当前uid
%g - insert current gid into filename 添加当前gid
%s - insert signal that caused the coredump into the filename 添加导致产生core的信号
%t - insert UNIX time that the coredump occurred into filename 添加core文件生成时的unix时间
%h - insert hostname where the coredump happened into filename 添加主机名
%e - insert coredumping executable name into filename 添加命令名
Для получения дополнительной информации см.core dump file.
Пример:
Код, который будет генерировать ошибку, выглядит следующим образом:
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/resource.h>
#define CORE_SIZE 500 * 1024 * 1024
int main(){
struct rlimit rlmt;
if (getrlimit(RLIMIT_CORE, &rlmt) == -1) {
return -1;
}
printf("Before set rlimit core dump current is:%d, max is:%d\n", (int)rlmt.rlim_cur, (int)rlmt.rlim_max);
rlmt.rlim_cur = (rlim_t)CORE_SIZE;
rlmt.rlim_max = (rlim_t)CORE_SIZE;
if (setrlimit(RLIMIT_CORE, &rlmt) == -1) {
return -1;
}
if (getrlimit(RLIMIT_CORE, &rlmt) == -1) {
return -1;
}
printf("After set rlimit core dump current is:%d, max is:%d\n", (int)rlmt.rlim_cur, (int)rlmt.rlim_max);
// 对空指针指向的内存区域写,会发生段错误 -->产生core文件
int *null_ptr = NULL;
*null_ptr = 10;
return 0;
}
Используйте gcc для компиляции исходного файла и добавьте -g для добавления отладочной информации; выполнение вызовет ошибку и создаст основной файл.
воплощать в жизньgdb <program> core
Выходная информация выглядит следующим образом:
gdb <program> core
: используйте gdb для одновременной отладки работающей программы и файла ядра.Ядро — это файл, созданный дампом ядра после незаконного выполнения программы. Видно, что проблема программы заключается в сообщении об ошибке присваивания нулевого указателя в строке 31 файла core_dump.c.