Заставить GDB завершиться автоматически при успешном завершении?

Я использую сценарий отладки, который запускает несколько связанных процессов последовательно с отладчиком. В настоящее время я использую -x для автоматического выполнения нескольких команд (например, run). Как я могу заставить GDB завершиться автоматически после успешного завершения отлаженного процесса? Добавление команды quit в командный файл приведет к тому, что эта команда будет обрабатываться не только при успешном завершении, но и при возникновении ошибок (когда я я бы предпочел вступить во владение на этом этапе).

Вот отрывок из того, что происходит:

+ gdb -return-child-result -x gdbbatch --args ./mkfs.cpfs /dev/loop0
GNU gdb (GDB) 7.1-ubuntu
Reading symbols from /home/matt/cpfs/mkfs.cpfs...done.

Program exited normally.
Breakpoint 2 at 0x805224f: file log.c, line 32.
(gdb)

Содержание gdbbatch:

start
b cpfs_log if level >= WARNING

person Matt Joiner    schedule 18.09.2010    source источник
comment
Есть повторяющийся вопрос о Stackoverflow с полезным ответом: stackoverflow.com/a/8657833/431087   -  person Isaac Turner    schedule 11.03.2014


Ответы (3)


Думаю, я нашел полное решение вашего вопроса в связи с поиском чего-то похожего в Как заставить GDB отправлять внешнее уведомление при получении сигнала?. Похоже, что никто из присутствующих здесь ребят не упомянул и не обнаружил перехватчики gdb.

Основываясь на советах Мэтью о $ _exitcode, теперь это мое app / .gdbinit, которое обеспечивает именно то, что нужно; нормальный выход при успешном завершении и переход к приглашению gdb, отправка электронной почты и т. д. обо всем остальном:

set $_exitcode = -999
set height 0
handle SIGTERM nostop print pass
handle SIGPIPE nostop
define hook-stop
    if $_exitcode != -999
        quit
    else
        shell echo | mail -s "NOTICE: app has stopped on unhandled signal" root
    end
end
echo .gdbinit: running app\n
run
person lkraav    schedule 12.03.2011

gdb устанавливает $_exitcode, когда программа успешно завершается. Вы можете использовать это - установите маловероятное значение в начале вашего скрипта и только quit в конце, если оно изменилось:

set $_exitcode = -999
# ...
run
# ...
if $_exitcode != -999
  quit
end

(Установка $_exitcode на маловероятное значение немного некрасиво, но в противном случае оно вообще не будет определено, если программа не завершится, и, похоже, не существует очевидного способа спросить, «определена ли эта переменная?» В условное.)

person Matthew Slattery    schedule 18.09.2010
comment
В этом документе показано как использовать _isvoid с _exitcode, чтобы избежать установки маловероятных значений. - person Daniel Kamil Kozar; 10.01.2017
comment
Даниэль, твоя ссылка не работает :( - person Patrizio Bertoni; 12.11.2020

GDB имеет другой «язык» для взаимодействия с автоматизированными программами, который называется GDB / MI (подробно здесь), но, к сожалению, не похоже, что он поддерживает условные выражения, и ожидается, что он будет запускаться из других программ с синтаксическим анализом и ветвлением. Итак, похоже, Expect - самое простое (или, по крайней мере, рабочее) решение:

$ cat gdbrunner
#!/usr/bin/expect -f

#spawn gdb -return-child-result --args ./mkfs.cpfs /dev/loop0
spawn gdb -return-child-result --args [lindex $argv 0]

#send "start\n"
#send "b cpfs_log if level >= WARNING"
send "run\n"

expect {
    normally\.         { send "quit\n" }
    "exited with code" { interact -nobuffer }
}

Я проверил это с помощью простых программ:

$ cat prog1.c
int main(void) { return 0; }
$ cat prog2.c
int main(void) { return 1; }

Со следующими результатами:

$ ./gdbrunner ./prog1
spawn gdb -return-child-result --args ./prog1
run
(gdb) run
Starting program: /home/foo/prog1

Program exited normally.
(gdb) quit
$ ./gdbrunner ./prog2
spawn gdb -return-child-result --args ./prog2
run
(gdb) run
Starting program: /home/foo/prog2

Program exited with code 01.
(gdb)

По сути, вы должны анализировать вывод и переходить, используя что-то еще. Это, конечно, будет работать с любой другой программой, способной обрабатывать ввод / вывод другого процесса, но приведенный выше сценарий ожидания должен помочь вам начать, если вы не против Tcl. Он должен быть немного лучше и ожидать первого приглашения (gdb), но работает из-за буферизации stdin.

Вы также можете изменить его, чтобы использовать этот интерфейс GDB / MI с аргументом командной строки -i для GDB; его команды и выходные данные немного легче поддаются синтаксическому анализу, если вы расширите его, чтобы потребовались более продвинутые функции, как вы можете видеть в ранее связанной документации.

person Sdaz MacSkibbons    schedule 18.09.2010