Тема лабораторной
На данном занятии вы научитесь отладке своих программ - дебажить с помощью программы cgdb, который собой представляет надстройку над gdb. Умение дебажить программу присуще каждому программисту, оно позволяет облегчить понимание того, как работает программа. Научившись и поняв раз, как работает debugger, вам больше не понадобится писать тестовые выводу на экран типа "я тут".
Цели
- Научиться основам cgdb .
- Понимать термины и действия, связанные напрямую с процессом отладки программы.
- Попрактиковать в работе с массивами чисел.
- Ознакомить с оператором
sizeof()
.
Инструкции
Шаг 1: Linear Search: The Reconstruction
Каждый программист как-то начинал. Разные программисты на начале своего пути учили разные алгоритмы. Посмотрите на следующий фрагмент кода, который пытается осуществить алгоритм линейного поиска. И как это часто бывает - на первый раз чаще всего не выходит.
Вашей задачей на данном этапе будет лишить данную реализацию всех недостатков и показать, почему-таки стоит проходить предмет Основы алгоритмизации и программирования.
Задача 1.1
Скачайте файл linear.c или создайте новый файл, скопировав в него следующий код:
#include <stdio.h>
int search(const int[], const int);
int main(){
int items[] = { 1, 5, 2, 3, 6, 8, 9, 7 };
printf("Enter item to find: ");
int find;
scanf("%d", &find);
int position = search(items, find);
printf("Position of %d is %d\n", find, position);
return 0;
}
int search(const int items[], const int find){
int idx = 0;
while(find != items[idx] || idx < sizeof(items)){
idx++;
}
return idx;
}
Задача 1.2
Скомпилируйте программу так, чтобы её можно было загрузить утилитой cgdb.
При компиляции в таком случае нужно использовать параметр -g, который в конечный бинарный файл добавит информацию, нужную для отладки в родном формате операционной системы (stabs, COFF, XCOFF, или DWARF 2). Эти данные может затем дебаггер gdb считать, таким образом, и cgdb.
Параметр -g можно использовать прямо при сборке следующим образом:
gcc -std=c11 -Wall -Werror -g linear.c -lm -o linear
Таким же образом, можно добавить этот параметр в переменную среды CFLAGS
, что позволит использование данного параметра при сборке проекта с помощью make
. Поэтому проверьте значение данной переменной в файле ~/.bashrc
(или ~/.profile
- в зависимости от того, каким образов запускается bash
у вас).
В случае, если параметр -g в вашей переменной среды CFLAGS
отсутствует, добавьте его (затем перезайдите в систему). При этом можно осуществить и временное изменение переменной CFLAGS
, введя следующую команду (изменения будут сброшены при следующем запуске):
export CFLAGS="$CFLAGS -g"
Комментарий
В случае, если вы используете нами предложенный VirtualBox или сервер, параметр -g уже задан в переменной среды CFLAGS
.
Задача 1.3
Измените ошибку, связанную с использованием оператора sizeof()
.
При компиляции программы должна была возникнуть следующая ошибка (при этом есть вероятность, что старые версии компилятора данную ошибку даже не заметят):
linear.c: In function ‘search’:
linear.c:21:45: error: ‘sizeof’ on array function parameter ‘items’ will return size of ‘const int *’ [-Werror=sizeof-array-argument]
while(find != items[idx] || idx < sizeof(items)){
^
linear.c:19:22: note: declared here
int search(const int items[], const int find){
^~~~~
cc1: all warnings being treated as errors
Задача 1.4
С помощью cgdb определите другие ошибки в алгоритме линеарного поиска и исправьте их.
После компиляции программы с параметром -g
программу в утилите cgdb запустите командой (linear
- название вашего исполнительного файла после компиляции):
cgdb linear
- После запуска программы экран делится на две части:
- Окно с кодом программы (верхняя часть программы)
- GDB окно (нижняя часть экрана)
- Утилита ориентирована главным образом на пользователей редактора ViM, так что комбинации некоторых клавиш им будут очень знакомы.
- Если хотите перенести фокус на окно с кодом, нажмите на клавишу ESC. Так вы также перейдёте в CGDB режим. Если наоборот хотите перевести фокус на GDB окно, нажмите на клавишу i. Так вы также перейдёте в GDB режим.
- В случае, если вам не подходит размещение окон и, главным образом, их размер, из CGDB режима возможно менять размер окон с помощью клавиш - и =.
- В режиме CGDB вы можете проходить по коду программы с помощью стрелочек или другими способами, известными вам из VIM.
- В случае, если на определённой строке вы ходите добавить точку остановки (breakpoint), нажмите SPACE, находясь на нём. Тем же нажатием можно breakpoint убрать.
- Программу можно запустить из режима CGDB нажатием клавиши F5. В случае, если на какой-то строке будет breakpoint, исполнение программы остановится на соответствующей строке. Начиная с этого момента, программу можно выполнять построчно (строка за строкой), исследуя состояние и значения отдельных переменных.
- Если ваша программа использует стандартные ввод или вывод, в cgdb нужно включить так называемый TTY режим. Это можно сделать, находясь в CGDB режиме нажатием клавиши T. Таким образом, если вам нужно что-то ввести в программу из клавиатуры, это можно сделать через вид TTY.
- Если вы хотите в программе один шаг, нажмите на F8. В любой момент вы можете перейти в окно gdb и выписать значение любой переменной в настоящей области видимости с помощью команды (
VARNAME
- имя переменной, значение которой вы хотите отследить):
print VARNAME
- Если вы не хотите постоянно вводить
print
для изображения переменной, в таком случае можно создать список переменных, которых будут отображаться после каждой остановки программы. Данное действием можно осуществить с помощью (VARNAME
- имя переменной, значение которой вы хотите отследить):
display VARNAME
- Каждой так выписываемой переменной присуждается ID (
VARNUMBER
), руководствуясь которым можно впоследствии данную переменную из списка для вывода исключить:
undisplay VARNUMBER
- Если ваша программа остановилась на breakpoint-e и вы бы хотели продолжить её выполнение, можно нажать на F6. Программа таким образом продолжит свою работу, останавливаясь на любом breakpoint-е по пути.
- Debugger можно запустить в отдельном окне, а в другом окне иметь редактор. После компиляции и новом запуске в cgdb произойдёт обновление. Если вы хотите обновить программу вручную ещё перед её запуском, в режиме GDB напишите программу
update
.
Список отдельных команд и комбинаций клавиш для cgdb находится в следующей таблице. Для полного списка команд для cgdb перейдите к мануалу к cgdb.
CGDB Mode | GDB Mode | Description |
---|---|---|
quit |
выход и завершение | |
ESC | переход в режим CGDB (окно с кодом программы) | |
i |
переход в режим GDB (окно с GDB) | |
I |
переход в режим TTY (окно с TTY) | |
SPACE | добавление/удаление breakpoint-а на данной строке | |
F5 | run |
запуск программы |
F6 | continue |
продолжить работу после остановки |
F8 | next |
выполнение одного шага в программе |
print VARNAME |
вывод содержания переменной VARNAME |
|
display VARNAME |
автоматический вывод переменной VARNAME после каждой следующей остановки программы |
|
undisplay VARNUMBER |
отмена предыдущего действия | |
update |
обновить версию запускаемой программы | |
- |
уменьшение окна с программным кодом | |
= |
увеличение окна с программным кодом | |
T |
запуск/выключения TTY вида |
Дополнительные источники
- CGDB Мануал
- Домашняя страница CGDB
- Домашняя страница GDB
- Linear search
- Оператор
sizeof()
: c-reference - Queries size of the object or type. Used when actual size of the object must be known. - Как определить размер массива