Опубликован: 19.01.2025 | Доступ: свободный | Студентов: 0 / 0 | Длительность: 05:57:00
Лекция 10:

Лабораторная работа №9. Методы отладки программ

< Лекция 9 || Лекция 10: 12 || Лекция 11 >

9.3.1. Описание последовательности выполнения работы

Первым шагом для выполнения задания необходимо воспроизвести описанную неисправность вне отладчика путем запуска программы в RISC-V ОС и передачи ей строки, вызывающей ошибку. Это необходимо для того, чтобы в дальнейшем вести отладку с учетом максимально достоверной картины - в ряде случаев использование отладчиков может само по себе изменять поведение программы.

Далее, программу необходимо запустить в gdb и зафиксировать момент ее аварийной остановки. После этого необходимо визуализировать исходный код программы через команды gdb и путем изучения значений переменных, определить - какая именно операция привела к ошибке. Затем завершить выполнение программы.

Далее, необходимо установить точку останова до момента сбоя так, чтобы на момент остановки у вас была возможность вмешаться в ее работу путем изменения значений переменных. Далее запустите программу через gdb и введите данные, вызывающие ошибку. После остановки на точке останова, измените значения нужных переменных в программе и продолжите ее выполнение. Убедитесь, что после данного вмешательства не происходит ошибок и программа корректно завершает работу. Зафиксируйте ее вывод в отчете.

9.3.2. Пример выполнения задания на защиту

Для примера рассмотрим измененный пример программы из теоретической части:


#include <stdio.h>

int main(){
  int a=0;
  int b;
  int c= 13;

  scanf("%d", &b);
  a = a / b;
  printf("%d", b + c);

  return 0;
}

Мы знаем, что программа должна выводить некоторую контрольную сумму, но при вводе значения 0 происходит ошибка. Воспроизводим ошибку в gdb:

$ gdb a.out
Starting program: /home/user/ws/a.out 

0


Program received signal SIGFPE, Arithmetic exception.

0x0000555555554717 in main () at example.c:9

9	  a = a / b;

Последнее сообщение содержит номер строки, в которой произошла ошибка - строка №9. Выведем часть исходного кода через отладчик


(gdb) l
4	  int a=0;
5	  int b;
6	  int c= 13;
7	
8	  scanf("%d", &b);
9	  a = a / b;
10	  printf("%d", b + c);
11	
12	  return 0;
13	}

Таким образом мы видим проблему в исходном коде - результат ввода пользователя в переменной b используется для деления. В случае если b=0 происходит ошибка деления на ноль. При этом результат деления никак не используется. Поэтому, при использовании точек останова и редактирования значений переменных мы можем вмешаться в поведение программы и преодолеть сбой:

(gdb) continue
Continuing.

Program terminated with signal SIGFPE, Arithmetic exception.
The program no longer exists.
(gdb) break 9
Breakpoint 1 at 0x555555554757: file example.c, line 9.
(gdb) break 10
Breakpoint 2 at 0x555555554763: file example.c, line 10.
(gdb) run
Starting program: /home/vood/ws/a.out 
0

Breakpoint 1, main () at example.c:9
9	  a = a / b;
(gdb) set variable b=1
(gdb) continue
Continuing.

Breakpoint 2, main () at example.c:10
10	  printf("%d", b + c);
(gdb) set variable b=0
(gdb) continue
Continuing.
13[Inferior 1 (process 26853) exited normally]

9.4. Вопросы для контроля

  1. Приведите примеры кода на языке С, который может вызвать ошибку времени выполнения.
  2. Что необходимо сделать в процессе сборки программы компилятором gcc, чтобы ее бинарный файл включал отладочную информацию?
  3. Объясните, как с точки зрения программиста выглядит работа механизма точек останова.
< Лекция 9 || Лекция 10: 12 || Лекция 11 >