data = "john", ' ' <repeats 4091 times>, key =2}, {
data = "neil", ' ' <repeats 4091 times>, key = 4}, {
data = "alex", ' ' <repeats 4091 times>, key =1}, {
data = "rick", ' ' <repeats 4091 times>, key =5}}
(gdb)
Можно воспользоваться командой display, чтобы задать в gdb автоматическое отображение массива при каждой остановке программы в точке останова:
(gdb) <b>display array[0]@5</b>
1: array[0]@5 = {{data = "bill", ' ' <repeats 4091 times>, key = 3}, {
data = "john", ' ' <repeats 4091 times>, key = 2}, {
data = "neil", ' ' <repeats 4091 times>, key = 4}, {
data = "alex", ' ' <repeats 4091 times>, key = 1}, {
data = "rick", ' ' <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", ' 00' <repeats 4091 times>, key = 2}, {
data = "bill", ' 00' <repeats 4091 times>, key =3}, {
data = "alex", ' 00' <repeats 4091 times>, key =1}, {
data = "neil", ' 00' <repeats 4091 times>, key =4}, {
data = "rick", ' 00' <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>