Литмир - Электронная Библиотека
Содержание  
A
A

    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 = &quot;bill&quot;, '\0' &lt;repeats 4091 times&gt;, key = 3}, {

    data = &quot;john&quot;, '\0' &lt;repeats 4091 times&gt;, key = 2}, {

    data = &quot;neil&quot;, '\0' &lt;repeats 4091 times&gt;, key = 4}, {

    data = &quot;alex&quot;, '\0' &lt;repeats 4091 times&gt;, key = 1}, {

    data = &quot;rick&quot;, '\0' &lt;repeats 4091 times&gt;, key, = 5}}

Более того, вы можете изменить точку останова таким образом, что вместо остановки программы она просто отобразит данные, которые вы запросили, и продолжит выполнение. Для этого примените команду

commands
. Она позволит указать, какие команды отладчика выполнять при попадании в точку останова. Поскольку вы уже указали отображение, вам нужно лишь задать команду в точке останова для продолжения выполнения:

(gdb)<b> commands</b>

Type commands for when breakpoint 1 is hit, one per line.

End with a line saying just &quot;end&quot;.

&gt; <b>cont</b>

&gt; <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 = &quot;john&quot;, '\000' &lt;repeats 4091 times&gt;, key = 2}, {

    data = &quot;bill&quot;, '\000' &lt;repeats 4091 times&gt;, key =3}, {

    data = &quot;alex&quot;, '\000' &lt;repeats 4091 times&gt;, key =1}, {

    data = &quot;neil&quot;, '\000' &lt;repeats 4091 times&gt;, key =4}, {

    data = &quot;rick&quot;, '\000' &lt;repeats 4091 times&gt;, 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 &quot;end&quot;.

&gt;<b>set variable n = n+1</b>

&gt;<b>cont</b>

&gt;<b>end</b>

191
{"b":"285844","o":1}