Есть ли в GDB встроенный скриптовый механизм, должен ли я кодировать ожидаемый script, или есть еще лучшее решение?
Я буду отправлять ту же последовательность команд каждый раз, и я буду сохранять вывод каждой команды в файл (скорее всего, используя встроенный механизм ведения журнала GDB, если у кого-то нет лучшей идеи).
Ответ 2
Я просто пережил нечто похожее и придумал базовый пример - и, зная, что скоро забуду об этом, я подумал, что лучше разместить его :)
. Поэтому я отправлю его здесь, так как он смотрит на вопрос.
В принципе, в этом примере я хотел получить некоторые значения переменных в определенных местах кода; и выводить их до тех пор, пока программа не выйдет из строя. Итак, вот сначала небольшая программа, которая гарантировала сбой в несколько шагов, test.c
:
#include <stdio.h>
#include <stdlib.h>
int icount = 1; // default value
main(int argc, char *argv[])
{
int i;
if (argc == 2) {
icount = atoi(argv[1]);
}
i = icount;
while (i > -1) {
int b = 5 / i;
printf(" 5 / %d = %d \n", i, b );
i = i - 1;
}
printf("Finished\n");
return 0;
}
Единственная причина, по которой программа принимает аргументы командной строки, состоит в том, чтобы иметь возможность выбирать количество шагов перед сбоем - и показать, что gdb
игнорирует --args
в пакетном режиме. Это я компилирую с помощью:
gcc -g test.c -o test.exe
Затем я готовлю следующий script - основной трюк здесь - назначить command
каждому breakpoint
, который в конечном итоге будет continue
(см. также Автоматизация gdb: показать обратную трассировку при каждом вызове функции puts). Этот script я вызываю test.gdb
:
# http://sourceware.org/gdb/wiki/FAQ: to disable the
# "---Type <return> to continue, or q <return> to quit---"
# in batch mode:
set width 0
set height 0
set verbose off
# at entry point - cmd1
b main
commands 1
print argc
continue
end
# printf line - cmd2
b test.c:17
commands 2
p i
p b
continue
end
# int b = line - cmd3
b test.c:16
commands 3
p i
p b
continue
end
# show arguments for program
show args
printf "Note, however: in batch mode, arguments will be ignored!\n"
# note: even if arguments are shown;
# must specify cmdline arg for "run"
# when running in batch mode! (then they are ignored)
# below, we specify command line argument "2":
run 2 # run
#start # alternative to run: runs to main, and stops
#continue
Обратите внимание, что если вы собираетесь использовать его в пакетном режиме, вам нужно "запустить" script в конце с помощью run
или start
или чего-то подобного.
С помощью этого script на месте я могу вызвать gdb
в пакетном режиме - который будет генерировать следующий вывод в терминале:
$ gdb --batch --command=test.gdb --args ./test.exe 5
Breakpoint 1 at 0x804844d: file test.c, line 10.
Breakpoint 2 at 0x8048485: file test.c, line 17.
Breakpoint 3 at 0x8048473: file test.c, line 16.
Argument list to give program being debugged when it is started is "5".
Note, however: in batch mode, arguments will be ignored!
Breakpoint 1, main (argc=2, argv=0xbffff424) at test.c:10
10 if (argc == 2) {
$1 = 2
Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16
16 int b = 5 / i;
$2 = 2
$3 = 134513899
Breakpoint 2, main (argc=2, argv=0xbffff424) at test.c:17
17 printf(" 5 / %d = %d \n", i, b );
$4 = 2
$5 = 2
5 / 2 = 2
Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16
16 int b = 5 / i;
$6 = 1
$7 = 2
Breakpoint 2, main (argc=2, argv=0xbffff424) at test.c:17
17 printf(" 5 / %d = %d \n", i, b );
$8 = 1
$9 = 5
5 / 1 = 5
Breakpoint 3, main (argc=2, argv=0xbffff424) at test.c:16
16 int b = 5 / i;
$10 = 0
$11 = 5
Program received signal SIGFPE, Arithmetic exception.
0x0804847d in main (argc=2, argv=0xbffff424) at test.c:16
16 int b = 5 / i;
Обратите внимание, что хотя мы указываем аргумент командной строки 5, цикл все еще вращается только два раза (как спецификация run
в gdb
script); если run
не имеет аргументов, он вращается только один раз (значение по умолчанию программы), подтверждающее, что --args ./test.exe 5
игнорируется.
Однако, поскольку теперь это выводится в одном вызове и без какого-либо взаимодействия с пользователем, вывод командной строки можно легко записать в текстовый файл с использованием перенаправления bash
, скажем:
gdb --batch --command=test.gdb --args ./test.exe 5 > out.txt
Существует также пример использования python для автоматизации gdb в c - автоматический степпинг GDB - автоматическая распечатка строк при свободном запуске?
Надеюсь, что это поможет,
Ура!