====== Отладка ====== Идея -- программы часто не работают так, как того хочет программист. Какие ошибки сложнее всего искать? - 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]]