From 4384e91c3ccda6ce33f1f13a2b701923de9e21e3 Mon Sep 17 00:00:00 2001 From: Andrei Gavrilov Date: Wed, 12 Nov 2025 14:15:47 +0300 Subject: [PATCH] Added core dumps example --- README.md | 5 +++- core-dump-example/Makefile | 10 +++++++ core-dump-example/README.md | 55 +++++++++++++++++++++++++++++++++++++ core-dump-example/main.c | 18 ++++++++++++ 4 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 core-dump-example/Makefile create mode 100644 core-dump-example/README.md create mode 100644 core-dump-example/main.c diff --git a/README.md b/README.md index b47f7a0..38d319a 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ -# debug_examples \ No newline at end of file +# Debug examples + +## Debugging with core dumps +`core-dump-example` contains simple example of generating and using core dumps for debugging. diff --git a/core-dump-example/Makefile b/core-dump-example/Makefile new file mode 100644 index 0000000..bedaeef --- /dev/null +++ b/core-dump-example/Makefile @@ -0,0 +1,10 @@ +PROG_NAME=program + +.PHONY=all clean + +all: + gcc -g main.c -o ${PROG_NAME} + +clean: + rm -rf ./*.o + diff --git a/core-dump-example/README.md b/core-dump-example/README.md new file mode 100644 index 0000000..8addc42 --- /dev/null +++ b/core-dump-example/README.md @@ -0,0 +1,55 @@ +# Core dump example + +Пример программы с ошибкой, приводящей к аварийному завершению программы для демонстрации использования дампов памяти при отладке программы. + +## Сборка программы +Собрать программу можно с помощью make и компилятора gcc (предварительно убедитесь в их наличии): +``` +make +``` + +## Настройка окружения для записи дампов памяти в текущую директорию +``` +sudo sysctl -w kernel.core_pattern=$(pwd)/core-%e.%p.%t +ulimit -c unlimited +``` + +## Запуск программы и отладка +Запус к программы: +``` +./program +``` + +Результат: `Ошибка сегментирования (образ памяти сброшен на диск)`. В выводе видно, что произошла запись на диск и в текущей директории появился файл `core-*`. + +Теперь мы можем запустить отладкич gdb и восставновить состояние программы на момент завершения работы: +``` +gdb ./program +``` + +Вместо `` необходимо указать имя сгенерированного файла дампа памяти. + +После запуска отладчика получим: +``` +Core was generated by `./program'. +Program terminated with signal SIGSEGV, Segmentation fault. +#0 0x0000605ab889d139 in faulty_function (user=0x0) at main.c:9 +9 user->id = 100; +``` +Благодаря отладочным символам мы видим ошибку в строке 9 файла `main.c`. Ошибка в функции `faulty_function`, где видим, что аргумент `user=0x0`. Место ошибки становится очевидным. + +Чтобы легче было понять из какой функции и при каких обстоятельствах была вызвана функция, можно получить стек вызовов: +``` +(gdb) bt +#0 0x0000605ab889d139 in faulty_function (user=0x0) at main.c:9 +#1 0x0000605ab889d162 in main () at main.c:15 +(gdb) up +#1 0x0000605ab889d162 in main () at main.c:15 +15 faulty_function(user); +(gdb) info locals +user = 0x0 +``` + +В отладчике мы получили стек вызовов с помощью команды `bt`, поднялись по этому стеку наверх к функции #1 (`main`) с помощью `up` и вывели информацию о локальных переменных. Оказалось, что уже в функции `main`, переменная `user` была нулем. +Зачастую в программе сложнее понять из-за чего переменная получает значение нуля, поэтому информация о локальных переменных в функциях стека вызовов может сильно упростить понимание аварийной ситуации. + diff --git a/core-dump-example/main.c b/core-dump-example/main.c new file mode 100644 index 0000000..b31ca1f --- /dev/null +++ b/core-dump-example/main.c @@ -0,0 +1,18 @@ +#include + +typedef struct { + int id; + char name[32]; +} User; + +void faulty_function(User* user) { + user->id = 100; +} + +int main() { + User* user = NULL; + + faulty_function(user); + + return 0; +}