User Tools

Site Tools


courses:programming:debug

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
courses:programming:debug [2022/12/10 09:08]
127.0.0.1 external edit
courses:programming:debug [2024/02/07 06:54]
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>​   - Ввести исходные данные,​ если ваша программа получает какие-то данные на вход. Если требуется перенаправить на вход вашей программе содержимое файла, запустите ее с помощью <code bash>​(gdb) run < input_file.txt</​code>​
-  - gdb распечатает сообщение "Program received signal SIGSEGV, Segmentation fault." ​с указанием строки и инструкции на которой это ​произошло. Вы также ​можете ​после краха Вашей ​программы написать <code bash>​(gdb) where</​code>​ и получить подробный стектрейс + 
-  - Вывести на экран значения переменных ​на этот момент можно с помощью команды [[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 + VS ===== 
 + 
 +WIP 
 + 
 + 
 +====== Архив ====== 
 + 
 +===== gdb + другие ​ide =====
 Любая среда разработки или даже мощный текстовый редактор обычно предоставляют вам графический интерфейс для использования gdb при отладке своих программ. Обычно он достаточно наглядный и имеет хорошее описание для каждой IDE. Любая среда разработки или даже мощный текстовый редактор обычно предоставляют вам графический интерфейс для использования gdb при отладке своих программ. Обычно он достаточно наглядный и имеет хорошее описание для каждой IDE.
  
courses/programming/debug.txt · Last modified: 2024/02/07 07:23 by yaroslav.gosudarkin