This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
courses:programming:debug [2019/03/19 12:32] pro100kot |
courses:programming:debug [2024/02/07 07:23] (current) yaroslav.gosudarkin |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Отладка ====== | ====== Отладка ====== | ||
- | ===== Отладочный вывод ===== | + | |
+ | Идея -- программы часто не работают так, как того хочет программист. Какие ошибки сложнее всего искать? | ||
+ | |||
+ | - Runtime errors, приводящие к немедленной остановке программы. SEGFAULT, Double free corruption и т.п | ||
+ | - Логические ошибки, которые приводят к неверному поведению программы | ||
+ | |||
+ | Есть несколько техник, как искать подобные ошибки. | ||
+ | |||
+ | ===== Способ 1. Отладочный вывод ===== | ||
==== Основные полезные моменты ==== | ==== Основные полезные моменты ==== | ||
- Все отладочные выводы следует делать в поток stderr | - Все отладочные выводы следует делать в поток stderr | ||
Line 26: | Line 34: | ||
* [[http://www.gnu.org/software/libc/manual/html_node/index.html#toc-Syslog-1|Использование syslog]] | * [[http://www.gnu.org/software/libc/manual/html_node/index.html#toc-Syslog-1|Использование syslog]] | ||
- | ===== gdb + cli ===== | + | ===== Способ 2. gdb + cli ===== |
- | GDB имеет достаточно простой, но мощный командный интерфейс и хорошую справку по нему. Однако, если достаточно всего лишь узнать в каком месте программа упала (Segmentation fault), может хватить и следующего набора действий: | + | |
+ | GDB имеет достаточно простой, но мощный командный интерфейс и хорошую справку по нему. Пример: | ||
+ | |||
+ | <code c> | ||
+ | #include <stdio.h> | ||
+ | #include <stdarg.h> | ||
+ | |||
+ | void get_int(int* val) { | ||
+ | val = NULL; | ||
+ | printf("%d\n", *val); | ||
+ | } | ||
+ | |||
+ | int main() { | ||
+ | printf("Hello!"); | ||
+ | |||
+ | int* a; | ||
+ | get_int(a); | ||
+ | |||
+ | return 0; | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | При запуске данной программы появляется ошибка segmentation fault, т.е попытка доступа к несуществующей/чужой памяти. Что можно сделать что её найти: | ||
+ | |||
+ | - Найти строчку, где происходит непосредственно обращение к невалидной памяти | ||
+ | - Изучить состояние переменных, памяти в тот момент, когда произошла ошибка | ||
+ | |||
+ | Для этого необходимо: | ||
- Собрать программу с добавлением отладочных данных: <code bash>gcc -g myprog.c</code> | - Собрать программу с добавлением отладочных данных: <code bash>gcc -g myprog.c</code> | ||
- Открыть её в отладчике: <code bash>gdb ./a.out</code> | - Открыть её в отладчике: <code bash>gdb ./a.out</code> | ||
- Запустить программу командой run: <code bash>(gdb) run</code> | - Запустить программу командой run: <code bash>(gdb) run</code> | ||
- | - Ввести исходные данные, если ваша программа этого требуется | + | - Ввести исходные данные, если ваша программа получает какие-то данные на вход. Если требуется перенаправить на вход вашей программе содержимое файла, запустите ее с помощью <code bash>(gdb) run < input_file.txt</code> |
- | - gdb распечатает сообщение "Program received signal SIGSEGV, Segmentation fault." с указанием строки и инструкции на которой это произошло. Вывести на экран значения переменных на этот момент можно с помощью команды [[http://visualgdb.com/gdbreference/commands/print|print]] | + | |
+ | Вывод для программы после команды run будет следующий: | ||
+ | |||
+ | <code bash> | ||
+ | (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); | ||
+ | </code> | ||
+ | |||
+ | Теперь вы можете изучить состояние программы, например: | ||
+ | |||
+ | Написать <code bash>(gdb) where</code> и получить подробный стектрейс, чтобы узнать в каком файле и функции произошла ошибка: | ||
+ | |||
+ | <code bash> | ||
+ | (gdb) where | ||
+ | #0 0x0000555555555165 in get_int (val=0x0) at main.c:6 | ||
+ | #1 0x00005555555551ac in main () at main.c:13 | ||
+ | </code> | ||
+ | |||
+ | Изучить состояние переменных с помощью команды "p <variable_name>" | ||
+ | |||
+ | <code bash> | ||
+ | (gdb) p val | ||
+ | $1 = (int *) 0x0 | ||
+ | </code> | ||
+ | |||
+ | Если вы хотите изучить состояние программы ДО того, как ошибка случится, то можете использовать команду "b" для расстановки точек останова. https://www.opennet.ru/docs/RUS/gdb/gdb_6.html | ||
+ | |||
+ | Полезные ссылки: | ||
* [[https://www.tutorialspoint.com/gnu_debugger|Краткий туториал с примерами отладки ломающихся программ]] | * [[https://www.tutorialspoint.com/gnu_debugger|Краткий туториал с примерами отладки ломающихся программ]] | ||
* [[https://habr.com/post/181738|Полезное про массивы и работу с памятью]] | * [[https://habr.com/post/181738|Полезное про массивы и работу с памятью]] | ||
* [[https://sourceware.org/gdb/current/onlinedocs/gdb|Полная официальная документация]] | * [[https://sourceware.org/gdb/current/onlinedocs/gdb|Полная официальная документация]] | ||
- | ===== gdb + ide ===== | + | ===== Способ 3. GDB + VSCode ===== |
+ | |||
+ | <color #ed1c24>WIP</color> | ||
+ | |||
+ | Чтобы использовать отладчик 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. | Любая среда разработки или даже мощный текстовый редактор обычно предоставляют вам графический интерфейс для использования gdb при отладке своих программ. Обычно он достаточно наглядный и имеет хорошее описание для каждой IDE. | ||