Как читать и анализировать core dump в Linux с помощью gdb
Иногда приложения в Linux падают с критической ошибкой, создавая core dump — снимок памяти процесса в момент аварии. Core dump содержит состояние регистров, стек вызовов, значения переменных и другую информацию, которая позволяет понять, почему приложение упало.
В этой статье разберём, как включить создание core dump, как открыть его в gdb и как анализировать ошибки на практике.
Включение core dump в Linux
По умолчанию многие системы ограничивают создание core dump. Чтобы разрешить их, нужно:
- Убедиться, что лимиты ядра позволяют создавать файлы:
ulimit -c unlimited- Настроить директорию для хранения core dump (опционально):
sudo mkdir -p /var/dumps
sudo chmod 1777 /var/dumps
echo '/var/dumps/core.%e.%p.%t' | sudo tee /proc/sys/kernel/core_patternЗдесь:
%e— имя исполняемого файла,%p— PID процесса,%t— время создания.
Теперь все аварийные процессы будут сохранять core dump в /var/dumps.
Проверка наличия core dump
После падения приложения можно убедиться, что core dump создан:
ls -lh /var/dumpsФайл будет содержать имя процесса, PID и timestamp. Этот файл и станет основным источником для анализа.
Анализ core dump с помощью gdb
Основная команда для открытия core dump:
gdb /path/to/executable /var/dumps/core.processname.pidПосле запуска gdb можно выполнять несколько ключевых команд:
bt(backtrace) — вывод стеков вызова всех потоков, показывает последовательность функций до аварии.frame N— переключение на конкретный фрейм в стеке, позволяет смотреть локальные переменные.info locals— показывает локальные переменные текущего фрейма.info threads— список всех потоков процесса, их состояние и ID.
Пример использования:
(gdb) bt
#0 0x00007f8c8a1d6c30 in divide_by_zero () at main.c:42
#1 0x00007f8c8a1d6c70 in main () at main.c:50
(gdb) frame 0
(gdb) info locals
denominator = 0
numerator = 100
Из этого примера видно, что ошибка произошла из-за деления на ноль в функции divide_by_zero().
Полезные команды для глубокого анализа
list— показывает исходный код вокруг текущей точки падения.print variable— вывод значения конкретной переменной.x /N format address— просмотр содержимого памяти.thread apply all bt— вывод стеков вызова для всех потоков.
Для многопоточных приложений это особенно важно, так как crash может произойти в одном потоке, но влиять на другие.
Советы по эффективному анализу
- Собирайте символьные таблицы
Скомпилируйте приложение с-g, чтобы gdb показывал имена функций и переменных. - Используйте core pattern для отладки production
Настройка/proc/sys/kernel/core_patternпозволяет автоматически сохранять core dump в определённую директорию, чтобы их можно было анализировать после падений. - Объединяйте с логами приложения
Часто причина падения видна через сочетание core dump и логов. - Скрипты и инструменты
Для массового анализа можно использоватьgdb -batch -ex 'bt' /path/to/executable /path/to/core, чтобы получить backtrace без интерактивной сессии.
Частые сценарии
- Segmentation fault — gdb покажет точную строку, где произошло обращение к запрещённой памяти.
- Divide by zero / arithmetic exception — локальные переменные подскажут значения, вызвавшие ошибку.
- Use after free / heap corruption — можно использовать вместе с valgrind или AddressSanitizer для уточнения причин.
Core dump и gdb вместе позволяют полностью реконструировать состояние процесса в момент аварии, что делает их незаменимыми для отладки критических приложений.
Практический пример: анализ Segmentation Fault
Создадим маленькую программу crash_example.c:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr = NULL;
printf("Перед обращением к NULL\n");
*ptr = 42; // здесь будет segmentation fault
printf("Эта строка не выполнится\n");
return 0;
}Скомпилируем с отладочными символами:
gcc -g crash_example.c -o crash_exampleЗапускаем программу:
./crash_example
Segmentation fault (core dumped)Теперь в текущей директории появится файл core (или core.crash_example.pid в зависимости от core_pattern).
Анализ с помощью gdb
Открываем core dump:
gdb ./crash_example coreВнутри gdb:
(gdb) bt
#0 0x00005555555551b6 in main () at crash_example.c:7
(gdb) frame 0
(gdb) info locals
ptr = 0x0
Вывод показывает:
- Ошибка произошла в строке
*ptr = 42;(строка 7). - Переменная
ptrравнаNULL(0x0), что и вызвало segmentation fault.
Можно также вывести содержимое памяти (для наглядности):
(gdb) x/1x ptr
0x0: 0x0
Советы для более сложных приложений
- Для многопоточных программ используйте:
thread apply all bt
чтобы увидеть стеки всех потоков.
- Для программ с динамической памятью можно подключать valgrind или AddressSanitizer, чтобы отлавливать use-after-free и heap corruption вместе с core dump.
- В продакшене удобно настроить core dump в отдельной папке, чтобы при падении сохранялся файл с PID и timestamp:
/var/dumps/core.%e.%p.%t.
Итог
Core dump в Linux — это мощный инструмент для анализа аварийных завершений. Правильная настройка системы и использование gdb позволяют:
- находить причины падений без догадок,
- изучать поведение потоков и переменных,
- восстанавливать полное состояние процесса для глубокого анализа.
Освоение работы с core dump — ключевой навык для системных разработчиков и инженеров по поддержке production-приложений.
Настроить мониторинг за 30 секунд
Надежные оповещения о даунтаймах. Без ложных срабатываний