====== Отладка ======
Идея -- программы часто не работают так, как того хочет программист. Какие ошибки сложнее всего искать?
- Runtime errors, приводящие к немедленной остановке программы. SEGFAULT, Double free corruption и т.п
- Логические ошибки, которые приводят к неверному поведению программы
Есть несколько техник, как искать подобные ошибки.
===== Способ 1. Отладочный вывод =====
==== Основные полезные моменты ====
- Все отладочные выводы следует делать в поток stderr
- При отладке полезно использовать макросы, сообщающие, например, номер строки и имя функции
- Полезно уметь "отключать" отладочные сообщения
Простой пример отладочных выводов "на коленке" (более подробно этот вопрос рассматривается в статье [[http://www.valvers.com/programming/c/logging-with-gcc/|Logging with GCC]]):
#include
#define DEBUG
int main(){
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s:%s:%d: %s\n", __FILE__, __func__, __LINE__,
"Debug message");
#endif
return 0;
}
==== Почитать подробнее ====
* [[https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html|Полезные стандартные макросы]]
* [[http://www.valvers.com/programming/c/logging-with-gcc/|Статья про простое логгирование (Logging with GCC)]]
* [[http://www.gnu.org/software/libc/manual/html_node/index.html#toc-Syslog-1|Использование syslog]]
===== Способ 2. gdb + cli =====
GDB имеет достаточно простой, но мощный командный интерфейс и хорошую справку по нему. Пример:
#include
#include
void get_int(int* val) {
val = NULL;
printf("%d\n", *val);
}
int main() {
printf("Hello!");
int* a;
get_int(a);
return 0;
}
При запуске данной программы появляется ошибка segmentation fault, т.е попытка доступа к несуществующей/чужой памяти. Что можно сделать что её найти:
- Найти строчку, где происходит непосредственно обращение к невалидной памяти
- Изучить состояние переменных, памяти в тот момент, когда произошла ошибка
Для этого необходимо:
- Собрать программу с добавлением отладочных данных: gcc -g myprog.c
- Открыть её в отладчике: gdb ./a.out
- Запустить программу командой run: (gdb) run
- Ввести исходные данные, если ваша программа получает какие-то данные на вход. Если требуется перенаправить на вход вашей программе содержимое файла, запустите ее с помощью (gdb) run < input_file.txt
Вывод для программы после команды run будет следующий:
(gdb) run
Starting program: /a.out
Program received signal SIGSEGV, Segmentation fault.
0x0000555555555165 in get_int (val=0x0) at main.c:6
6 printf("%d\n", *val);
Теперь вы можете изучить состояние программы, например:
Написать (gdb) where
и получить подробный стектрейс, чтобы узнать в каком файле и функции произошла ошибка:
(gdb) where
#0 0x0000555555555165 in get_int (val=0x0) at main.c:6
#1 0x00005555555551ac in main () at main.c:13
Изучить состояние переменных с помощью команды "p "
(gdb) p val
$1 = (int *) 0x0
Если вы хотите изучить состояние программы ДО того, как ошибка случится, то можете использовать команду "b" для расстановки точек останова. https://www.opennet.ru/docs/RUS/gdb/gdb_6.html
Полезные ссылки:
* [[https://www.tutorialspoint.com/gnu_debugger|Краткий туториал с примерами отладки ломающихся программ]]
* [[https://habr.com/post/181738|Полезное про массивы и работу с памятью]]
* [[https://sourceware.org/gdb/current/onlinedocs/gdb|Полная официальная документация]]
===== Способ 3. GDB + VSCode =====
WIP
Чтобы использовать отладчик gdb из IDE VSCode, необходимо:
Установить расширения для отладки и работы с языком С:
{{courses:programming:screenshot_from_2024-02-07_14-11-54.png}}
{{courses:programming:screenshot_from_2024-02-07_14-12-01.png}}
- Открыть ваш проект/файл в VSCode
- Расставить точки останова напротив интересующих вас строк кода (нажать слева от номер строки)
- Перейти в вкладку "Debug"
{{courses:programming:screenshot_from_2024-02-07_13-51-04.png}}
Нажать комбинацию клавиш ctrl+shift+P (откроется командная консоль vscode) и написать debug. Выбрать С/C++ debugging
{{courses:programming:screenshot_from_2024-02-07_14-16-57.png}}
Сохранить файл launch.json. Теперь у вас есть конфигурация для отладки этой программы. Запустите отладку, нажав F5
{{courses:programming:screenshot_from_2024-02-07_14-18-13.png}}
Теперь в VScode вам доступен интерфейс отладки:
- Справа панель управления отладкой
- Слева -- состояние памяти и переменных
{{courses:programming:screenshot_from_2024-02-07_14-18-27.png}}
{{courses:programming:screenshot_from_2024-02-07_14-18-34.png}}
====== Архив ======
===== gdb + другие ide =====
Любая среда разработки или даже мощный текстовый редактор обычно предоставляют вам графический интерфейс для использования gdb при отладке своих программ. Обычно он достаточно наглядный и имеет хорошее описание для каждой IDE.
Вы можете самостоятельно найти описание использования отладчика в вашей любимой IDE. Для CLion можно посмотреть эти источники:
* [[https://blog.jetbrains.com/clion/2015/05/debug-clion/|Debugging in CLion]]
* [[https://www.youtube.com/watch?v=wUZyoAnPdCY|Debugging in CLion on youtube]]