Я хотел бы иметь возможность установить точку останова в GDB и запустить ее до этой точки - и в процессе распечатать строки, которые у него есть " пошагово через ".
Вот пример, основанный на этом простом файле с main
и функцией, и двумя точками останова для каждого:
$ cat > test.c <<EOF
#include "stdio.h"
int count=0;
void doFunction(void) {
// two steps forward
count += 2;
// one step back
count--;
}
int main(void) {
// some pointless init commands;
count = 1;
count += 2;
count = 0;
//main loop
while(1) {
doFunction();
printf("%d\n", count);
}
}
EOF
$ gcc -g -Wall test.c -o test.exe
$ chmod +x test.exe
$ gdb -se test.exe
...
Reading symbols from /path/to/test.exe...done.
(gdb) b main
Breakpoint 1 at 0x80483ec: file test.c, line 14.
(gdb) b doFunction
Breakpoint 2 at 0x80483c7: file test.c, line 7.
Чтобы начать сеанс, мне нужно запустить ( r
) программа, которая затем остановится на первой точке останова ( main
):
(gdb) r
Starting program: /path/to/test.exe
Breakpoint 1, main () at test.c:14
14 count = 1;
(gdb)
На этом этапе - я могу, например, нажать continue ( c
);и процесс продолжится, ничего не выводя, и прервется на запрошенной строке:
(gdb) c
Continuing.
Breakpoint 2, doFunction () at test.c:7
7 count += 2;
(gdb)
С другой стороны, вместо продолжения - я могу идти построчно, либо используя step ( s
) или следующий ( n
); например:
14 count = 1;
(gdb) n
15 count += 2;
(gdb) s
16 count = 0;
(gdb) s
19 doFunction();
(gdb) s
Breakpoint 2, doFunction () at test.c:7
7 count += 2;
(gdb) s
9 count--;
(gdb) s
10 }
(gdb) s
main () at test.c:20
20 printf("%d\n", count);
(gdb) s
...
(gdb) s
_IO_vfprintf_internal (s=Cannot access memory at address 0xe5853361
) at vfprintf.c:210
210 vfprintf.c: No such file or directory.
in vfprintf.c
(gdb) s
245 in vfprintf.c
(gdb) s
210 in vfprintf.c
(gdb) n
245 in vfprintf.c
...
(gdb) n
2006 in vfprintf.c
(gdb) n
__printf (format=0x80484f0 "%d\n") at printf.c:39
39 printf.c: No such file or directory.
in printf.c
(gdb) n
main () at test.c:21
21 }
(gdb) n
19 doFunction();
(gdb) n
Breakpoint 2, doFunction () at test.c:7
7 count += 2;
(gdb)
В любом случае, я знаю, что могу удерживать нажатой Enter , и последняя введенная команда (шаг или следующая) повторится ( оставил немного более длительный сеанс во втором случае, чтобы показать, что 'next' остается на том же уровне, 'step' выполняет шаги внутри вызываемых функций ). Однако, как можно видеть, в зависимости от того, выполняется ли шаг или следующий, может пройти некоторое время, пока результат не будет достигнут - и поэтому я не хочу сидеть 10 минут с зажатой рукой на кнопке Enter :)
Итак, у меня вопрос - могу ли я как-нибудь проинструктировать gdb
запустить "точку останова 2" без дальнейшего вмешательства пользователя - при распечатке строк, через которые он проходит, как если бы был нажат шаг (или следующий) ?
Как насчет того, чтобы сделать это в gdb, используя командный файл? Измените аргумент файла и количество циклов, как требуется.
gdb -x run.gdb
run.gdb:
set pagination off
set logging file gdb.log
set logging on
set $i = 0
file main
break main
break WriteData
# sadly, commands not getting executed on reaching breakpoint 2
commands 2
set $i=1000
print "commands 2 : %d",$i
end
run
while ( $i < 1000 )
step
# next
# continue
set $i = $i + 1
end
В качестве нового ответа, так как предыдущий уже заточен :) В основном, если дело в том, чтобы наблюдать за выполнением строк исходного кода (и / или ассемблера), когда программа работает, - мотивация часто для меня, когда я ищу в « автоматическая распечатка » - тогда, по сути, очень быстрый способ - использовать режим GDB TUI; Я цитирую:
c - поведение gdb: оптимизировано значение - переполнение стека # 1354762
Используйте режим TUI GDB. Моя копия GDB включает его, когда я набираю минус и ввод. Затем введите C-x 2 (то есть удерживайте нажатой клавишу «Control» и нажмите «X», отпустите обе кнопки и затем нажмите «2»). Это поместит его в разделенное отображение источника и разборки. Затем используйте stepi и nexti для перемещения одной машинной инструкции за раз. Используйте C-x o для переключения между окнами TUI.
Хитрость в том, что, даже если вы нажмете continue
- этот источник времени будет показан и указан в TUI; и следуют по мере выполнения программы:
... и это для меня позволяет избежать многих ситуаций, когда мне приходится писать сценарии точек останова в контексте «автоматического перехода» "(хотя такие ситуации все еще существуют). Документы о TUI: TUI - отладка с помощью GDB
Приветствия!