Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# debug_examples
# Debug examples

## Debugging with core dumps
`core-dump-example` contains simple example of generating and using core dumps for debugging.
10 changes: 10 additions & 0 deletions core-dump-example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
PROG_NAME=program

.PHONY=all clean

all:
gcc -g main.c -o ${PROG_NAME}

clean:
rm -rf ./*.o

55 changes: 55 additions & 0 deletions core-dump-example/README.md
Original file line number Diff line number Diff line change
@@ -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>
```

Вместо `<core>` необходимо указать имя сгенерированного файла дампа памяти.

После запуска отладчика получим:
```
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` была нулем.
Зачастую в программе сложнее понять из-за чего переменная получает значение нуля, поэтому информация о локальных переменных в функциях стека вызовов может сильно упростить понимание аварийной ситуации.

18 changes: 18 additions & 0 deletions core-dump-example/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <stdlib.h>

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;
}