Целью работы является освоение способов отладки программ на примере RISC-V.
Для достижения поставленной цели требуется решить следующие задачи:
gdb.Презентация к блоку "Оптимизации в компиляторах и отладка"
Отладка программ является неотъемлемой частью работы программиста. Существует несколько подходов к отладке:
В идеальных условиях, все три подхода должны применяться на различных стадиях жизненного цикла ПО, так как каждый из них обладает своими сильными сторонами: инструментирование позволяет в автоматическом режиме на ранних этапах обнаружить большое количество ошибок, отладчики обеспечивают эффективное воспроизведение и отладку ошибок времени выполнения, а JTAG является способом отладить ошибки для уже развернутых встраиваемых систем.
Наиболее важным и востребованным инструментом поиска ошибок в работе программ выступает отладчик. Как правило, графические среды разработки содержат специальные интерфейсы для его запуска, позволяющие визуализировать работу программы. Однако при этом, чаще всего, в основе подобных наглядных инструментов лежит открытый отладчик gdb, реализующий типовые операции отладки бинарных файлов программ с помощью интерактивной оболочки командной строки:
Рассмотрим пример сеанса отладки программы a.out в gdb. Для примера будем считать, что наша программа ожидает ввода целого числа и после ввода выполнит деление константы на данное число, а также что она собрана с флагом -g. Для начала запустим gdb с указанием бинарного файла для отладки:
$ gdb a.out
GNU gdb (Ubuntu 8.2-0ubuntu1~16.04.1) 8.2
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...(no debugging symbols found)...done.
(gdb)
После этого открылась оболочка (Интерфейс командной строки) отладчика gdb. Строка (gdb) является приглашением ввода команд. Обратите внимание, что сразу после запуска отладчика программа не начинает свою работу - для ее запуска необходимо вызвать команду run.
(gdb) run Starting program: /home/user/a.out
В данной точке начинается выполнение бинарного файла программы - a.out ожидает пользовательского ввода. Введем число 0, чтобы спровоцировать ошибку:
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; (gdb)
Мы увидим сообщение отладчика о типе ошибки (Arithmetic exception), указание на стек вызова и проблемную строку из исходного кода. В данный момент исполнение программы (в данном случае - аварийное завершение работы) приостановлено и мы можем изучить обстоятельства, приведшие к ошибке. Для печати более широкого фрагмента исходного кода используем команду l (list):
(gdb) l
4 int a=0;
5 int b;
6
7 scanf("%d", b);
8
9 a = a / b;
10
11 return 0;
12 }
(gdb)
Для печати текущих (на момент сбоя) значений переменных используем команду p (print) :
(gdb) p a $1 = 0 (gdb) p b $2 = 0
Для изменения значений переменных можно использовать команду set:
(gdb) set variable a=20 (gdb) p a $3 = 20
Для продолжения выполнения программы используем c (continue):
(gdb) c Continuing. Program terminated with signal SIGFPE, Arithmetic exception. The program no longer exists.
Мы можем также искусственно остановить работу программы в определенной точке, не дожидаясь сбоя, используя команду break (создание точки останова):
(gdb) break 8 Breakpoint 1 at 0x555555554710: file example.c, line 9. Запустим программу заново командой run и снова введем 0: (gdb) run Starting program: /home/vood/ws/a.out 0 Breakpoint 1, main () at example.c:9 9 a = a / b; (gdb)
Выполнение программы снова остановлено, однако это произошло ДО ошибки деления на ноль, поэтому в данной точке у нас есть возможность подробнее изучить причины сбоя или вмешаться в выполнение программы для проверки гипотез. После данных манипуляций можно возобновить работу программы командой continue.
Вам дан бинарный исполняемый файл, скомпилированный с отладочной информацией (флаг -g). Данный файл реализует логику программы расчета контрольных сумм для строк по оригинальному (но не практичному) алгоритму. Исходная строка вводится в программу через поток stdin. Программа аварийно завершает работу при вводе строки "sdasdasz".
Вам необходимо провести отладку программы с помощью gdb и определить:
Пример программы:
#include <stdio.h>
int main(void) {
char data[5] ;
scanf("%s", data);
int sum = 0;
int i;
int *pointer = NULL;
for(i = 0; data[i] != '\0' data[i + 1] != '\0'; i += 2) {
int value = ((unsigned char)data[i] << 8) | (unsigned char)data[i + 1];
if (data[i] == 'z' ) pointer = 4 ;
sum = (sum + value ) 0xffff;
}
printf("Sum is %04x\n", sum);
return 0;
}
Примечание для преподавателей: Выше приведен пример исходного кода программы, расчитаный на начинающих студентов. Мы рекомендуем дополнительно модифицировать этот файл в тайне от студентов так, чтобы логика и требуемые значения были изменены - в противном случае, студенты могут скопировать часть ответа из кода выше. При необходимости, данное задание можно усложнить с помощью нескольких способов:
-g. Тогда студентам потребуется анализировать поведение ПО с опорой только на ассемблерный код.Первым шагом для выполнения задания необходимо воспроизвести описанную неисправность вне отладчика путем запуска программы в RISC-V ОС и передачи ей строки, вызывающей ошибку. Это необходимо для того, чтобы в дальнейшем вести отладку с учетом максимально достоверной картины - в ряде случаев использование отладчиков может само по себе изменять поведение программы.
Далее, программу необходимо запустить в gdb и зафиксировать момент ее аварийной остановки. После этого необходимо визуализировать исходный код программы через команды gdb и путем изучения значений переменных, определить - какая именно операция привела к ошибке. Затем завершить выполнение программы.
Далее, необходимо установить точку останова до момента сбоя так, чтобы на момент остановки у вас была возможность вмешаться в ее работу путем изменения значений переменных. Далее запустите программу через gdb и введите данные, вызывающие ошибку. После остановки на точке останова, измените значения нужных переменных в программе и продолжите ее выполнение. Убедитесь, что после данного вмешательства не происходит ошибок и программа корректно завершает работу. Зафиксируйте ее вывод в отчете.
Для примера рассмотрим измененный пример программы из теоретической части:
#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]
gcc, чтобы ее бинарный файл включал отладочную информацию?Целью работы является освоение способов отладки программ на примере RISC-V.
Для достижения поставленной цели требуется решить следующие задачи:
gdb.Презентация к блоку "Оптимизации в компиляторах и отладка"
Отладка программ является неотъемлемой частью работы программиста. Существует несколько подходов к отладке:
В идеальных условиях, все три подхода должны применяться на различных стадиях жизненного цикла ПО, так как каждый из них обладает своими сильными сторонами: инструментирование позволяет в автоматическом режиме на ранних этапах обнаружить большое количество ошибок, отладчики обеспечивают эффективное воспроизведение и отладку ошибок времени выполнения, а JTAG является способом отладить ошибки для уже развернутых встраиваемых систем.
Наиболее важным и востребованным инструментом поиска ошибок в работе программ выступает отладчик. Как правило, графические среды разработки содержат специальные интерфейсы для его запуска, позволяющие визуализировать работу программы. Однако при этом, чаще всего, в основе подобных наглядных инструментов лежит открытый отладчик gdb, реализующий типовые операции отладки бинарных файлов программ с помощью интерактивной оболочки командной строки:
Рассмотрим пример сеанса отладки программы a.out в gdb. Для примера будем считать, что наша программа ожидает ввода целого числа и после ввода выполнит деление константы на данное число, а также что она собрана с флагом -g. Для начала запустим gdb с указанием бинарного файла для отладки:
$ gdb a.out
GNU gdb (Ubuntu 8.2-0ubuntu1~16.04.1) 8.2
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from a.out...(no debugging symbols found)...done.
(gdb)
После этого открылась оболочка (Интерфейс командной строки) отладчика gdb. Строка (gdb) является приглашением ввода команд. Обратите внимание, что сразу после запуска отладчика программа не начинает свою работу - для ее запуска необходимо вызвать команду run.
(gdb) run Starting program: /home/user/a.out
В данной точке начинается выполнение бинарного файла программы - a.out ожидает пользовательского ввода. Введем число 0, чтобы спровоцировать ошибку:
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; (gdb)
Мы увидим сообщение отладчика о типе ошибки (Arithmetic exception), указание на стек вызова и проблемную строку из исходного кода. В данный момент исполнение программы (в данном случае - аварийное завершение работы) приостановлено и мы можем изучить обстоятельства, приведшие к ошибке. Для печати более широкого фрагмента исходного кода используем команду l (list):
(gdb) l
4 int a=0;
5 int b;
6
7 scanf("%d", b);
8
9 a = a / b;
10
11 return 0;
12 }
(gdb)
Для печати текущих (на момент сбоя) значений переменных используем команду p (print) :
(gdb) p a $1 = 0 (gdb) p b $2 = 0
Для изменения значений переменных можно использовать команду set:
(gdb) set variable a=20 (gdb) p a $3 = 20
Для продолжения выполнения программы используем c (continue):
(gdb) c Continuing. Program terminated with signal SIGFPE, Arithmetic exception. The program no longer exists.
Мы можем также искусственно остановить работу программы в определенной точке, не дожидаясь сбоя, используя команду break (создание точки останова):
(gdb) break 8 Breakpoint 1 at 0x555555554710: file example.c, line 9. Запустим программу заново командой run и снова введем 0: (gdb) run Starting program: /home/vood/ws/a.out 0 Breakpoint 1, main () at example.c:9 9 a = a / b; (gdb)
Выполнение программы снова остановлено, однако это произошло ДО ошибки деления на ноль, поэтому в данной точке у нас есть возможность подробнее изучить причины сбоя или вмешаться в выполнение программы для проверки гипотез. После данных манипуляций можно возобновить работу программы командой continue.
Вам дан бинарный исполняемый файл, скомпилированный с отладочной информацией (флаг -g). Данный файл реализует логику программы расчета контрольных сумм для строк по оригинальному (но не практичному) алгоритму. Исходная строка вводится в программу через поток stdin. Программа аварийно завершает работу при вводе строки "sdasdasz".
Вам необходимо провести отладку программы с помощью gdb и определить:
Пример программы:
#include <stdio.h>
int main(void) {
char data[5] ;
scanf("%s", data);
int sum = 0;
int i;
int *pointer = NULL;
for(i = 0; data[i] != '\0' data[i + 1] != '\0'; i += 2) {
int value = ((unsigned char)data[i] << 8) | (unsigned char)data[i + 1];
if (data[i] == 'z' ) pointer = 4 ;
sum = (sum + value ) 0xffff;
}
printf("Sum is %04x\n", sum);
return 0;
}
Примечание для преподавателей: Выше приведен пример исходного кода программы, расчитаный на начинающих студентов. Мы рекомендуем дополнительно модифицировать этот файл в тайне от студентов так, чтобы логика и требуемые значения были изменены - в противном случае, студенты могут скопировать часть ответа из кода выше. При необходимости, данное задание можно усложнить с помощью нескольких способов:
-g. Тогда студентам потребуется анализировать поведение ПО с опорой только на ассемблерный код.Первым шагом для выполнения задания необходимо воспроизвести описанную неисправность вне отладчика путем запуска программы в RISC-V ОС и передачи ей строки, вызывающей ошибку. Это необходимо для того, чтобы в дальнейшем вести отладку с учетом максимально достоверной картины - в ряде случаев использование отладчиков может само по себе изменять поведение программы.
Далее, программу необходимо запустить в gdb и зафиксировать момент ее аварийной остановки. После этого необходимо визуализировать исходный код программы через команды gdb и путем изучения значений переменных, определить - какая именно операция привела к ошибке. Затем завершить выполнение программы.
Далее, необходимо установить точку останова до момента сбоя так, чтобы на момент остановки у вас была возможность вмешаться в ее работу путем изменения значений переменных. Далее запустите программу через gdb и введите данные, вызывающие ошибку. После остановки на точке останова, измените значения нужных переменных в программе и продолжите ее выполнение. Убедитесь, что после данного вмешательства не происходит ошибок и программа корректно завершает работу. Зафиксируйте ее вывод в отчете.
Для примера рассмотрим измененный пример программы из теоретической части:
#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]
gcc, чтобы ее бинарный файл включал отладочную информацию?Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.