data = "john", '\0' <repeats 4091 times>, key =2}, {
data = "neil", '\0' <repeats 4091 times>, key = 4}, {
data = "alex", '\0' <repeats 4091 times>, key =1}, {
data = "rick", '\0' <repeats 4091 times>, key =5}}
(gdb)
Можно воспользоваться командой
display
, чтобы задать в gdb автоматическое отображение массива при каждой остановке программы в точке останова:
(gdb) <b>display array[0]@5</b>
1: array[0]@5 = {{data = "bill", '\0' <repeats 4091 times>, key = 3}, {
data = "john", '\0' <repeats 4091 times>, key = 2}, {
data = "neil", '\0' <repeats 4091 times>, key = 4}, {
data = "alex", '\0' <repeats 4091 times>, key = 1}, {
data = "rick", '\0' <repeats 4091 times>, key, = 5}}
Более того, вы можете изменить точку останова таким образом, что вместо остановки программы она просто отобразит данные, которые вы запросили, и продолжит выполнение. Для этого примените команду
commands
. Она позволит указать, какие команды отладчика выполнять при попадании в точку останова. Поскольку вы уже указали отображение, вам нужно лишь задать команду в точке останова для продолжения выполнения:
(gdb)<b> commands</b>
Type commands for when breakpoint 1 is hit, one per line.
End with a line saying just "end".
> <b>cont</b>
> <b>end</b>
Теперь, когда вы разрешите программе продолжить выполнение, она продолжается до завершения, выводя значение массива каждый раз, когда оказывается вблизи внешнего цикла.
(gdb) <b>cont</b>
Continuing.
Breakpoint 1, sort (a=0x8049684, n=3) at debug4.c:21
21 /* 21 */ s = 0;
1: array[0]@5 = {{data = "john", '\000' <repeats 4091 times>, key = 2}, {
data = "bill", '\000' <repeats 4091 times>, key =3}, {
data = "alex", '\000' <repeats 4091 times>, key =1}, {
data = "neil", '\000' <repeats 4091 times>, key =4}, {
data = "rick", '\000' <repeats 4091 times>, key = 5}}
array[0] = {john, 2}
array[1] = {alex, 1}
array[2] = {bill, 3}
array[3] = {neil, 4}
array[4] = {rick, 5}
Program exited with code 025.
(gdb)
Отладчик gdb сообщает о том, что программа завершается с необычным кодом завершения. Это происходит потому, что программа сама не вызывает
exit
и не возвращает значение из функции
main
. Код завершения в данном случае не имеет смысла, значимый код должен предоставляться вызовом функции
exit
.
Кажется, что программа не выполняет внешний цикл столько раз, сколько ожидалось. Вы можете увидеть, что значение параметра
n
, используемого в условии завершения цикла, уменьшается при каждом достижении точки останова. Это значит, что цикл не будет выполняться нужное число раз. Дело в уменьшении
n
в строке 30.
/* 30 */ n--;
Это попытка оптимизировать программу за счет того, что в конце каждого прохода внешнего цикла наибольший, элемент
array
окажется внизу и поэтому остается меньше элементов для сортировки. Но как видно, это мешает внешнему циклу и создает проблемы. Простейший способ исправления (хотя есть и другие) — удалить ошибочную строку. Давайте проверим, применив отладчик для корректировки, устранило ли такое исправление проблему.
Вставка исправлений с помощью отладчика
Вы уже видели, что можно применять отладчик для установки точек останова и просмотра значений переменных. Применив точки останова с заданными действиями, можно проверить исправление, называемое "заплатой", перед тем, как изменять текст программы и выполнять ее повторную компиляцию. В данном случае нужно остановить программу в строке 30 и увеличить переменную
n
. В дальнейшем, когда строка 30 выполнится, значение останется неизменным.
Давайте перезапустим программу с самого начала. Прежде всего вы должны удалить вашу точку останова и отладочный вывод. С помощью команды info можно увидеть, какие точки останова и какой вывод вы включили:
(gdb)<b> info display</b>
Auto-display expressions now in effect:
Num Enb Expression
1: y array[0]@5 (gdb)<b> info break</b>
Num Type Disp Enb Address What
1 breakpoint keep y 0x08048427 in sort at debug4.c:21
breakpoint already hit 3 times
cont
Вы можете либо отключить эти точки останова, либо удалить их совсем. Если их отключить, у вас останется возможность включить их позже, когда понадобится.
(gdb) <b>disable break 1</b>
(gdb) <b>disable display 1</b>
(gdb) <b>break 30</b>
Breakpoint 2 at 0x8048545: file debug4.c, line 30.
(gdb) <b>commands 2</b>
Type commands for when breakpoint 2 is hit, one per line.
End with a line saying just "end".
><b>set variable n = n+1</b>
><b>cont</b>
><b>end</b>