Как печатать каждую выполненную строку в GDB автоматически, пока не будет достигнута заданная точка останова?

Я хотел бы иметь возможность установить точку останова в 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" без дальнейшего вмешательства пользователя - при распечатке строк, через которые он проходит, как если бы был нажат шаг (или следующий) ?

26
задан Ciro Santilli 新疆改造中心法轮功六四事件 2 July 2015 в 19:22
поделиться

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
5
ответ дан 28 November 2019 в 07:50
поделиться

В качестве нового ответа, так как предыдущий уже заточен :) В основном, если дело в том, чтобы наблюдать за выполнением строк исходного кода (и / или ассемблера), когда программа работает, - мотивация часто для меня, когда я ищу в « автоматическая распечатка » - тогда, по сути, очень быстрый способ - использовать режим GDB TUI; Я цитирую:

c - поведение gdb: оптимизировано значение - переполнение стека # 1354762

Используйте режим TUI GDB. Моя копия GDB включает его, когда я набираю минус и ввод. Затем введите C-x 2 (то есть удерживайте нажатой клавишу «Control» и нажмите «X», отпустите обе кнопки и затем нажмите «2»). Это поместит его в разделенное отображение источника и разборки. Затем используйте stepi и nexti для перемещения одной машинной инструкции за раз. Используйте C-x o для переключения между окнами TUI.

Хитрость в том, что, даже если вы нажмете continue - этот источник времени будет показан и указан в TUI; и следуют по мере выполнения программы:

GDB TUI Screenshot

... и это для меня позволяет избежать многих ситуаций, когда мне приходится писать сценарии точек останова в контексте «автоматического перехода» "(хотя такие ситуации все еще существуют). Документы о TUI: TUI - отладка с помощью GDB

Приветствия!

1
ответ дан 28 November 2019 в 07:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: